Skip to content

Commit

Permalink
edit-post
Browse files Browse the repository at this point in the history
  • Loading branch information
benawad committed Aug 16, 2020
1 parent cdfa09c commit f3d431c
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 49 deletions.
27 changes: 17 additions & 10 deletions server/src/resolvers/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,18 +188,25 @@ export class PostResolver {
}

@Mutation(() => Post, { nullable: true })
@UseMiddleware(isAuth)
async updatePost(
@Arg("id") id: number,
@Arg("title", () => String, { nullable: true }) title: string
@Arg("id", () => Int) id: number,
@Arg("title") title: string,
@Arg("text") text: string,
@Ctx() { req }: MyContext
): Promise<Post | null> {
const post = await Post.findOne(id);
if (!post) {
return null;
}
if (typeof title !== "undefined") {
await Post.update({ id }, { title });
}
return post;
const result = await getConnection()
.createQueryBuilder()
.update(Post)
.set({ title, text })
.where('id = :id and "creatorId" = :creatorId', {
id,
creatorId: req.session.userId,
})
.returning("*")
.execute();

return result.raw[0];
}

@Mutation(() => Boolean)
Expand Down
36 changes: 36 additions & 0 deletions web/src/components/EditDeletePostButtons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react";
import { Box, IconButton, Link } from "@chakra-ui/core";
import NextLink from "next/link";
import { useDeletePostMutation, useMeQuery } from "../generated/graphql";

interface EditDeletePostButtonsProps {
id: number;
creatorId: number;
}

export const EditDeletePostButtons: React.FC<EditDeletePostButtonsProps> = ({
id,
creatorId,
}) => {
const [{ data: meData }] = useMeQuery();
const [, deletePost] = useDeletePostMutation();

if (meData?.me?.id !== creatorId) {
return null;
}

return (
<Box>
<NextLink href="/post/edit/[id]" as={`/post/edit/${id}`}>
<IconButton as={Link} mr={4} icon="edit" aria-label="Edit Post" />
</NextLink>
<IconButton
icon="delete"
aria-label="Delete Post"
onClick={() => {
deletePost({ id });
}}
/>
</Box>
);
};
34 changes: 32 additions & 2 deletions web/src/generated/graphql.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,9 @@ export type MutationCreatePostArgs = {


export type MutationUpdatePostArgs = {
title?: Maybe<Scalars['String']>;
id: Scalars['Float'];
text: Scalars['String'];
title: Scalars['String'];
id: Scalars['Int'];
};


Expand Down Expand Up @@ -252,6 +253,21 @@ export type RegisterMutation = (
) }
);

export type UpdatePostMutationVariables = Exact<{
id: Scalars['Int'];
title: Scalars['String'];
text: Scalars['String'];
}>;


export type UpdatePostMutation = (
{ __typename?: 'Mutation' }
& { updatePost?: Maybe<(
{ __typename?: 'Post' }
& Pick<Post, 'id' | 'title' | 'text' | 'textSnippet'>
)> }
);

export type VoteMutationVariables = Exact<{
value: Scalars['Int'];
postId: Scalars['Int'];
Expand Down Expand Up @@ -424,6 +440,20 @@ export const RegisterDocument = gql`
export function useRegisterMutation() {
return Urql.useMutation<RegisterMutation, RegisterMutationVariables>(RegisterDocument);
};
export const UpdatePostDocument = gql`
mutation UpdatePost($id: Int!, $title: String!, $text: String!) {
updatePost(id: $id, title: $title, text: $text) {
id
title
text
textSnippet
}
}
`;

export function useUpdatePostMutation() {
return Urql.useMutation<UpdatePostMutation, UpdatePostMutationVariables>(UpdatePostDocument);
};
export const VoteDocument = gql`
mutation Vote($value: Int!, $postId: Int!) {
vote(value: $value, postId: $postId)
Expand Down
8 changes: 8 additions & 0 deletions web/src/graphql/mutations/updatePost.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
mutation UpdatePost($id: Int!, $title: String!, $text: String!) {
updatePost(id: $id, title: $title, text: $text) {
id
title
text
textSnippet
}
}
35 changes: 11 additions & 24 deletions web/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import { Box, Button, Flex, Heading, Link, Stack, Text } from "@chakra-ui/core";
import { withUrqlClient } from "next-urql";
import { createUrqlClient } from "../utils/createUrqlClient";
import { usePostsQuery, useDeletePostMutation } from "../generated/graphql";
import { Layout } from "../components/Layout";
import {
Link,
Stack,
Box,
Heading,
Text,
Flex,
Button,
Icon,
IconButton,
} from "@chakra-ui/core";
import NextLink from "next/link";
import { useState } from "react";
import { EditDeletePostButtons } from "../components/EditDeletePostButtons";
import { Layout } from "../components/Layout";
import { UpdootSection } from "../components/UpdootSection";
import { usePostsQuery } from "../generated/graphql";
import { createUrqlClient } from "../utils/createUrqlClient";

const Index = () => {
const [variables, setVariables] = useState({
Expand All @@ -26,7 +17,6 @@ const Index = () => {
const [{ data, fetching }] = usePostsQuery({
variables,
});
const [, deletePost] = useDeletePostMutation();

if (!fetching && !data) {
return <div>you got query failed for some reason</div>;
Expand All @@ -53,15 +43,12 @@ const Index = () => {
<Text flex={1} mt={4}>
{p.textSnippet}
</Text>
<IconButton
ml="auto"
variantColor="red"
icon="delete"
aria-label="Delete Post"
onClick={() => {
deletePost({ id: p.id });
}}
/>
<Box ml="auto">
<EditDeletePostButtons
id={p.id}
creatorId={p.creator.id}
/>
</Box>
</Flex>
</Box>
</Flex>
Expand Down
20 changes: 8 additions & 12 deletions web/src/pages/post/[id].tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
import React from "react";
import { withUrqlClient } from "next-urql";
import { createUrqlClient } from "../../utils/createUrqlClient";
import { useRouter } from "next/router";
import { usePostQuery } from "../../generated/graphql";
import { Layout } from "../../components/Layout";
import { Heading, Box } from "@chakra-ui/core";
import { useGetPostFromUrl } from "../../utils/useGetPostFromUrl";
import { EditDeletePostButtons } from "../../components/EditDeletePostButtons";

const Post = ({}) => {
const router = useRouter();
const intId =
typeof router.query.id === "string" ? parseInt(router.query.id) : -1;
const [{ data, error, fetching }] = usePostQuery({
pause: intId === -1,
variables: {
id: intId,
},
});
const [{ data, error, fetching }] = useGetPostFromUrl();

if (fetching) {
return (
Expand All @@ -40,7 +32,11 @@ const Post = ({}) => {
return (
<Layout>
<Heading mb={4}>{data.post.title}</Heading>
{data.post.text}
<Box mb={4}>{data.post.text}</Box>
<EditDeletePostButtons
id={data.post.id}
creatorId={data.post.creator.id}
/>
</Layout>
);
};
Expand Down
76 changes: 76 additions & 0 deletions web/src/pages/post/edit/[id].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { Box, Button } from "@chakra-ui/core";
import { Form, Formik } from "formik";
import { withUrqlClient } from "next-urql";
import { useRouter } from "next/router";
import React from "react";
import { InputField } from "../../../components/InputField";
import { Layout } from "../../../components/Layout";
import {
usePostQuery,
useUpdatePostMutation,
} from "../../../generated/graphql";
import { createUrqlClient } from "../../../utils/createUrqlClient";
import { useGetIntId } from "../../../utils/useGetIntId";

const EditPost = ({}) => {
const router = useRouter();
const intId = useGetIntId();
const [{ data, fetching }] = usePostQuery({
pause: intId === -1,
variables: {
id: intId,
},
});
const [, updatePost] = useUpdatePostMutation();
if (fetching) {
return (
<Layout>
<div>loading...</div>
</Layout>
);
}

if (!data?.post) {
return (
<Layout>
<Box>could not find post</Box>
</Layout>
);
}

return (
<Layout variant="small">
<Formik
initialValues={{ title: data.post.title, text: data.post.text }}
onSubmit={async (values) => {
await updatePost({ id: intId, ...values });
router.back();
}}
>
{({ isSubmitting }) => (
<Form>
<InputField name="title" placeholder="title" label="Title" />
<Box mt={4}>
<InputField
textarea
name="text"
placeholder="text..."
label="Body"
/>
</Box>
<Button
mt={4}
type="submit"
isLoading={isSubmitting}
variantColor="teal"
>
update post
</Button>
</Form>
)}
</Formik>
</Layout>
);
};

export default withUrqlClient(createUrqlClient)(EditPost);
2 changes: 1 addition & 1 deletion web/src/utils/createUrqlClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const cursorPagination = (): Resolver => {
export const createUrqlClient = (ssrExchange: any, ctx: any) => {
let cookie = "";
if (isServer()) {
cookie = ctx.req.headers.cookie;
cookie = ctx?.req?.headers?.cookie;
}

return {
Expand Down
9 changes: 9 additions & 0 deletions web/src/utils/useGetIntId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useRouter } from "next/router";

export const useGetIntId = () => {
const router = useRouter();
const intId =
typeof router.query.id === "string" ? parseInt(router.query.id) : -1;

return intId;
};
14 changes: 14 additions & 0 deletions web/src/utils/useGetPostFromUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { utimes } from "fs";
import { useRouter } from "next/router";
import { usePostQuery } from "../generated/graphql";
import { useGetIntId } from "./useGetIntId";

export const useGetPostFromUrl = () => {
const intId = useGetIntId();
return usePostQuery({
pause: intId === -1,
variables: {
id: intId,
},
});
};

0 comments on commit f3d431c

Please sign in to comment.