Skip to content

Commit 2c09964

Browse files
committed
Merge branch 'master' of https://github.com/howtographql/howtographql-core into community-page-styling
Merge with master
2 parents e9d33ab + c65ce81 commit 2c09964

35 files changed

+539
-312
lines changed

oss

packages/gatsby-theme/src/components/BookmarkMutation.tsx packages/gatsby-theme/src/components/community/BookmarkMutation.tsx

+10-17
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,23 @@
11
import * as React from 'react';
2-
import gql from 'graphql-tag';
32
import { Mutation } from 'react-apollo';
4-
import { loginUser } from '../utils/auth';
5-
import { BookmarkButton } from './buttons';
6-
import { handleMutationResponse, ApiErrors } from '../utils/errorHandling';
3+
import { loginUser } from '../../utils/auth';
4+
import { BookmarkButton } from '../shared/buttons';
5+
import { BookmarkTutorial } from '../../utils/queries';
6+
import { optionalChaining } from '../../utils/helpers';
7+
8+
import { handleMutationResponse, ApiErrors } from '../../utils/errorHandling';
79

810
const BookmarkMutation = ({ tutorial }) => (
911
<Mutation
10-
mutation={gql`
11-
mutation BookmarkTutorial($id: ID!) {
12-
bookmarkTutorial(tutorialId: $id) {
13-
code
14-
success
15-
userTutorial {
16-
id
17-
bookmarked
18-
}
19-
}
20-
}
21-
`}
12+
mutation={BookmarkTutorial}
2213
variables={{
2314
id: tutorial.id,
2415
}}
2516
>
2617
{bookmark => {
27-
let bookmarked = tutorial.viewerUserTutorial.bookmarked;
18+
let bookmarked = optionalChaining(
19+
() => tutorial.viewerUserTutorial.bookmarked,
20+
);
2821
return (
2922
<BookmarkButton
3023
active={bookmarked}

packages/gatsby-theme/src/components/TutorialListing.tsx packages/gatsby-theme/src/components/community/TutorialListing.tsx

+13-27
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import * as React from 'react';
2-
import { Heading, Text, Card, Flex, Box } from './shared/base';
3-
import { getTutorialOverviewSlug } from '../utils/getTutorialSlug';
2+
import { Heading, Text, Card, Flex, Box } from '../shared/base';
3+
import { getTutorialOverviewSlug } from '../../utils/getTutorialSlug';
44
import { Link } from 'gatsby';
55
import { Query } from 'react-apollo';
6-
import gql from 'graphql-tag';
76
import UpvoteMutation from './UpvoteMutation';
87
import BookmarkMutation from './BookmarkMutation';
8+
import Percentage from '../shared/Percentage';
9+
import { getTutorialbyGatsbyID } from '../../utils/queries';
910

1011
type TutorialListingProps = {
1112
tutorial: Tutorial;
@@ -27,25 +28,9 @@ const TutorialListing: React.FunctionComponent<TutorialListingProps> = ({
2728
tutorial,
2829
}) => {
2930
const gatsbyID = tutorial.frontmatter.id;
31+
let tutorialPath = getTutorialOverviewSlug(tutorial.fileAbsolutePath);
3032
return (
31-
<Query
32-
query={gql`
33-
query gatsbyTutorialQuery($gatsbyID: String!) {
34-
gatsbyTutorialQuery(gatsbyID: $gatsbyID) {
35-
id
36-
name
37-
upvotes
38-
numberOfStudents
39-
viewerUserTutorial {
40-
id
41-
upvoted
42-
bookmarked
43-
}
44-
}
45-
}
46-
`}
47-
variables={{ gatsbyID: gatsbyID }}
48-
>
33+
<Query query={getTutorialbyGatsbyID} variables={{ gatsbyID: gatsbyID }}>
4934
{({ data }) => {
5035
return (
5136
<Card
@@ -58,16 +43,17 @@ const TutorialListing: React.FunctionComponent<TutorialListingProps> = ({
5843
>
5944
<Flex alignItems="center" justifyContent="center">
6045
<Box width={1 / 12}>
61-
{data.gatsbyTutorialQuery && (
62-
<UpvoteMutation tutorial={data.gatsbyTutorialQuery} />
63-
)}
64-
{data.gatsbyTutorialQuery && (
65-
<BookmarkMutation tutorial={data.gatsbyTutorialQuery} />
46+
{data.getTutorialbyGatsbyID && (
47+
<div>
48+
<UpvoteMutation tutorial={data.getTutorialbyGatsbyID} />
49+
<BookmarkMutation tutorial={data.getTutorialbyGatsbyID} />
50+
<Percentage tutorial={data.getTutorialbyGatsbyID} />
51+
</div>
6652
)}
6753
</Box>
6854

6955
<Box width={11 / 12}>
70-
<Link to={getTutorialOverviewSlug(tutorial.fileAbsolutePath)}>
56+
<Link to={tutorialPath}>
7157
<Heading>{tutorial.frontmatter.tutorialTitle}</Heading>
7258
</Link>
7359
<Text>{tutorial.frontmatter.description}</Text>

packages/gatsby-theme/src/components/UpvoteMutation.tsx packages/gatsby-theme/src/components/community/UpvoteMutation.tsx

+9-28
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,17 @@
11
import * as React from 'react';
2-
import gql from 'graphql-tag';
32
import { Mutation } from 'react-apollo';
4-
import { loginUser } from '../utils/auth';
5-
import { handleMutationResponse, ApiErrors } from '../utils/errorHandling';
6-
import { VoteButton } from './buttons';
7-
import { Heading, Flex } from './shared/base';
3+
import { loginUser } from '../../utils/auth';
4+
import { handleMutationResponse, ApiErrors } from '../../utils/errorHandling';
5+
import { VoteButton } from '../shared/buttons';
6+
import { Heading, Flex } from '../shared/base';
7+
import { optionalChaining } from '../../utils/helpers';
8+
import { UpvoteTutorial } from '../../utils/queries';
89

910
const UpvoteMutation = ({ tutorial }) => (
10-
<Mutation
11-
mutation={gql`
12-
mutation UpvoteTutorial($id: ID!) {
13-
upvoteTutorial(tutorialId: $id) {
14-
code
15-
success
16-
userTutorial {
17-
id
18-
upvoted
19-
tutorial {
20-
id
21-
upvotes
22-
}
23-
}
24-
}
25-
}
26-
`}
27-
variables={{
28-
id: tutorial.id,
29-
}}
30-
>
11+
<Mutation mutation={UpvoteTutorial} variables={{ id: tutorial.id }}>
3112
{upvote => {
32-
let active = tutorial.viewerUserTutorial.upvoted;
33-
let upvotes = tutorial.upvotes;
13+
let active = optionalChaining(() => tutorial.viewerUserTutorial.upvoted);
14+
let upvotes = optionalChaining(() => tutorial.upvotes);
3415
return (
3516
<Flex
3617
flexDirection="column"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import * as React from 'react';
2+
import { Card, Flex, Image } from '../shared/base';
3+
import ProgressBar from '../shared/ProgressBar';
4+
import { TutorialButton } from '../shared/buttons';
5+
import { getTutorialOverviewSlug } from '../../utils/getTutorialSlug';
6+
7+
type CourseCardProps = {
8+
tutorialTitle: string;
9+
fileAbsolutePath: string;
10+
};
11+
12+
const CourseCard: React.FunctionComponent<CourseCardProps> = ({
13+
tutorialTitle,
14+
fileAbsolutePath,
15+
}) => {
16+
return (
17+
<Card m={[1, 1, 1]} p={[2, 2, 2]}>
18+
<Flex flexDirection="column" alignItems="center" justifyContent="center">
19+
<Image
20+
width={[0.5, 0.5, 0.5]}
21+
src="https://i.ibb.co/TcKwmwR/Icons.png"
22+
/>
23+
<h3>{tutorialTitle}</h3>
24+
<ProgressBar percentage={Math.floor(Math.random() * 100)} width={80} />
25+
<a href={getTutorialOverviewSlug(fileAbsolutePath)}>
26+
<TutorialButton>Start Tutorial</TutorialButton>
27+
</a>
28+
</Flex>
29+
</Card>
30+
);
31+
};
32+
33+
export default CourseCard;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import * as React from 'react';
2+
import { Heading, Text, Flex, Box } from '../shared/base';
3+
import CourseCard from './CourseCard';
4+
5+
type CourseSectionProps = {
6+
heading: string;
7+
body: string;
8+
data: [QueryData];
9+
};
10+
11+
type QueryData = {
12+
node: Node;
13+
};
14+
15+
type Node = {
16+
id: string;
17+
fileAbsolutePath: string;
18+
frontmatter: Frontmatter;
19+
};
20+
21+
type Frontmatter = {
22+
tutorialTitle: string;
23+
description: string;
24+
};
25+
26+
const CourseSection: React.FunctionComponent<CourseSectionProps> = ({
27+
heading,
28+
body,
29+
data,
30+
}) => {
31+
return (
32+
<Flex m={[1, 1, 1]}>
33+
<Box width={[0.2, 0.2, 0.2]}>
34+
<Heading> {heading} </Heading>
35+
<Text>{body}</Text>
36+
</Box>
37+
<Box width={[0.8, 0.8, 0.8]}>
38+
<Flex alignItems="top" justifyContent="center" flexWrap="wrap">
39+
{data.map(tutorial => (
40+
<Box width={[1, 0.8, 0.4]} key={tutorial.node.id}>
41+
<CourseCard
42+
tutorialTitle={tutorial.node.frontmatter.tutorialTitle}
43+
fileAbsolutePath={tutorial.node.fileAbsolutePath}
44+
/>
45+
</Box>
46+
))}
47+
</Flex>
48+
</Box>
49+
</Flex>
50+
);
51+
};
52+
53+
export default CourseSection;

packages/gatsby-theme/src/components/listing.tsx packages/gatsby-theme/src/components/index/listing.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Link } from 'gatsby';
22
import * as React from 'react';
3-
import { styled } from '../styles';
4-
import { useAllTutorialQuery } from '../hooks/useAllTutorialQuery';
5-
import { getTutorialSlug } from '../utils/getTutorialSlug';
3+
import { styled } from '../../styles';
4+
import { useAllTutorialQuery } from '../../hooks/useAllTutorialQuery';
5+
import { getTutorialSlug } from '../../utils/getTutorialSlug';
66

77
const Post = styled.article`
88
box-shadow: 0 0.3rem 1rem rgba(25, 17, 34, 0.05);

packages/gatsby-theme/src/components/Account.tsx packages/gatsby-theme/src/components/profile/Account.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React from 'react';
2-
import { Text, Image, Flex } from './shared/base';
2+
import { Text, Image, Flex } from '../shared/base';
33
import { Link } from 'gatsby';
4-
import { GithubButton } from './buttons';
5-
import { loginUser } from '../utils/auth';
6-
import WithCurrentUser from '../utils/auth/WithCurrentUser';
7-
import { CenteredLoader } from '../components/Loader';
4+
import { GithubButton } from '../shared/buttons';
5+
import { loginUser } from '../../utils/auth';
6+
import WithCurrentUser from '../../utils/auth/WithCurrentUser';
7+
import { CenteredLoader } from '../shared/Loader';
88

99
const Account = () => {
1010
return (

packages/gatsby-theme/src/components/shared/Header.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import Account from '../Account';
2+
import Account from '../profile/Account';
33

44
// Vectors
55
import Logo from './Logo';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import * as React from 'react';
2+
import { optionalChaining } from '../../utils/helpers';
3+
import { Text } from './base';
4+
5+
const Percentage = ({ tutorial }) => {
6+
let progress = optionalChaining(
7+
() => tutorial.viewerUserTutorial.currentChapter,
8+
);
9+
let percentage = progress
10+
? Math.floor((progress / tutorial.numberofChapters) * 100)
11+
: 0;
12+
return (
13+
<div>
14+
{percentage ? <Text>{percentage}%</Text> : <Text> No Progress </Text>}
15+
</div>
16+
);
17+
};
18+
19+
export default Percentage;

packages/gatsby-theme/src/components/ProgressBar.tsx packages/gatsby-theme/src/components/shared/ProgressBar.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react';
2-
import { styled } from '../styles';
3-
import { Text } from './shared/base';
2+
import { styled } from '../../styles';
3+
import { Text } from './base';
44

55
interface ProgressBarProps extends FillerProps, ContainerProps {}
66

@@ -41,7 +41,7 @@ interface FillerProps {
4141
percentage: number;
4242
}
4343

44-
const Filler = styled('div')<FillerProps>`
44+
const Filler = styled.div<FillerProps>`
4545
background: ${props => props.theme.colors.primary};
4646
height: 100%;
4747
border-radius: inherit;

packages/gatsby-theme/src/components/buttons.tsx packages/gatsby-theme/src/components/shared/buttons.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
2-
import { ButtonProps } from './shared/base';
3-
import { Flex, Image, Button } from './shared/base';
2+
import { ButtonProps } from './base';
3+
import { Flex, Image, Button } from './base';
44

55
export const VoteButton: React.FunctionComponent<
66
ButtonProps & {

packages/gatsby-theme/src/components/layout.tsx packages/gatsby-theme/src/components/shared/layout.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { RouterProps } from '@reach/router';
22
import * as React from 'react';
33
import Helmet from 'react-helmet';
4-
import { theme, ThemeProvider, styled } from '../styles';
5-
import { useLayoutQuery } from '../hooks/useLayoutQuery';
6-
import Header from './shared/Header';
4+
import { theme, ThemeProvider, styled } from '../../styles';
5+
import { useLayoutQuery } from '../../hooks/useLayoutQuery';
6+
import Header from './Header';
77

88
const MainLayout = styled.main`
99
max-width: 90%;

packages/gatsby-theme/src/components/templates/Tutorial.tsx

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import * as React from 'react';
22
import { RouterProps } from '@reach/router';
3-
import Layout from '../layout';
3+
import Layout from '../shared/layout';
44
import { MDXRenderer } from 'gatsby-mdx';
55
import { graphql } from 'gatsby';
6-
import { Sidebar, TabletSidebar } from '../TutorialSidebar';
6+
import { Sidebar, TabletSidebar } from '../tutorial/TutorialSidebar';
77
import { TutorialMdxQuery } from '../../graphqlTypes';
88
import { HideOnTablet, ShowOnTablet } from '../../utils/responsive';
99
import { Flex, Box } from '../shared/base';
1010
import { optionalChaining } from '../../utils/helpers';
11+
import ChapterMutation from '../tutorial/ChapterMutation';
1112

1213
type TutorialLayoutProps = { data: TutorialMdxQuery } & RouterProps;
1314

@@ -19,6 +20,10 @@ const TutorialLayout: React.FunctionComponent<TutorialLayoutProps> = ({
1920
return null;
2021
}
2122
const { pageTitle } = data!.mdx!.frontmatter!;
23+
const gatsbyID = optionalChaining(
24+
() => data!.tutorialTitle!.frontmatter!.id!,
25+
);
26+
2227
const tutorialTitle = optionalChaining(
2328
() => data!.tutorialTitle!.frontmatter!.tutorialTitle!,
2429
);
@@ -27,6 +32,7 @@ const TutorialLayout: React.FunctionComponent<TutorialLayoutProps> = ({
2732
data!.pageTitles!.edges!.map(a => a.node!.frontmatter!.pageTitle!),
2833
) || [];
2934
const { location } = props;
35+
const currentChapter = chapters.indexOf(pageTitle) + 1;
3036

3137
return (
3238
<Layout location={location}>
@@ -54,6 +60,7 @@ const TutorialLayout: React.FunctionComponent<TutorialLayoutProps> = ({
5460
<ShowOnTablet>
5561
<MDXRenderer>{data!.mdx!.code!.body}</MDXRenderer>
5662
</ShowOnTablet>
63+
<ChapterMutation gatsbyID={gatsbyID} currentChapter={currentChapter} />
5764
</Layout>
5865
);
5966
};
@@ -93,6 +100,7 @@ export const pageQuery = graphql`
93100
fileAbsolutePath: { regex: $folderRegex }
94101
) {
95102
frontmatter {
103+
id
96104
tutorialTitle
97105
}
98106
}

0 commit comments

Comments
 (0)