Skip to content

Commit

Permalink
feat(apps/gql): update home page & add new post button
Browse files Browse the repository at this point in the history
  • Loading branch information
usirin committed Aug 17, 2023
1 parent c68a735 commit a51a0c4
Show file tree
Hide file tree
Showing 18 changed files with 679 additions and 114 deletions.
19 changes: 19 additions & 0 deletions apps/kampus/app/pano/@modal/(.)post/create/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"use client";

import { useRouter } from "next/navigation";

import { Dialog, DialogContent } from "@kampus/ui";

import { CreatePanoPostForm } from "~/app/pano/CreatePanoPostForm";

export default function CreatePost({ searchParams }: { searchParams: { conn: string } }) {
const router = useRouter();

return (
<Dialog open onOpenChange={() => router.back()}>
<DialogContent className="sm:max-w-[425px]">
<CreatePanoPostForm connectionID={searchParams.conn} onCompleted={() => router.back()} />
</DialogContent>
</Dialog>
);
}
3 changes: 3 additions & 0 deletions apps/kampus/app/pano/@modal/(.)post/default.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Default() {
return null;
}
3 changes: 3 additions & 0 deletions apps/kampus/app/pano/@modal/default.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Default() {
return null;
}
143 changes: 143 additions & 0 deletions apps/kampus/app/pano/CreatePanoPostForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
"use client";

import { graphql, useMutation } from "react-relay";
import { z } from "zod";

import {
Button,
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
Input,
Textarea,
useForm,
} from "@kampus/ui";

const mutation = graphql`
mutation CreatePanoPostFormMutation(
$title: String!
$content: String
$url: String
$connections: [ID!]!
) {
createPanoPost(input: { url: $url, title: $title, content: $content }) {
edge @prependEdge(connections: $connections) {
cursor
node {
...PostItem_post
}
}
error {
... on UserError {
message
}
}
}
}
`;

const formSchema = z.object({
title: z.string().min(5, { message: "Başlık en az 5 karakterden oluşmalıdır" }),
url: z.string().url({ message: "URL duzgun degil" }),
content: z.string().optional(),
});

type FormSchema = z.infer<typeof formSchema>;

interface Props {
connectionID?: string;
onCompleted?: () => void;
}

export function CreatePanoPostForm(props: Props) {
const [commit, isInFlight] = useMutation(mutation);

const form = useForm(formSchema, {
defaultValues: {
title: "",
url: "",
content: "",
},
});

const onSubmit = (values: FormSchema) => {
commit({
variables: {
title: values.title,
url: values.url,
content: values.content,
connections: [props.connectionID].filter(Boolean),
},
onError: (error) => {
console.error(error);
},
onCompleted: () => {
props.onCompleted?.();
},
});
};

const onCancel = () => {
props.onCompleted?.();
};

return (
<Form {...form}>
{/* eslint-disable-next-line @typescript-eslint/no-misused-promises */}
<form className="flex flex-col gap-2" onSubmit={form.handleSubmit(onSubmit)}>
<FormField
control={form.control}
name="url"
render={(props) => (
<FormItem>
<FormLabel>URL</FormLabel>
<FormControl>
<Input placeholder="https://ornek.com" {...props.field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="title"
render={(props) => (
<FormItem>
<FormLabel>Başlık</FormLabel>
<FormControl>
<Input placeholder="Ornek baslik" {...props.field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="content"
render={(props) => (
<FormItem>
<FormLabel>Icerik</FormLabel>
<FormControl>
<Textarea placeholder="Ornek hakkindaki dusuncelerim .." {...props.field} />
</FormControl>
<FormDescription>Eklemek istediklerini ekleyebilirsin ..</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-end gap-1.5">
<Button onClick={onCancel} variant="outline" type="reset">
Iptal
</Button>
<Button type="submit" disabled={isInFlight}>
Gonder
</Button>
</div>
</form>
</Form>
);
}
78 changes: 40 additions & 38 deletions apps/kampus/app/pano/PanoFeed.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Suspense, useCallback } from "react";
import { Suspense } from "react";
import Link from "next/link";
import { graphql, useFragment, usePaginationFragment } from "react-relay";

import { Button } from "@kampus/ui";
Expand Down Expand Up @@ -50,45 +51,46 @@ export function PanoFeed(props: Props) {

const feed = data.panoFeed;

const loadPrevPage = useCallback(() => {
if (hasPrevious) {
loadPrevious(10);
}
}, [hasPrevious, loadPrevious]);

const loadNextPage = useCallback(() => {
if (hasNext) {
loadNext(10);
}
}, [hasNext, loadNext]);

return (
<Suspense fallback="loading">
<section className="flex flex-col gap-4">
{feed?.edges?.map((edge) => {
if (!edge?.node) {
return null;
}
<>
<Button variant="outline" asChild>
<Link
href={{
pathname: `/post/create`,
search: `foo=bar`,
}}
as="post/create"
>
New post
</Link>
</Button>
<Suspense fallback="loading">
<section className="flex flex-col gap-4">
{feed?.edges?.map((edge) => {
if (!edge?.node) {
return null;
}

return (
<PostItem
key={edge.node.id}
post={edge.node}
viewerRef={viewer}
postConnectionId={data.panoFeed?.__id}
/>
);
})}
return (
<PostItem
key={edge.node.id}
post={edge.node}
viewerRef={viewer}
postConnectionId={data.panoFeed?.__id}
/>
);
})}

<div className="flex gap-2">
<Button variant="secondary" onClick={loadPrevPage} disabled={!hasPrevious}>
{"< Prev"}
</Button>
<Button variant="secondary" onClick={loadNextPage} disabled={!hasNext}>
{"Next >"}
</Button>
</div>
</section>
</Suspense>
<div className="flex gap-2">
<Button variant="secondary" onClick={() => loadPrevious(10)} disabled={!hasPrevious}>
{"< Prev"}
</Button>
<Button variant="secondary" onClick={() => loadNext(10)} disabled={!hasNext}>
{"Next >"}
</Button>
</div>
</section>
</Suspense>
</>
);
}
Loading

0 comments on commit a51a0c4

Please sign in to comment.