renamed a type + small improvements

This commit is contained in:
Daniel 2023-06-16 16:25:21 +03:30
parent 93558bb791
commit c1831b650d
18 changed files with 70 additions and 70 deletions

View File

@ -1,8 +1,7 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faEllipsis, faLink } from "@fortawesome/free-solid-svg-icons"; import { faEllipsis, faLink } from "@fortawesome/free-solid-svg-icons";
import Link from "next/link"; import Link from "next/link";
import { CollectionIncludingMembers } from "@/types/global"; import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
import useLinkStore from "@/store/links";
import Dropdown from "./Dropdown"; import Dropdown from "./Dropdown";
import { useState } from "react"; import { useState } from "react";
import ProfilePhoto from "./ProfilePhoto"; import ProfilePhoto from "./ProfilePhoto";
@ -10,14 +9,13 @@ import { faCalendarDays } from "@fortawesome/free-regular-svg-icons";
import useModalStore from "@/store/modals"; import useModalStore from "@/store/modals";
type Props = { type Props = {
collection: CollectionIncludingMembers; collection: CollectionIncludingMembersAndLinkCount;
className?: string; className?: string;
}; };
export default function CollectionCard({ collection, className }: Props) { export default function CollectionCard({ collection, className }: Props) {
const { setModal } = useModalStore(); const { setModal } = useModalStore();
const { links } = useLinkStore();
const formattedDate = new Date(collection.createdAt as string).toLocaleString( const formattedDate = new Date(collection.createdAt as string).toLocaleString(
"en-US", "en-US",
{ {
@ -74,7 +72,7 @@ export default function CollectionCard({ collection, className }: Props) {
<div className="text-right w-40"> <div className="text-right w-40">
<div className="text-sky-500 font-bold text-sm flex justify-end gap-1 items-center"> <div className="text-sky-500 font-bold text-sm flex justify-end gap-1 items-center">
<FontAwesomeIcon icon={faLink} className="w-5 h-5 text-sky-600" /> <FontAwesomeIcon icon={faLink} className="w-5 h-5 text-sky-600" />
{links.filter((e) => e.collectionId === collection.id).length} {collection._count.links}
</div> </div>
<div className="flex items-center justify-end gap-1 text-gray-600"> <div className="flex items-center justify-end gap-1 text-gray-600">
<FontAwesomeIcon icon={faCalendarDays} className="w-4 h-4" /> <FontAwesomeIcon icon={faCalendarDays} className="w-4 h-4" />

View File

@ -1,5 +1,5 @@
import { import {
CollectionIncludingMembers, CollectionIncludingMembersAndLinkCount,
LinkIncludingShortenedCollectionAndTags, LinkIncludingShortenedCollectionAndTags,
} from "@/types/global"; } from "@/types/global";
import { import {
@ -34,17 +34,18 @@ export default function LinkCard({ link, count, className }: Props) {
const { account } = useAccountStore(); const { account } = useAccountStore();
const [collection, setCollection] = useState<CollectionIncludingMembers>( const [collection, setCollection] =
collections.find( useState<CollectionIncludingMembersAndLinkCount>(
(e) => e.id === link.collection.id collections.find(
) as CollectionIncludingMembers (e) => e.id === link.collection.id
); ) as CollectionIncludingMembersAndLinkCount
);
useEffect(() => { useEffect(() => {
setCollection( setCollection(
collections.find( collections.find(
(e) => e.id === link.collection.id (e) => e.id === link.collection.id
) as CollectionIncludingMembers ) as CollectionIncludingMembersAndLinkCount
); );
}, [collections]); }, [collections]);

View File

@ -5,7 +5,7 @@ import {
faPlus, faPlus,
} from "@fortawesome/free-solid-svg-icons"; } from "@fortawesome/free-solid-svg-icons";
import useCollectionStore from "@/store/collections"; import useCollectionStore from "@/store/collections";
import { CollectionIncludingMembers } from "@/types/global"; import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
import RequiredBadge from "../../RequiredBadge"; import RequiredBadge from "../../RequiredBadge";
import SubmitButton from "@/components/SubmitButton"; import SubmitButton from "@/components/SubmitButton";
import { HexColorPicker } from "react-colorful"; import { HexColorPicker } from "react-colorful";
@ -13,8 +13,10 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
type Props = { type Props = {
toggleCollectionModal: Function; toggleCollectionModal: Function;
setCollection: Dispatch<SetStateAction<CollectionIncludingMembers>>; setCollection: Dispatch<
collection: CollectionIncludingMembers; SetStateAction<CollectionIncludingMembersAndLinkCount>
>;
collection: CollectionIncludingMembersAndLinkCount;
method: "CREATE" | "UPDATE"; method: "CREATE" | "UPDATE";
}; };

View File

@ -1,13 +1,13 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faTrashCan } from "@fortawesome/free-solid-svg-icons"; import { faTrashCan } from "@fortawesome/free-solid-svg-icons";
import { CollectionIncludingMembers } from "@/types/global"; import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
import useCollectionStore from "@/store/collections"; import useCollectionStore from "@/store/collections";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
type Props = { type Props = {
toggleDeleteCollectionModal: Function; toggleDeleteCollectionModal: Function;
collection: CollectionIncludingMembers; collection: CollectionIncludingMembersAndLinkCount;
}; };
export default function DeleteCollection({ export default function DeleteCollection({

View File

@ -7,7 +7,7 @@ import {
faUserPlus, faUserPlus,
} from "@fortawesome/free-solid-svg-icons"; } from "@fortawesome/free-solid-svg-icons";
import useCollectionStore from "@/store/collections"; import useCollectionStore from "@/store/collections";
import { CollectionIncludingMembers, Member } from "@/types/global"; import { CollectionIncludingMembersAndLinkCount, Member } from "@/types/global";
import { useSession } from "next-auth/react"; import { useSession } from "next-auth/react";
import addMemberToCollection from "@/lib/client/addMemberToCollection"; import addMemberToCollection from "@/lib/client/addMemberToCollection";
import Checkbox from "../../Checkbox"; import Checkbox from "../../Checkbox";
@ -16,8 +16,10 @@ import ProfilePhoto from "@/components/ProfilePhoto";
type Props = { type Props = {
toggleCollectionModal: Function; toggleCollectionModal: Function;
setCollection: Dispatch<SetStateAction<CollectionIncludingMembers>>; setCollection: Dispatch<
collection: CollectionIncludingMembers; SetStateAction<CollectionIncludingMembersAndLinkCount>
>;
collection: CollectionIncludingMembersAndLinkCount;
method: "CREATE" | "UPDATE"; method: "CREATE" | "UPDATE";
}; };

View File

@ -1,13 +1,13 @@
import { Tab } from "@headlessui/react"; import { Tab } from "@headlessui/react";
import CollectionInfo from "./CollectionInfo"; import CollectionInfo from "./CollectionInfo";
import { CollectionIncludingMembers } from "@/types/global"; import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
import TeamManagement from "./TeamManagement"; import TeamManagement from "./TeamManagement";
import { useState } from "react"; import { useState } from "react";
import DeleteCollection from "./DeleteCollection"; import DeleteCollection from "./DeleteCollection";
type Props = { type Props = {
toggleCollectionModal: Function; toggleCollectionModal: Function;
activeCollection: CollectionIncludingMembers; activeCollection: CollectionIncludingMembersAndLinkCount;
method: "CREATE" | "UPDATE"; method: "CREATE" | "UPDATE";
className?: string; className?: string;
defaultIndex?: number; defaultIndex?: number;
@ -21,7 +21,7 @@ export default function CollectionModal({
method, method,
}: Props) { }: Props) {
const [collection, setCollection] = const [collection, setCollection] =
useState<CollectionIncludingMembers>(activeCollection); useState<CollectionIncludingMembersAndLinkCount>(activeCollection);
return ( return (
<div className={className}> <div className={className}>

View File

@ -3,7 +3,7 @@ import Modal from "./Modal";
import LinkModal from "./Modal/LinkModal"; import LinkModal from "./Modal/LinkModal";
import { import {
AccountSettings, AccountSettings,
CollectionIncludingMembers, CollectionIncludingMembersAndLinkCount,
LinkIncludingShortenedCollectionAndTags, LinkIncludingShortenedCollectionAndTags,
} from "@/types/global"; } from "@/types/global";
import CollectionModal from "./Modal/Collection"; import CollectionModal from "./Modal/Collection";
@ -33,7 +33,9 @@ export default function ModalManagement() {
toggleCollectionModal={toggleModal} toggleCollectionModal={toggleModal}
method={modal.method} method={modal.method}
defaultIndex={modal.defaultIndex} defaultIndex={modal.defaultIndex}
activeCollection={modal.active as CollectionIncludingMembers} activeCollection={
modal.active as CollectionIncludingMembersAndLinkCount
}
/> />
</Modal> </Modal>
); );

View File

@ -1,12 +1,14 @@
import { import {
CollectionIncludingMembers, CollectionIncludingMembersAndLinkCount,
LinkIncludingShortenedCollectionAndTags, LinkIncludingShortenedCollectionAndTags,
Sort, Sort,
} from "@/types/global"; } from "@/types/global";
import { SetStateAction, useEffect } from "react"; import { SetStateAction, useEffect } from "react";
type Props< type Props<
T extends CollectionIncludingMembers | LinkIncludingShortenedCollectionAndTags T extends
| CollectionIncludingMembersAndLinkCount
| LinkIncludingShortenedCollectionAndTags
> = { > = {
sortBy: Sort; sortBy: Sort;
@ -15,7 +17,9 @@ type Props<
}; };
export default function useSort< export default function useSort<
T extends CollectionIncludingMembers | LinkIncludingShortenedCollectionAndTags T extends
| CollectionIncludingMembersAndLinkCount
| LinkIncludingShortenedCollectionAndTags
>({ sortBy, data, setData }: Props<T>) { >({ sortBy, data, setData }: Props<T>) {
useEffect(() => { useEffect(() => {
const dataArray = [...data]; const dataArray = [...data];

View File

@ -9,6 +9,9 @@ export default async function getCollection(userId: number) {
], ],
}, },
include: { include: {
_count: {
select: { links: true },
},
members: { members: {
include: { include: {
user: { user: {

View File

@ -1,9 +1,9 @@
import { prisma } from "@/lib/api/db"; import { prisma } from "@/lib/api/db";
import { CollectionIncludingMembers } from "@/types/global"; import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
import { existsSync, mkdirSync } from "fs"; import { existsSync, mkdirSync } from "fs";
export default async function postCollection( export default async function postCollection(
collection: CollectionIncludingMembers, collection: CollectionIncludingMembersAndLinkCount,
userId: number userId: number
) { ) {
if (!collection || collection.name.trim() === "") if (!collection || collection.name.trim() === "")
@ -50,6 +50,9 @@ export default async function postCollection(
}, },
}, },
include: { include: {
_count: {
select: { links: true },
},
members: { members: {
include: { include: {
user: { user: {

View File

@ -1,9 +1,9 @@
import { prisma } from "@/lib/api/db"; import { prisma } from "@/lib/api/db";
import { CollectionIncludingMembers } from "@/types/global"; import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
import getPermission from "@/lib/api/getPermission"; import getPermission from "@/lib/api/getPermission";
export default async function updateCollection( export default async function updateCollection(
collection: CollectionIncludingMembers, collection: CollectionIncludingMembersAndLinkCount,
userId: number userId: number
) { ) {
if (!collection.id) if (!collection.id)
@ -27,6 +27,7 @@ export default async function updateCollection(
where: { where: {
id: collection.id, id: collection.id,
}, },
data: { data: {
name: collection.name, name: collection.name,
description: collection.description, description: collection.description,
@ -42,6 +43,9 @@ export default async function updateCollection(
}, },
}, },
include: { include: {
_count: {
select: { links: true },
},
members: { members: {
include: { include: {
user: { user: {

View File

@ -1,10 +1,10 @@
import { CollectionIncludingMembers, Member } from "@/types/global"; import { CollectionIncludingMembersAndLinkCount, Member } from "@/types/global";
import getPublicUserDataByEmail from "./getPublicUserDataByEmail"; import getPublicUserDataByEmail from "./getPublicUserDataByEmail";
const addMemberToCollection = async ( const addMemberToCollection = async (
ownerEmail: string, ownerEmail: string,
memberEmail: string, memberEmail: string,
collection: CollectionIncludingMembers, collection: CollectionIncludingMembersAndLinkCount,
setMember: (newMember: Member) => null | undefined setMember: (newMember: Member) => null | undefined
) => { ) => {
console.log(collection.members); console.log(collection.members);

View File

@ -1,26 +0,0 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { getServerSession } from "next-auth/next";
import { authOptions } from "pages/api/auth/[...nextauth]";
type Data = {
message: string;
data?: object;
};
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
const session = await getServerSession(req, res, authOptions);
console.log(session);
if (!session) {
res.status(401).json({ message: "You must be logged in." });
return;
}
return res.json({
message: "Success",
});
}

View File

@ -2,7 +2,7 @@ import Dropdown from "@/components/Dropdown";
import LinkCard from "@/components/LinkCard"; import LinkCard from "@/components/LinkCard";
import useCollectionStore from "@/store/collections"; import useCollectionStore from "@/store/collections";
import useLinkStore from "@/store/links"; import useLinkStore from "@/store/links";
import { CollectionIncludingMembers, Sort } from "@/types/global"; import { CollectionIncludingMembersAndLinkCount, Sort } from "@/types/global";
import { import {
faEllipsis, faEllipsis,
faFolder, faFolder,
@ -33,7 +33,7 @@ export default function Index() {
const [sortBy, setSortBy] = useState<Sort>(Sort.DateNewestFirst); const [sortBy, setSortBy] = useState<Sort>(Sort.DateNewestFirst);
const [activeCollection, setActiveCollection] = const [activeCollection, setActiveCollection] =
useState<CollectionIncludingMembers>(); useState<CollectionIncludingMembersAndLinkCount>();
useLinks({ collectionId: Number(router.query.id), sort: sortBy }); useLinks({ collectionId: Number(router.query.id), sort: sortBy });

View File

@ -77,7 +77,11 @@ export default function Dashboard() {
<div className="flex flex-col md:flex-row md:items-center justify-evenly gap-2 mb-10"> <div className="flex flex-col md:flex-row md:items-center justify-evenly gap-2 mb-10">
<div className="flex items-baseline gap-2"> <div className="flex items-baseline gap-2">
<p className="font-bold text-6xl bg-gradient-to-tr from-sky-500 to-slate-400 bg-clip-text text-transparent"> <p className="font-bold text-6xl bg-gradient-to-tr from-sky-500 to-slate-400 bg-clip-text text-transparent">
{links.length} {collections.reduce(
(accumulator, collection) =>
accumulator + collection._count.links,
0
)}
</p> </p>
<p className="text-sky-900 text-xl"> <p className="text-sky-900 text-xl">
Links Links

View File

@ -1,13 +1,15 @@
import { create } from "zustand"; import { create } from "zustand";
import { CollectionIncludingMembers } from "@/types/global"; import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
import useTagStore from "./tags"; import useTagStore from "./tags";
type CollectionStore = { type CollectionStore = {
collections: CollectionIncludingMembers[]; collections: CollectionIncludingMembersAndLinkCount[];
setCollections: () => void; setCollections: () => void;
addCollection: (body: CollectionIncludingMembers) => Promise<boolean>; addCollection: (
body: CollectionIncludingMembersAndLinkCount
) => Promise<boolean>;
updateCollection: ( updateCollection: (
collection: CollectionIncludingMembers collection: CollectionIncludingMembersAndLinkCount
) => Promise<boolean>; ) => Promise<boolean>;
removeCollection: (collectionId: number) => Promise<boolean>; removeCollection: (collectionId: number) => Promise<boolean>;
}; };

View File

@ -1,6 +1,6 @@
import { import {
AccountSettings, AccountSettings,
CollectionIncludingMembers, CollectionIncludingMembersAndLinkCount,
LinkIncludingShortenedCollectionAndTags, LinkIncludingShortenedCollectionAndTags,
} from "@/types/global"; } from "@/types/global";
import { create } from "zustand"; import { create } from "zustand";
@ -28,7 +28,7 @@ type Modal =
modal: "COLLECTION"; modal: "COLLECTION";
state: boolean; state: boolean;
method: "CREATE" | "UPDATE"; method: "CREATE" | "UPDATE";
active: CollectionIncludingMembers; active: CollectionIncludingMembersAndLinkCount;
defaultIndex?: number; defaultIndex?: number;
} }
| null; | null;

View File

@ -27,10 +27,11 @@ export interface Member {
user: OptionalExcluding<User, "email" | "name">; user: OptionalExcluding<User, "email" | "name">;
} }
export interface CollectionIncludingMembers export interface CollectionIncludingMembersAndLinkCount
extends Omit<Collection, "id" | "createdAt"> { extends Omit<Collection, "id" | "createdAt"> {
id?: number; id?: number;
createdAt?: string; createdAt?: string;
_count: { links: number };
members: Member[]; members: Member[];
} }