diff --git a/client/src/app/[username]/page.tsx b/client/src/app/[username]/page.tsx index 0788890..f01c3f6 100644 --- a/client/src/app/[username]/page.tsx +++ b/client/src/app/[username]/page.tsx @@ -127,6 +127,7 @@ function UserProfile({ params }: { params: { username: string } }) {
{dataToDisplay ? ( dataToDisplay.length > 0 ? ( + // @ts-ignore dataToDisplay.map(item => { switch (selectedTab) { case 'posts': diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx index 9b0c819..685980f 100644 --- a/client/src/app/page.tsx +++ b/client/src/app/page.tsx @@ -34,6 +34,9 @@ const formSchema = z.object({ required_error: "Forum is required", }), imageUrl: z.string().default(""), + title: z.string({ + required_error: "Title is required", + }) }); export default function Home() { diff --git a/client/src/components/core/mobile-sidebar.tsx b/client/src/components/core/mobile-sidebar.tsx index c966694..bc5db4d 100644 --- a/client/src/components/core/mobile-sidebar.tsx +++ b/client/src/components/core/mobile-sidebar.tsx @@ -1,4 +1,4 @@ - +import { useState } from 'react'; import { FaHome, FaRocket, FaPlus, FaArrowDown } from 'react-icons/fa'; import { Sheet, SheetContent } from "~/components/ui/sheet"; import Link from 'next/link'; @@ -11,6 +11,8 @@ import { } from "~/components/ui/collapsible"; import { Separator } from "~/components/ui/separator"; import { Button } from "~/components/ui/button"; +import CreatePostModal from "~/components/posts/create-post-modal"; + interface Forum { id: string; @@ -21,8 +23,15 @@ interface Forum { } const MobileSidebar = ({ open, handleShow, user, data }: { open: boolean, handleShow: () => void, user: any, data?: Forum[] }) => { + const [openPost, setOpenPost] = useState(false); + + const handleModalOpen = () => { + setOpenPost(!openPost); + if (open) handleShow() + } return ( + @@ -59,7 +68,7 @@ const MobileSidebar = ({ open, handleShow, user, data }: { open: boolean, handle
-
diff --git a/client/src/components/core/side-bar.tsx b/client/src/components/core/side-bar.tsx index 9a18a5f..9896ab8 100644 --- a/client/src/components/core/side-bar.tsx +++ b/client/src/components/core/side-bar.tsx @@ -13,15 +13,20 @@ import { CollapsibleContent, CollapsibleTrigger, } from "~/components/ui/collapsible"; +import CreatePostModal from "~/components/posts/create-post-modal"; import { useUser } from "@clerk/clerk-react"; import { useFetcher } from "~/hooks/fetcher"; import useSWR from "swr"; export default function SideBar() { const { isSignedIn } = useUser(); + const [open, setOpen] = React.useState(false); const { allForums } = useFetcher(); const { data, error } = useSWR("/forums", allForums); - //console.log("forrrrrum", data, error) + + const handleModalOpen = () => { + setOpen(!open); + } return (
-
- +
{/* TODO Make this into a component */} @@ -100,6 +108,7 @@ export default function SideBar() {
+
diff --git a/client/src/components/posts/create-post-modal.tsx b/client/src/components/posts/create-post-modal.tsx new file mode 100644 index 0000000..4e8f7d6 --- /dev/null +++ b/client/src/components/posts/create-post-modal.tsx @@ -0,0 +1,274 @@ +import { useState, useEffect } from "react"; +import { Button } from "~/components/ui/button"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useFetcher } from "~/hooks/fetcher"; +import { useAuth } from "@clerk/clerk-react"; +import { Input } from "~/components/ui/input"; +import { useToast } from "~/components/ui/use-toast"; +import { ToastAction } from "~/components/ui/toast"; +import { useQuill } from "react-quilljs"; +import Link from "next/link"; +import useSWR from "swr"; + +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "~/components/ui/select"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, +} from "~/components/ui/form"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "~/components/ui/dialog"; +import { Textarea } from "~/components/ui/textarea"; +import CirclePopLoader from "react-loaders-kit/lib/circlePop/CirclePopLoader"; + +interface CreatePostModalProps { + open: boolean; + setOpen: () => void; +} + +const formSchema = z.object({ + forum: z.string({ + required_error: "Forum is required", + }), + imageUrl: z.string().default(""), + title: z.string({ + required_error: "Title is required", + }), + content: z.string({ + required_error: "Content is required", + }), +}); + +export default function CreatePostModal({ + open, + setOpen, +}: CreatePostModalProps) { + const { toast } = useToast(); + const [value, setValue] = useState(""); + const [loading, setLoading] = useState(false); + const { quill, quillRef } = useQuill(); + const { isSignedIn, getToken } = useAuth(); + const { allForums, createPost } = useFetcher(); + const { data: forums, error } = useSWR("/forums", allForums); + + const form = useForm>({ + resolver: zodResolver(formSchema), + }); + + useEffect(() => { + if (quill) { + quill.on("text-change", () => { + setValue(quill.getText()); + }); + } + }, [quill]); + + async function onSubmit(data: z.infer) { + setLoading(true); + const token = await getToken(); + if (token === null) { + console.error("Token is null"); + return; + } + try { + const res = await createPost( + { + title: data.title, + content: data.content, + forumId: forums?.find( + (forum) => forum.slug === form.getValues("forum") + )?.id, + imageUrl: data.imageUrl, + }, + token + ); + setLoading(false); + toast({ + title: "Post created sucessfully", + description: "Your post has been created", + action: ( + + View post + + ), + }); + form.reset(); + setOpen(); + + // quill?.setText(""); + } catch (e) { + setLoading(false); + console.error(e); + toast({ + title: "Error creating post", + description: "An error occurred while creating your post", + }); + } + } + + return ( + + {/*Open*/} + + + Create a post + + Share your thoughts with the world. You can attach an image to your + post by pasting the URL in the input field. + + {forums && ( +
+ {isSignedIn && ( +
+ +
+ ( + + Forum + + + )} + > + ( + + Attach image + +
+ + {/* */} +
+
+
+ )} + >
+
+ ( + + Title + +
+ +
+
+
+ )} + >
+ ( + + + Content + + +
+