Skip to content

Commit d51c9a0

Browse files
committed
set up voting and tutorial mutations on the frontend to work with Prisma database
1 parent 5f839ac commit d51c9a0

File tree

10 files changed

+891
-765
lines changed

10 files changed

+891
-765
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import * as React from 'react';
2+
import gql from 'graphql-tag';
3+
import { Mutation } from 'react-apollo';
4+
import { loginUser } from '../utils/auth';
5+
6+
import { handleMutationResponse, ApiErrors } from '../utils/errorHandling';
7+
import { Button } from './shared/base';
8+
9+
const BookmarkMutation = ({ tutorial }) => (
10+
<Mutation
11+
mutation={gql`
12+
mutation BookmarkTutorial($id: ID!) {
13+
bookmarkTutorial(tutorialId: $id) {
14+
code
15+
success
16+
userTutorial {
17+
id
18+
bookmarked
19+
}
20+
}
21+
}
22+
`}
23+
variables={{
24+
id: tutorial.id,
25+
}}
26+
>
27+
{bookmark => {
28+
return (
29+
<Button
30+
onClick={async () => {
31+
const mutationRes = await handleMutationResponse(bookmark());
32+
if (mutationRes.error) {
33+
if (mutationRes.error === ApiErrors.AUTHORIZATION) {
34+
loginUser();
35+
} else {
36+
console.log(mutationRes.error);
37+
}
38+
}
39+
}}
40+
>
41+
Bookmark
42+
</Button>
43+
);
44+
}}
45+
</Mutation>
46+
);
47+
48+
export default BookmarkMutation;

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

+17-87
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import gql from 'graphql-tag';
88
import { optionalChaining } from '../utils/helpers';
99
import { loginUser } from '../utils/auth';
1010
import { handleMutationResponse, ApiErrors } from '../utils/errorHandling';
11+
import UpvoteMutation from './UpvoteMutation';
12+
import BookmarkMutation from './BookmarkMutation';
1113

1214
type TutorialListingProps = {
1315
tutorial: Tutorial;
@@ -20,19 +22,21 @@ type Tutorial = {
2022
};
2123

2224
type FrontMatter = {
25+
id: string;
2326
tutorialTitle: string;
2427
description: string;
2528
};
2629

2730
const TutorialListing: React.FunctionComponent<TutorialListingProps> = ({
2831
tutorial,
2932
}) => {
30-
const tutorialId = 'cjwi9iv2klfsb0b14sqc9wpuj';
33+
const gatsbyID = tutorial.frontmatter.id;
34+
console.log(gatsbyID);
3135
return (
3236
<Query
3337
query={gql`
34-
query TutorialListing($id: ID!) {
35-
tutorial(id: $id) {
38+
query gatsbyTutorialQuery($gatsbyID: String!) {
39+
gatsbyTutorialQuery(gatsbyID: $gatsbyID) {
3640
id
3741
upvotes
3842
numberOfStudents
@@ -44,95 +48,21 @@ const TutorialListing: React.FunctionComponent<TutorialListingProps> = ({
4448
}
4549
}
4650
`}
47-
variables={{ id: tutorialId }}
51+
variables={{ gatsbyID: gatsbyID }}
4852
>
49-
{({ data }) => {
53+
{({ loading, error, data }) => {
54+
if (error) return `Error! ${error.message}`;
55+
5056
return (
5157
<Card width={[1]} p={4} my={4} borderRadius={8} boxShadow="small">
5258
<Flex alignItems="center" justifyContent="center">
5359
<Box width={1 / 12}>
54-
<Mutation
55-
mutation={gql`
56-
mutation UpvoteTutorial($id: ID!) {
57-
upvoteTutorial(tutorialId: $id) {
58-
code
59-
success
60-
userTutorial {
61-
id
62-
upvoted
63-
tutorial {
64-
id
65-
upvotes
66-
}
67-
}
68-
}
69-
}
70-
`}
71-
variables={{
72-
id: tutorialId,
73-
}}
74-
>
75-
{upvote => {
76-
return (
77-
<Upvote
78-
onClick={async () => {
79-
const mutationRes = await handleMutationResponse(
80-
upvote(),
81-
);
82-
if (mutationRes.error) {
83-
if (mutationRes.error === ApiErrors.AUTHORIZATION) {
84-
loginUser();
85-
} else {
86-
console.log(mutationRes.error);
87-
}
88-
}
89-
}}
90-
active={optionalChaining(
91-
() => data.tutorial.viewerUserTutorial.upvoted,
92-
)}
93-
count={optionalChaining(() => data.tutorial.upvotes)}
94-
/>
95-
);
96-
}}
97-
</Mutation>
98-
<Mutation
99-
mutation={gql`
100-
mutation BookmarkTutorial($id: ID!) {
101-
bookmarkTutorial(tutorialId: $id) {
102-
code
103-
success
104-
userTutorial {
105-
id
106-
bookmarked
107-
}
108-
}
109-
}
110-
`}
111-
variables={{
112-
id: tutorialId,
113-
}}
114-
>
115-
{bookmark => {
116-
return (
117-
<Button
118-
onClick={async () => {
119-
const mutationRes = await handleMutationResponse(
120-
bookmark(),
121-
);
122-
if (mutationRes.error) {
123-
if (mutationRes.error === ApiErrors.AUTHORIZATION) {
124-
loginUser();
125-
} else {
126-
console.log(mutationRes.error);
127-
}
128-
}
129-
}}
130-
>
131-
Bookmark
132-
</Button>
133-
);
134-
}}
135-
</Mutation>
60+
{data.gatsbyTutorialQuery && (
61+
<UpvoteMutation tutorial={data.gatsbyTutorialQuery} />
62+
)}
63+
{data.gatsbyTutorialQuery && (
64+
<BookmarkMutation tutorial={data.gatsbyTutorialQuery} />
65+
)}
13666
</Box>
13767
<Box width={11 / 12}>
13868
<Link to={getTutorialOverviewSlug(tutorial.fileAbsolutePath)}>

packages/gatsby-theme/src/components/Upvote.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { VoteButton } from './buttons';
44

55
type UpvoteDataProps = {
66
onClick: () => any;
7-
count: number;
7+
upvotes: number;
88
active: boolean;
99
};
1010

@@ -13,12 +13,12 @@ type UpvoteDataProps = {
1313
const Upvote: React.FunctionComponent<UpvoteDataProps> = ({
1414
onClick: event,
1515
active,
16-
count = '...',
16+
upvotes,
1717
}) => {
1818
return (
1919
<Flex flexDirection="column" alignItems="center" justifyContent="center">
2020
<VoteButton active={active} onClick={event} />
21-
<Heading>{count}</Heading>
21+
<Heading>{upvotes}</Heading>
2222
</Flex>
2323
);
2424
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import * as React from 'react';
2+
import gql from 'graphql-tag';
3+
import { Mutation } from 'react-apollo';
4+
import { optionalChaining } from '../utils/helpers';
5+
import { loginUser } from '../utils/auth';
6+
import { handleMutationResponse, ApiErrors } from '../utils/errorHandling';
7+
import Upvote from './Upvote';
8+
9+
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+
>
31+
{upvote => {
32+
return (
33+
<Upvote
34+
onClick={async () => {
35+
const mutationRes = await handleMutationResponse(upvote());
36+
if (mutationRes.error) {
37+
if (mutationRes.error === ApiErrors.AUTHORIZATION) {
38+
loginUser();
39+
} else {
40+
console.log(tutorial.id);
41+
console.log(tutorial);
42+
43+
console.log(mutationRes.error);
44+
}
45+
}
46+
}}
47+
active={
48+
optionalChaining(() => tutorial.viewerUserTutorial.upvoted) || false
49+
}
50+
upvotes={optionalChaining(() => tutorial.upvotes)}
51+
/>
52+
);
53+
}}
54+
</Mutation>
55+
);
56+
57+
export default UpvoteMutation;

packages/gatsby-theme/src/pages/community.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export const query = graphql`
3636
id
3737
fileAbsolutePath
3838
frontmatter {
39+
id
3940
tutorialTitle
4041
description
4142
}

packages/server/.yoga/nexus.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ export interface NexusGenFieldTypes {
348348
upvoteTutorial: NexusGenRootTypes['UserTutorialPayload']; // UserTutorialPayload!
349349
}
350350
Query: { // field return type
351+
gatsbyTutorialQuery: NexusGenRootTypes['Tutorial']; // Tutorial!
351352
tutorial: NexusGenRootTypes['Tutorial']; // Tutorial!
352353
tutorials: NexusGenRootTypes['Tutorial'][] | null; // [Tutorial!]
353354
viewer: NexusGenRootTypes['Viewer'] | null; // Viewer
@@ -363,7 +364,7 @@ export interface NexusGenFieldTypes {
363364
updatedAt: any; // DateTime!
364365
upvotes: number; // Int!
365366
userTutorials: NexusGenRootTypes['UserTutorial'][] | null; // [UserTutorial!]
366-
viewerUserTutorial: NexusGenRootTypes['UserTutorial']; // UserTutorial!
367+
viewerUserTutorial: NexusGenRootTypes['UserTutorial'] | null; // UserTutorial
367368
}
368369
User: { // field return type
369370
avatarUrl: string | null; // String
@@ -415,7 +416,7 @@ export interface NexusGenArgTypes {
415416
tutorialId: string; // ID!
416417
}
417418
upsertTutorial: { // args
418-
gatsbyID: string; // ID!
419+
gatsbyID: string; // String!
419420
name: string; // String!
420421
numberofChapters: number; // Int!
421422
}
@@ -424,6 +425,9 @@ export interface NexusGenArgTypes {
424425
}
425426
}
426427
Query: {
428+
gatsbyTutorialQuery: { // args
429+
gatsbyID: string; // String!
430+
}
427431
tutorial: { // args
428432
id: string; // ID!
429433
}

0 commit comments

Comments
 (0)