From aef0a90f43225f29c9e352094299e871fbea70c2 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 27 May 2023 21:19:09 +0330 Subject: [PATCH] cleaner code --- components/Dashboard/LinkItem.tsx | 8 +- components/LinkList.tsx | 8 +- components/Modal/AddLink.tsx | 149 -------------------- components/Modal/EditLink.tsx | 129 ----------------- components/Modal/LinkModal.tsx | 223 ++++++++++++++++++++++++++++++ components/Navbar.tsx | 4 +- pages/collections/[id].tsx | 7 +- store/links.ts | 6 +- 8 files changed, 246 insertions(+), 288 deletions(-) delete mode 100644 components/Modal/AddLink.tsx delete mode 100644 components/Modal/EditLink.tsx create mode 100644 components/Modal/LinkModal.tsx diff --git a/components/Dashboard/LinkItem.tsx b/components/Dashboard/LinkItem.tsx index 3e95990..0ebdec4 100644 --- a/components/Dashboard/LinkItem.tsx +++ b/components/Dashboard/LinkItem.tsx @@ -16,7 +16,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useState } from "react"; import Image from "next/image"; import useLinkStore from "@/store/links"; -import EditLink from "../Modal/EditLink"; +import LinkModal from "../Modal/LinkModal"; import Link from "next/link"; import Dropdown from "../Dropdown"; import Modal from "../Modal"; @@ -50,7 +50,11 @@ export default function ({ link, count }: Props) {
{editModal ? ( - + ) : null} diff --git a/components/LinkList.tsx b/components/LinkList.tsx index fea8cff..733ea9f 100644 --- a/components/LinkList.tsx +++ b/components/LinkList.tsx @@ -18,7 +18,7 @@ import Image from "next/image"; import Dropdown from "./Dropdown"; import useLinkStore from "@/store/links"; import Modal from "./Modal"; -import EditLink from "./Modal/EditLink"; +import LinkModal from "./Modal/LinkModal"; import Link from "next/link"; type Props = { @@ -50,7 +50,11 @@ export default function ({ link, count }: Props) {
{editModal ? ( - + ) : null} diff --git a/components/Modal/AddLink.tsx b/components/Modal/AddLink.tsx deleted file mode 100644 index 2988db9..0000000 --- a/components/Modal/AddLink.tsx +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (C) 2022-present Daniel31x13 -// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3. -// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -// You should have received a copy of the GNU General Public License along with this program. If not, see . - -import React, { useEffect, useState } from "react"; -import CollectionSelection from "@/components/InputSelect/CollectionSelection"; -import TagSelection from "@/components/InputSelect/TagSelection"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faPlus } from "@fortawesome/free-solid-svg-icons"; -import { LinkIncludingCollectionAndTags } from "@/types/global"; -import useLinkStore from "@/store/links"; -import { useRouter } from "next/router"; -import useCollectionStore from "@/store/collections"; -import RequiredBadge from "../RequiredBadge"; - -type Props = { - toggleLinkModal: Function; -}; - -export default function AddLink({ toggleLinkModal }: Props) { - const router = useRouter(); - const [link, setLink] = useState({ - name: "", - url: "", - title: "", - screenshotPath: "", - pdfPath: "", - tags: [], - collection: { - name: "", - description: "", - ownerId: 1, - }, - }); - - const { addLink } = useLinkStore(); - const { collections } = useCollectionStore(); - - useEffect(() => { - if (router.query.id) { - const currentCollection = collections.find( - (e) => e.id == Number(router.query.id) - ); - - if (currentCollection) - setLink({ - ...link, - collection: { - id: currentCollection?.id, - name: currentCollection?.name, - ownerId: currentCollection?.ownerId, - }, - }); - } - }, []); - - const setTags = (e: any) => { - const tagNames = e.map((e: any) => { - return { name: e.label }; - }); - - setLink({ ...link, tags: tagNames }); - }; - - const setCollection = (e: any) => { - if (e?.__isNew__) e.value = null; - - setLink({ - ...link, - collection: { id: e?.value, name: e?.label, ownerId: e?.ownerId }, - }); - }; - - const submit = async () => { - console.log(link); - - const response = await addLink(link); - - if (response) toggleLinkModal(); - }; - - return ( -
-

New Link

- -
-
-

- Name - -

- setLink({ ...link, name: e.target.value })} - type="text" - placeholder="e.g. Example Link" - className="w-full rounded-md p-2 border-sky-100 border-solid border outline-none focus:border-sky-500 duration-100" - /> -
- -
-

- URL - -

- setLink({ ...link, url: e.target.value })} - type="text" - placeholder="e.g. http://example.com/" - className="w-full rounded-md p-2 border-sky-100 border-solid border outline-none focus:border-sky-500 duration-100" - /> -
- -
-

- Collection - -

- -
- -
-

Tags

- -
-
- -
- - Add Link -
-
- ); -} diff --git a/components/Modal/EditLink.tsx b/components/Modal/EditLink.tsx deleted file mode 100644 index 00c049d..0000000 --- a/components/Modal/EditLink.tsx +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (C) 2022-present Daniel31x13 -// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3. -// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -// You should have received a copy of the GNU General Public License along with this program. If not, see . - -import React, { useState } from "react"; -import CollectionSelection from "@/components/InputSelect/CollectionSelection"; -import TagSelection from "@/components/InputSelect/TagSelection"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { LinkIncludingCollectionAndTags } from "@/types/global"; -import { faPenToSquare } from "@fortawesome/free-regular-svg-icons"; -import useLinkStore from "@/store/links"; -import { faTrashCan } from "@fortawesome/free-solid-svg-icons"; -import RequiredBadge from "../RequiredBadge"; - -type Props = { - toggleLinkModal: Function; - link: LinkIncludingCollectionAndTags; -}; - -export default function EditLink({ toggleLinkModal, link }: Props) { - const [currentLink, setCurrentLink] = - useState(link); - - const { updateLink, removeLink } = useLinkStore(); - - const shortendURL = new URL(link.url).host.toLowerCase(); - - const setTags = (e: any) => { - const tagNames = e.map((e: any) => { - return { name: e.label }; - }); - - setCurrentLink({ ...currentLink, tags: tagNames }); - }; - - const setCollection = (e: any) => { - if (e?.__isNew__) e.value = null; - - setCurrentLink({ - ...currentLink, - collection: { id: e?.value, name: e?.label, ownerId: e?.ownerId } as any, - }); - }; - - const submit = async () => { - updateLink(currentLink); - toggleLinkModal(); - }; - - return ( -
-

Edit Link

-

- {shortendURL} | {link.title} -

- -
-
-

- Name - -

- - setCurrentLink({ ...currentLink, name: e.target.value }) - } - type="text" - placeholder="e.g. Example Link" - className="w-full rounded-md p-2 border-sky-100 border-solid border outline-none focus:border-sky-500 duration-100" - /> -
- -
-

- Collection - -

- -
- -
-

Tags

- { - return { label: e.name, value: e.id }; - })} - /> -
-
- -
-
- - Edit Link -
- -
-
- -

OR

- -
-
- -
{ - removeLink(link); - toggleLinkModal(); - }} - className="w-fit inline-flex rounded-md cursor-pointer bg-red-500 hover:bg-red-400 duration-100 p-2" - > - -
-
-
- ); -} diff --git a/components/Modal/LinkModal.tsx b/components/Modal/LinkModal.tsx new file mode 100644 index 0000000..30e7ab8 --- /dev/null +++ b/components/Modal/LinkModal.tsx @@ -0,0 +1,223 @@ +// Copyright (C) 2022-present Daniel31x13 +// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3. +// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// You should have received a copy of the GNU General Public License along with this program. If not, see . + +import React, { useEffect, useState } from "react"; +import CollectionSelection from "@/components/InputSelect/CollectionSelection"; +import TagSelection from "@/components/InputSelect/TagSelection"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { LinkIncludingCollectionAndTags } from "@/types/global"; +import { faPenToSquare } from "@fortawesome/free-regular-svg-icons"; +import useLinkStore from "@/store/links"; +import { faPlus, faTrashCan } from "@fortawesome/free-solid-svg-icons"; +import RequiredBadge from "../RequiredBadge"; +import { useSession } from "next-auth/react"; +import useCollectionStore from "@/store/collections"; +import { useRouter } from "next/router"; + +type Props = + | { + toggleLinkModal: Function; + method: "CREATE"; + activeLink?: LinkIncludingCollectionAndTags; + } + | { + toggleLinkModal: Function; + method: "UPDATE"; + activeLink: LinkIncludingCollectionAndTags; + }; + +export default function EditLink({ + toggleLinkModal, + method, + activeLink, +}: Props) { + const { data } = useSession(); + + const [link, setLink] = useState( + method === "UPDATE" + ? activeLink + : { + name: "", + url: "", + title: "", + screenshotPath: "", + pdfPath: "", + tags: [], + collection: { + name: "", + ownerId: data?.user.id as number, + }, + } + ); + + const { updateLink, removeLink, addLink } = useLinkStore(); + + const router = useRouter(); + + const { collections } = useCollectionStore(); + + useEffect(() => { + if (router.query.id) { + const currentCollection = collections.find( + (e) => e.id == Number(router.query.id) + ); + + if (currentCollection) + setLink({ + ...link, + collection: { + id: currentCollection.id, + name: currentCollection.name, + ownerId: currentCollection.ownerId, + }, + }); + } + }, []); + + const shortendURL = + method === "UPDATE" ? new URL(link.url).host.toLowerCase() : undefined; + + const setTags = (e: any) => { + const tagNames = e.map((e: any) => { + return { name: e.label }; + }); + + setLink({ ...link, tags: tagNames }); + }; + + const setCollection = (e: any) => { + if (e?.__isNew__) e.value = null; + + setLink({ + ...link, + collection: { id: e?.value, name: e?.label, ownerId: e?.ownerId }, + }); + }; + + const submit = async () => { + let response; + + if (method === "UPDATE") response = await updateLink(link); + else if (method === "CREATE") response = await addLink(link); + + toggleLinkModal(); + }; + + return ( +
+

+ {method === "UPDATE" ? "Edit" : "New"} Link +

+ + {method === "UPDATE" ? ( +

+ {shortendURL} | {link.title} +

+ ) : null} + +
+
+

+ Name + +

+ setLink({ ...link, name: e.target.value })} + type="text" + placeholder="e.g. Example Link" + className="w-full rounded-md p-2 border-sky-100 border-solid border outline-none focus:border-sky-500 duration-100" + /> +
+ + {method === "CREATE" ? ( +
+

+ URL + +

+ setLink({ ...link, url: e.target.value })} + type="text" + placeholder="e.g. http://example.com/" + className="w-full rounded-md p-2 border-sky-100 border-solid border outline-none focus:border-sky-500 duration-100" + /> +
+ ) : null} + +
+

+ Collection + +

+ +
+ +
+

Tags

+ { + return { label: e.name, value: e.id }; + })} + /> +
+
+ +
+
+ + {method === "CREATE" ? "Add Link" : "Edit Link"} +
+ + {method === "UPDATE" ? ( + <> +
+
+ +

OR

+ +
+
+ +
{ + removeLink(link); + toggleLinkModal(); + }} + className="w-fit inline-flex rounded-md cursor-pointer bg-red-500 hover:bg-red-400 duration-100 p-2" + > + +
+ + ) : null} +
+
+ ); +} diff --git a/components/Navbar.tsx b/components/Navbar.tsx index 39efd3c..c1e0723 100644 --- a/components/Navbar.tsx +++ b/components/Navbar.tsx @@ -16,7 +16,7 @@ import { import { useEffect, useState } from "react"; import Dropdown from "@/components/Dropdown"; import Modal from "@/components/Modal"; -import AddLink from "@/components/Modal/AddLink"; +import LinkModal from "@/components/Modal/LinkModal"; import ClickAwayHandler from "@/components/ClickAwayHandler"; import Sidebar from "@/components/Sidebar"; import { useRouter } from "next/router"; @@ -129,7 +129,7 @@ export default function () { {linkModal ? ( - + ) : null} diff --git a/pages/collections/[id].tsx b/pages/collections/[id].tsx index f75c3ef..fa39d42 100644 --- a/pages/collections/[id].tsx +++ b/pages/collections/[id].tsx @@ -6,7 +6,7 @@ import Dropdown from "@/components/Dropdown"; import LinkList from "@/components/LinkList"; import Modal from "@/components/Modal"; -import AddLink from "@/components/Modal/AddLink"; +import LinkModal from "@/components/Modal/LinkModal"; import CollectionModal from "@/components/Modal/CollectionModal"; import DeleteCollection from "@/components/Modal/DeleteCollection"; import useCollectionStore from "@/store/collections"; @@ -280,7 +280,10 @@ export default function () { {linkModal ? ( - + ) : null} diff --git a/store/links.ts b/store/links.ts index 0dc3f69..7976317 100644 --- a/store/links.ts +++ b/store/links.ts @@ -12,8 +12,8 @@ type LinkStore = { links: LinkIncludingCollectionAndTags[]; setLinks: () => void; addLink: (body: LinkIncludingCollectionAndTags) => Promise; - updateLink: (link: LinkIncludingCollectionAndTags) => void; - removeLink: (link: LinkIncludingCollectionAndTags) => void; + updateLink: (link: LinkIncludingCollectionAndTags) => Promise; + removeLink: (link: LinkIncludingCollectionAndTags) => Promise; }; const useLinkStore = create()((set) => ({ @@ -70,6 +70,8 @@ const useLinkStore = create()((set) => ({ useTagStore.getState().setTags(); useCollectionStore.getState().setCollections(); } + + return response.ok; }, removeLink: async (link) => { const response = await fetch("/api/routes/links", {