import useAccountStore from "@/store/account"; import useCollectionStore from "@/store/collections"; import { CollectionIncludingMembersAndLinkCount } from "@/types/global"; import Link from "next/link"; import { useRouter } from "next/router"; import React, { useEffect, useState } from "react"; import { DragDropContext, Draggable, DraggableProvided, Droppable } from "react-beautiful-dnd"; type Props = { links: boolean; }; const CollectionSelection = ({ links }: Props) => { const { collections } = useCollectionStore(); const { account, updateAccount } = useAccountStore(); // Use local state to store the collection order so we don't have to wait for a response from the API to update the UI const [localCollectionOrder, setLocalCollectionOrder] = useState([]); const [active, setActive] = useState(""); const router = useRouter(); useEffect(() => { setActive(router.asPath); setLocalCollectionOrder(account.collectionOrder || []); if (!account.collectionOrder || account.collectionOrder.length === 0) { updateAccount({ ...account, collectionOrder: collections .filter((e) => e.parentId === null) // Filter out collections with non-null parentId .map((e) => e.id as number), // Use "as number" to assert that e.id is a number }); } }, [router, collections, account]); return ( { if (!result.destination) { return; // Dragged outside the droppable area, do nothing } const updatedCollectionOrder = [...account.collectionOrder]; const [movedCollectionId] = updatedCollectionOrder.splice(result.source.index, 1); updatedCollectionOrder.splice(result.destination.index, 0, movedCollectionId); // Update local state with the new collection order setLocalCollectionOrder(updatedCollectionOrder); // Update account with the new collection order updateAccount({ ...account, collectionOrder: updatedCollectionOrder, }); }} > {(provided) => (
{localCollectionOrder?.map((collectionId, index) => { const collection = collections.find((c) => c.id === collectionId); if (collection) { return ( {(provided) => ( )} ); } })} {provided.placeholder}
)}
); }; export default CollectionSelection; const CollectionItem = ({ collection, active, collections, innerRef, ...props }: { collection: CollectionIncludingMembersAndLinkCount; active: string; collections: CollectionIncludingMembersAndLinkCount[]; innerRef?: DraggableProvided["innerRef"]; }) => { const hasChildren = collections.some((e) => e.parentId === collection.id); // Check if the current collection or any of its subcollections is active const isActiveOrParentOfActive = React.useMemo(() => { const isActive = active === `/collections/${collection.id}`; if (isActive) return true; const checkIfParentOfActive = (parentId: number): boolean => { return collections.some((e) => { if (e.id === parseInt(active.split("/collections/")[1])) { if (e.parentId === parentId) return true; if (e.parentId) return checkIfParentOfActive(e.parentId); } return false; }); }; return checkIfParentOfActive(collection.id as number); }, [active, collection.id, collections]); const [isOpen, setIsOpen] = useState(isActiveOrParentOfActive); useEffect(() => { setIsOpen(isActiveOrParentOfActive); }, [isActiveOrParentOfActive]); return hasChildren ? ( <>

{collection.name}

{collection.isPublic ? ( ) : undefined}
{collection._count?.links}
{isOpen && hasChildren && (
{collections .filter((e) => e.parentId === collection.id) .map((subCollection) => ( ))}
)} ) : (

{collection.name}

{collection.isPublic ? ( ) : undefined}
{collection._count?.links}
); };