finalized dashboard

This commit is contained in:
Daniel 2023-06-13 22:49:37 +03:30
parent 41446f5bd4
commit 99cfbdf44b
10 changed files with 78 additions and 100 deletions

View File

@ -15,6 +15,7 @@ import Dropdown from "./Dropdown";
import useLinkStore from "@/store/links"; import useLinkStore from "@/store/links";
import Link from "next/link"; import Link from "next/link";
import useCollectionStore from "@/store/collections"; import useCollectionStore from "@/store/collections";
import useAccountStore from "@/store/account";
import useModalStore from "@/store/modals"; import useModalStore from "@/store/modals";
type Props = { type Props = {
@ -30,6 +31,8 @@ export default function LinkCard({ link, count, className }: Props) {
const { collections } = useCollectionStore(); const { collections } = useCollectionStore();
const { account } = useAccountStore();
const [collection, setCollection] = useState<CollectionIncludingMembers>( const [collection, setCollection] = useState<CollectionIncludingMembers>(
collections.find( collections.find(
(e) => e.id === link.collection.id (e) => e.id === link.collection.id
@ -44,7 +47,7 @@ export default function LinkCard({ link, count, className }: Props) {
); );
}, [collections]); }, [collections]);
const { removeLink } = useLinkStore(); const { removeLink, updateLink } = useLinkStore();
const url = new URL(link.url); const url = new URL(link.url);
const formattedDate = new Date(link.createdAt as string).toLocaleString( const formattedDate = new Date(link.createdAt as string).toLocaleString(
@ -66,7 +69,7 @@ export default function LinkCard({ link, count, className }: Props) {
width={42} width={42}
height={42} height={42}
alt="" alt=""
className="select-none mt-3 z-10 rounded-full shadow border-[3px] border-white bg-white" className="select-none mt-3 z-10 rounded-full shadow border-[3px] border-white bg-white aspect-square"
draggable="false" draggable="false"
onError={(e) => { onError={(e) => {
const target = e.target as HTMLElement; const target = e.target as HTMLElement;
@ -129,7 +132,7 @@ export default function LinkCard({ link, count, className }: Props) {
className="group/url" className="group/url"
> >
<div className="text-sky-400 font-bold flex items-center gap-1"> <div className="text-sky-400 font-bold flex items-center gap-1">
<p className="truncate w-40">{url.host}</p> <p className="truncate max-w-[10rem]">{url.host}</p>
<FontAwesomeIcon <FontAwesomeIcon
icon={faArrowUpRightFromSquare} icon={faArrowUpRightFromSquare}
className="w-3 opacity-0 group-hover/url:opacity-100 duration-75" className="w-3 opacity-0 group-hover/url:opacity-100 duration-75"
@ -182,6 +185,22 @@ export default function LinkCard({ link, count, className }: Props) {
{expandDropdown ? ( {expandDropdown ? (
<Dropdown <Dropdown
items={[ items={[
{
name:
link?.pinnedBy && link.pinnedBy[0]
? "Unpin"
: "Pin to Dashboard",
onClick: () => {
updateLink({
...link,
pinnedBy:
link?.pinnedBy && link.pinnedBy[0]
? undefined
: [{ id: account.id }],
});
setExpandDropdown(false);
},
},
{ {
name: "Edit", name: "Edit",
onClick: () => { onClick: () => {

View File

@ -37,8 +37,6 @@ export default function EditLink({
name: "", name: "",
url: "", url: "",
title: "", title: "",
screenshotPath: "",
pdfPath: "",
tags: [], tags: [],
collection: { collection: {
name: "", name: "",

View File

@ -33,9 +33,9 @@ export default function ProfilePhoto({
return error || !src ? ( return error || !src ? (
<div <div
className={`bg-sky-500 text-white h-10 w-10 shadow rounded-full border-[3px] border-slate-200 flex items-center justify-center ${className}`} className={`bg-sky-500 text-white h-10 w-10 aspect-square shadow rounded-full border-[3px] border-slate-200 flex items-center justify-center ${className}`}
> >
<FontAwesomeIcon icon={faUser} className="w-1/2 h-1/2" /> <FontAwesomeIcon icon={faUser} className="w-1/2 h-1/2 aspect-square" />
</div> </div>
) : ( ) : (
<Image <Image
@ -43,7 +43,7 @@ export default function ProfilePhoto({
src={src} src={src}
height={112} height={112}
width={112} width={112}
className={`h-10 w-10 shadow rounded-full border-[3px] border-slate-200 ${className}`} className={`h-10 w-10 shadow rounded-full aspect-square border-[3px] border-slate-200 ${className}`}
/> />
); );
} }

View File

@ -7,7 +7,7 @@ import Image from "next/image";
import { Link as LinkType } from "@prisma/client"; import { Link as LinkType } from "@prisma/client";
type Props = { type Props = {
link: Omit<LinkType, "screenshotPath" | "pdfPath">; link: LinkType;
count: number; count: number;
}; };

View File

@ -20,6 +20,10 @@ export default async function getLink(userId: number) {
include: { include: {
tags: true, tags: true,
collection: true, collection: true,
pinnedBy: {
where: { id: userId },
select: { id: true },
},
}, },
}); });

View File

@ -64,10 +64,18 @@ export default async function updateLink(
}, },
})), })),
}, },
pinnedBy:
link?.pinnedBy && link.pinnedBy[0]
? { connect: { id: userId } }
: { disconnect: { id: userId } },
}, },
include: { include: {
tags: true, tags: true,
collection: true, collection: true,
pinnedBy: {
where: { id: userId },
select: { id: true },
},
}, },
}); });

View File

@ -102,7 +102,7 @@ export default function Dashboard() {
<div className="flex flex-col 2xl:flex-row items-start justify-evenly 2xl:gap-2"> <div className="flex flex-col 2xl:flex-row items-start justify-evenly 2xl:gap-2">
<Disclosure defaultOpen={linkPinDisclosure}> <Disclosure defaultOpen={linkPinDisclosure}>
<div className="flex flex-col gap-5 p-2 w-full"> <div className="flex flex-col gap-5 p-2 w-full mx-auto md:w-2/3">
<Disclosure.Button <Disclosure.Button
onClick={() => { onClick={() => {
setLinkPinDisclosure(!linkPinDisclosure); setLinkPinDisclosure(!linkPinDisclosure);
@ -131,7 +131,9 @@ export default function Dashboard() {
leaveTo="transform opacity-0 -translate-y-3" leaveTo="transform opacity-0 -translate-y-3"
> >
<Disclosure.Panel className="flex flex-col gap-5 w-full"> <Disclosure.Panel className="flex flex-col gap-5 w-full">
{links.slice(0, 5).map((e, i) => ( {links
.filter((e) => e.pinnedBy && e.pinnedBy[0])
.map((e, i) => (
<LinkCard key={i} link={e} count={i} /> <LinkCard key={i} link={e} count={i} />
))} ))}
</Disclosure.Panel> </Disclosure.Panel>
@ -139,7 +141,7 @@ export default function Dashboard() {
</div> </div>
</Disclosure> </Disclosure>
<Disclosure defaultOpen={collectionPinDisclosure}> {/* <Disclosure defaultOpen={collectionPinDisclosure}>
<div className="flex flex-col gap-5 p-2 w-full"> <div className="flex flex-col gap-5 p-2 w-full">
<Disclosure.Button <Disclosure.Button
onClick={() => { onClick={() => {
@ -174,9 +176,9 @@ export default function Dashboard() {
</Disclosure.Panel> </Disclosure.Panel>
</Transition> </Transition>
</div> </div>
</Disclosure> </Disclosure> */}
<Disclosure defaultOpen={tagPinDisclosure}> {/* <Disclosure defaultOpen={tagPinDisclosure}>
<div className="flex flex-col gap-5 p-2 w-full"> <div className="flex flex-col gap-5 p-2 w-full">
<Disclosure.Button <Disclosure.Button
onClick={() => { onClick={() => {
@ -217,7 +219,7 @@ export default function Dashboard() {
</Disclosure.Panel> </Disclosure.Panel>
</Transition> </Transition>
</div> </div>
</Disclosure> </Disclosure> */}
</div> </div>
</div> </div>
</MainLayout> </MainLayout>

View File

@ -24,33 +24,6 @@ CREATE TABLE "Collection" (
CONSTRAINT "Collection_pkey" PRIMARY KEY ("id") CONSTRAINT "Collection_pkey" PRIMARY KEY ("id")
); );
-- CreateTable
CREATE TABLE "PinnedCollections" (
"id" SERIAL NOT NULL,
"userId" INTEGER NOT NULL,
"collectionId" INTEGER NOT NULL,
CONSTRAINT "PinnedCollections_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PinnedLinks" (
"id" SERIAL NOT NULL,
"userId" INTEGER NOT NULL,
"linkId" INTEGER NOT NULL,
CONSTRAINT "PinnedLinks_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PinnedTags" (
"id" SERIAL NOT NULL,
"userId" INTEGER NOT NULL,
"tagId" INTEGER NOT NULL,
CONSTRAINT "PinnedTags_pkey" PRIMARY KEY ("id")
);
-- CreateTable -- CreateTable
CREATE TABLE "UsersAndCollections" ( CREATE TABLE "UsersAndCollections" (
"userId" INTEGER NOT NULL, "userId" INTEGER NOT NULL,
@ -83,6 +56,12 @@ CREATE TABLE "Tag" (
CONSTRAINT "Tag_pkey" PRIMARY KEY ("id") CONSTRAINT "Tag_pkey" PRIMARY KEY ("id")
); );
-- CreateTable
CREATE TABLE "_LinkToUser" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL
);
-- CreateTable -- CreateTable
CREATE TABLE "_LinkToTag" ( CREATE TABLE "_LinkToTag" (
"A" INTEGER NOT NULL, "A" INTEGER NOT NULL,
@ -98,6 +77,12 @@ CREATE UNIQUE INDEX "Collection_name_ownerId_key" ON "Collection"("name", "owner
-- CreateIndex -- CreateIndex
CREATE UNIQUE INDEX "Tag_name_ownerId_key" ON "Tag"("name", "ownerId"); CREATE UNIQUE INDEX "Tag_name_ownerId_key" ON "Tag"("name", "ownerId");
-- CreateIndex
CREATE UNIQUE INDEX "_LinkToUser_AB_unique" ON "_LinkToUser"("A", "B");
-- CreateIndex
CREATE INDEX "_LinkToUser_B_index" ON "_LinkToUser"("B");
-- CreateIndex -- CreateIndex
CREATE UNIQUE INDEX "_LinkToTag_AB_unique" ON "_LinkToTag"("A", "B"); CREATE UNIQUE INDEX "_LinkToTag_AB_unique" ON "_LinkToTag"("A", "B");
@ -107,24 +92,6 @@ CREATE INDEX "_LinkToTag_B_index" ON "_LinkToTag"("B");
-- AddForeignKey -- AddForeignKey
ALTER TABLE "Collection" ADD CONSTRAINT "Collection_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; ALTER TABLE "Collection" ADD CONSTRAINT "Collection_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PinnedCollections" ADD CONSTRAINT "PinnedCollections_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PinnedCollections" ADD CONSTRAINT "PinnedCollections_collectionId_fkey" FOREIGN KEY ("collectionId") REFERENCES "Collection"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PinnedLinks" ADD CONSTRAINT "PinnedLinks_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PinnedLinks" ADD CONSTRAINT "PinnedLinks_linkId_fkey" FOREIGN KEY ("linkId") REFERENCES "Link"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PinnedTags" ADD CONSTRAINT "PinnedTags_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PinnedTags" ADD CONSTRAINT "PinnedTags_tagId_fkey" FOREIGN KEY ("tagId") REFERENCES "Tag"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey -- AddForeignKey
ALTER TABLE "UsersAndCollections" ADD CONSTRAINT "UsersAndCollections_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; ALTER TABLE "UsersAndCollections" ADD CONSTRAINT "UsersAndCollections_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
@ -137,6 +104,12 @@ ALTER TABLE "Link" ADD CONSTRAINT "Link_collectionId_fkey" FOREIGN KEY ("collect
-- AddForeignKey -- AddForeignKey
ALTER TABLE "Tag" ADD CONSTRAINT "Tag_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; ALTER TABLE "Tag" ADD CONSTRAINT "Tag_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_LinkToUser" ADD CONSTRAINT "_LinkToUser_A_fkey" FOREIGN KEY ("A") REFERENCES "Link"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_LinkToUser" ADD CONSTRAINT "_LinkToUser_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey -- AddForeignKey
ALTER TABLE "_LinkToTag" ADD CONSTRAINT "_LinkToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "Link"("id") ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE "_LinkToTag" ADD CONSTRAINT "_LinkToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "Link"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -14,9 +14,9 @@ model User {
password String password String
collections Collection[] collections Collection[]
tags Tag[] tags Tag[]
pinnedCollections PinnedCollections[]
pinnedLinks PinnedLinks[] pinnedLinks Link[]
pinnedTags PinnedTags[]
collectionsJoined UsersAndCollections[] collectionsJoined UsersAndCollections[]
isPrivate Boolean @default(false) isPrivate Boolean @default(false)
whitelistedUsers String[] @default([]) whitelistedUsers String[] @default([])
@ -29,7 +29,8 @@ model Collection {
description String @default("") description String @default("")
color String @default("#0ea5e9") color String @default("#0ea5e9")
isPublic Boolean @default(false) isPublic Boolean @default(false)
pins PinnedCollections[]
owner User @relation(fields: [ownerId], references: [id]) owner User @relation(fields: [ownerId], references: [id])
ownerId Int ownerId Int
members UsersAndCollections[] members UsersAndCollections[]
@ -39,37 +40,6 @@ model Collection {
@@unique([name, ownerId]) @@unique([name, ownerId])
} }
model PinnedCollections {
id Int @id @default(autoincrement())
user User @relation(fields: [userId], references: [id])
userId Int
collection Collection @relation(fields: [collectionId], references: [id])
collectionId Int
}
model PinnedLinks {
id Int @id @default(autoincrement())
user User @relation(fields: [userId], references: [id])
userId Int
link Link @relation(fields: [linkId], references: [id])
linkId Int
}
model PinnedTags {
id Int @id @default(autoincrement())
user User @relation(fields: [userId], references: [id])
userId Int
tag Tag @relation(fields: [tagId], references: [id])
tagId Int
}
model UsersAndCollections { model UsersAndCollections {
user User @relation(fields: [userId], references: [id]) user User @relation(fields: [userId], references: [id])
userId Int userId Int
@ -89,10 +59,12 @@ model Link {
name String name String
url String url String
title String title String
pinnedBy User[]
collection Collection @relation(fields: [collectionId], references: [id]) collection Collection @relation(fields: [collectionId], references: [id])
collectionId Int collectionId Int
tags Tag[] tags Tag[]
pins PinnedLinks[]
createdAt DateTime @default(now()) createdAt DateTime @default(now())
} }
@ -100,7 +72,6 @@ model Tag {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
name String name String
links Link[] links Link[]
pins PinnedTags[]
owner User @relation(fields: [ownerId], references: [id]) owner User @relation(fields: [ownerId], references: [id])
ownerId Int ownerId Int

View File

@ -9,6 +9,9 @@ export interface LinkIncludingCollectionAndTags
createdAt?: string; createdAt?: string;
collectionId?: number; collectionId?: number;
tags: Tag[]; tags: Tag[];
pinnedBy?: {
id: number;
}[];
collection: OptionalExcluding<Collection, "name" | "ownerId">; collection: OptionalExcluding<Collection, "name" | "ownerId">;
} }
@ -37,5 +40,5 @@ export interface AccountSettings extends User {
export interface PublicCollectionIncludingLinks export interface PublicCollectionIncludingLinks
extends Omit<Collection, "ownerId"> { extends Omit<Collection, "ownerId"> {
ownerName?: string; ownerName?: string;
links: Omit<Link, "screenshotPath" | "pdfPath">[]; links: Link[];
} }