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"
- />
-
-
-
-
-
-
-
-
-
- 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"
- />
-
-
-
-
-
-
Tags
-
{
- return { label: e.name, value: e.id };
- })}
- />
-
-
-
-
-
-
- Edit Link
-
-
-
-
-
{
- 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}
+
+
+
+
+
Tags
+
{
+ return { label: e.name, value: e.id };
+ })}
+ />
+
+
+
+
+
+
+ {method === "CREATE" ? "Add Link" : "Edit Link"}
+
+
+ {method === "UPDATE" ? (
+ <>
+
+
+
{
+ 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", {