diff --git a/components/Dashboard/LinkItem.tsx b/components/Dashboard/LinkItem.tsx index 4945ea0..e93516e 100644 --- a/components/Dashboard/LinkItem.tsx +++ b/components/Dashboard/LinkItem.tsx @@ -3,7 +3,7 @@ // 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 { ExtendedLink } from "@/types/global"; +import { LinkIncludingCollectionAndTags } from "@/types/global"; import { faFolder, faArrowUpRightFromSquare, @@ -25,7 +25,7 @@ export default function ({ link, count, }: { - link: ExtendedLink; + link: LinkIncludingCollectionAndTags; count: number; }) { const [expandDropdown, setExpandDropdown] = useState(false); @@ -34,11 +34,14 @@ export default function ({ const { removeLink } = useLinkStore(); const url = new URL(link.url); - const formattedDate = new Date(link.createdAt).toLocaleString("en-US", { - year: "numeric", - month: "short", - day: "numeric", - }); + const formattedDate = new Date(link.createdAt as string).toLocaleString( + "en-US", + { + year: "numeric", + month: "short", + day: "numeric", + } + ); const toggleEditModal = () => { setEditModal(!editModal); diff --git a/components/InputSelect/CollectionSelection.tsx b/components/InputSelect/CollectionSelection.tsx index e202d6e..f86be56 100644 --- a/components/InputSelect/CollectionSelection.tsx +++ b/components/InputSelect/CollectionSelection.tsx @@ -14,8 +14,8 @@ type Props = { onChange: any; defaultValue: | { - value: number; label: string; + value?: number; } | undefined; }; diff --git a/components/InputSelect/types.ts b/components/InputSelect/types.ts index e32f849..ff1a571 100644 --- a/components/InputSelect/types.ts +++ b/components/InputSelect/types.ts @@ -4,6 +4,6 @@ // You should have received a copy of the GNU General Public License along with this program. If not, see . export interface Options { - value: string | number; label: string; + value?: string | number; } diff --git a/components/LinkList.tsx b/components/LinkList.tsx index 3c649fa..772812a 100644 --- a/components/LinkList.tsx +++ b/components/LinkList.tsx @@ -3,7 +3,7 @@ // 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 { ExtendedLink } from "@/types/global"; +import { LinkIncludingCollectionAndTags } from "@/types/global"; import { faFolder, faArrowUpRightFromSquare, @@ -25,7 +25,7 @@ export default function ({ link, count, }: { - link: ExtendedLink; + link: LinkIncludingCollectionAndTags; count: number; }) { const [expandDropdown, setExpandDropdown] = useState(false); @@ -34,11 +34,14 @@ export default function ({ const { removeLink } = useLinkStore(); const url = new URL(link.url); - const formattedDate = new Date(link.createdAt).toLocaleString("en-US", { - year: "numeric", - month: "short", - day: "numeric", - }); + const formattedDate = new Date(link.createdAt as string).toLocaleString( + "en-US", + { + year: "numeric", + month: "short", + day: "numeric", + } + ); const toggleEditModal = () => { setEditModal(!editModal); diff --git a/components/Modal/AddLink.tsx b/components/Modal/AddLink.tsx index 1b0309e..2988db9 100644 --- a/components/Modal/AddLink.tsx +++ b/components/Modal/AddLink.tsx @@ -8,7 +8,7 @@ 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 { ExtendedLink, NewLink } from "@/types/global"; +import { LinkIncludingCollectionAndTags } from "@/types/global"; import useLinkStore from "@/store/links"; import { useRouter } from "next/router"; import useCollectionStore from "@/store/collections"; @@ -20,14 +20,17 @@ type Props = { export default function AddLink({ toggleLinkModal }: Props) { const router = useRouter(); - const [newLink, setNewLink] = useState({ + const [link, setLink] = useState({ name: "", url: "", + title: "", + screenshotPath: "", + pdfPath: "", tags: [], collection: { - id: undefined, name: "", - ownerId: undefined, + description: "", + ownerId: 1, }, }); @@ -40,14 +43,15 @@ export default function AddLink({ toggleLinkModal }: Props) { (e) => e.id == Number(router.query.id) ); - setNewLink({ - ...newLink, - collection: { - id: currentCollection?.id, - name: currentCollection?.name, - ownerId: currentCollection?.ownerId, - }, - }); + if (currentCollection) + setLink({ + ...link, + collection: { + id: currentCollection?.id, + name: currentCollection?.name, + ownerId: currentCollection?.ownerId, + }, + }); } }, []); @@ -56,22 +60,22 @@ export default function AddLink({ toggleLinkModal }: Props) { return { name: e.label }; }); - setNewLink({ ...newLink, tags: tagNames }); + setLink({ ...link, tags: tagNames }); }; const setCollection = (e: any) => { if (e?.__isNew__) e.value = null; - setNewLink({ - ...newLink, + setLink({ + ...link, collection: { id: e?.value, name: e?.label, ownerId: e?.ownerId }, }); }; const submit = async () => { - console.log(newLink); + console.log(link); - const response = await addLink(newLink as NewLink); + const response = await addLink(link); if (response) toggleLinkModal(); }; @@ -87,8 +91,8 @@ export default function AddLink({ toggleLinkModal }: Props) {

setNewLink({ ...newLink, name: e.target.value })} + value={link.name} + onChange={(e) => 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" @@ -101,8 +105,8 @@ export default function AddLink({ toggleLinkModal }: Props) {

setNewLink({ ...newLink, url: e.target.value })} + value={link.url} + onChange={(e) => 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" @@ -116,10 +120,10 @@ export default function AddLink({ toggleLinkModal }: Props) {

(link); + const [currentLink, setCurrentLink] = + useState(link); const { updateLink, removeLink } = useLinkStore(); diff --git a/lib/api/controllers/links/deleteLink.ts b/lib/api/controllers/links/deleteLink.ts index 12342b5..308fa84 100644 --- a/lib/api/controllers/links/deleteLink.ts +++ b/lib/api/controllers/links/deleteLink.ts @@ -4,13 +4,17 @@ // You should have received a copy of the GNU General Public License along with this program. If not, see . import { prisma } from "@/lib/api/db"; -import { ExtendedLink } from "@/types/global"; +import { LinkIncludingCollectionAndTags } from "@/types/global"; import fs from "fs"; import { Link, UsersAndCollections } from "@prisma/client"; import getPermission from "@/lib/api/getPermission"; -export default async function (link: ExtendedLink, userId: number) { - if (!link) return { response: "Please choose a valid link.", status: 401 }; +export default async function ( + link: LinkIncludingCollectionAndTags, + userId: number +) { + if (!link || !link.collectionId) + return { response: "Please choose a valid link.", status: 401 }; const collectionIsAccessible = await getPermission(userId, link.collectionId); diff --git a/lib/api/controllers/links/postLink.ts b/lib/api/controllers/links/postLink.ts index 331ddac..f678a49 100644 --- a/lib/api/controllers/links/postLink.ts +++ b/lib/api/controllers/links/postLink.ts @@ -4,7 +4,7 @@ // You should have received a copy of the GNU General Public License along with this program. If not, see . import { prisma } from "@/lib/api/db"; -import { ExtendedLink } from "@/types/global"; +import { LinkIncludingCollectionAndTags } from "@/types/global"; import getTitle from "../../getTitle"; import archive from "../../archive"; import { Link, UsersAndCollections } from "@prisma/client"; @@ -12,7 +12,10 @@ import AES from "crypto-js/aes"; import getPermission from "@/lib/api/getPermission"; import { existsSync, mkdirSync } from "fs"; -export default async function (link: ExtendedLink, userId: number) { +export default async function ( + link: LinkIncludingCollectionAndTags, + userId: number +) { link.collection.name = link.collection.name.trim(); if (!link.name) { @@ -21,7 +24,7 @@ export default async function (link: ExtendedLink, userId: number) { return { response: "Please enter a valid collection name.", status: 401 }; } - if (link.collection.ownerId) { + if (link.collection.id) { const collectionIsAccessible = await getPermission( userId, link.collection.id @@ -81,8 +84,6 @@ export default async function (link: ExtendedLink, userId: number) { }, }); - console.log(newLink); - const AES_SECRET = process.env.AES_SECRET as string; const screenshotHashedPath = AES.encrypt( @@ -95,7 +96,7 @@ export default async function (link: ExtendedLink, userId: number) { AES_SECRET ).toString(); - const updatedLink: ExtendedLink = await prisma.link.update({ + const updatedLink = await prisma.link.update({ where: { id: newLink.id }, data: { screenshotPath: screenshotHashedPath, pdfPath: pdfHashedPath }, include: { tags: true, collection: true }, @@ -105,8 +106,6 @@ export default async function (link: ExtendedLink, userId: number) { if (!existsSync(collectionPath)) mkdirSync(collectionPath, { recursive: true }); - console.log(updatedLink); - archive(updatedLink.url, updatedLink.collectionId, updatedLink.id); return { response: updatedLink, status: 200 }; diff --git a/lib/api/controllers/links/updateLink.ts b/lib/api/controllers/links/updateLink.ts index 2854ed2..8e73f23 100644 --- a/lib/api/controllers/links/updateLink.ts +++ b/lib/api/controllers/links/updateLink.ts @@ -4,14 +4,17 @@ // You should have received a copy of the GNU General Public License along with this program. If not, see . import { prisma } from "@/lib/api/db"; -import { ExtendedLink } from "@/types/global"; +import { LinkIncludingCollectionAndTags } from "@/types/global"; import { UsersAndCollections } from "@prisma/client"; import getPermission from "@/lib/api/getPermission"; -export default async function (link: ExtendedLink, userId: number) { +export default async function ( + link: LinkIncludingCollectionAndTags, + userId: number +) { if (!link) return { response: "Please choose a valid link.", status: 401 }; - if (link.collection.ownerId) { + if (link.collection.id) { const collectionIsAccessible = await getPermission( userId, link.collection.id @@ -27,7 +30,7 @@ export default async function (link: ExtendedLink, userId: number) { link.collection.ownerId = userId; } - const updatedLink: ExtendedLink = await prisma.link.update({ + const updatedLink = await prisma.link.update({ where: { id: link.id, }, diff --git a/store/links.ts b/store/links.ts index 819a51d..0dc3f69 100644 --- a/store/links.ts +++ b/store/links.ts @@ -4,16 +4,16 @@ // You should have received a copy of the GNU General Public License along with this program. If not, see . import { create } from "zustand"; -import { ExtendedLink, NewLink } from "@/types/global"; +import { LinkIncludingCollectionAndTags } from "@/types/global"; import useTagStore from "./tags"; import useCollectionStore from "./collections"; type LinkStore = { - links: ExtendedLink[]; + links: LinkIncludingCollectionAndTags[]; setLinks: () => void; - addLink: (body: NewLink) => Promise; - updateLink: (link: ExtendedLink) => void; - removeLink: (link: ExtendedLink) => void; + addLink: (body: LinkIncludingCollectionAndTags) => Promise; + updateLink: (link: LinkIncludingCollectionAndTags) => void; + removeLink: (link: LinkIncludingCollectionAndTags) => void; }; const useLinkStore = create()((set) => ({ diff --git a/types/global.ts b/types/global.ts index 77822e8..b789c32 100644 --- a/types/global.ts +++ b/types/global.ts @@ -5,35 +5,16 @@ import { Collection, Link, Tag, User } from "@prisma/client"; -type OptionalExcluding = Partial & +export type OptionalExcluding = Partial & Pick; -export interface ExtendedLink extends Link { +export interface LinkIncludingCollectionAndTags + extends Omit { + id?: number; + createdAt?: string; + collectionId?: number; tags: Tag[]; - collection: Collection; -} - -export interface NewLink { - name: string; - url: string; - tags: Tag[]; - collection: { - id: number | undefined; - name: string | undefined; - ownerId: number | undefined; - }; -} - -export interface NewCollection { - name: string; - description: string; - members: { - name: string; - email: string; - canCreate: boolean; - canUpdate: boolean; - canDelete: boolean; - }[]; + collection: OptionalExcluding; } export interface Member {