import { useState, useEffect } from "react"; import Link from "next/link"; import { useRouter } from "next/router"; import { useParams } from "next/navigation"; import { HiOutlinePlusSmall } from "react-icons/hi2"; import { DragDropContext, Droppable, type DropResult, Draggable, } from "react-beautiful-dnd"; import { useForm } from "react-hook-form"; import { api } from "~/utils/api"; import { formatToArray } from "~/utils/helpers"; import { useBoard } from "~/providers/board"; import { useModal } from "~/providers/modal"; import Modal from "~/components/modal"; import PatternedBackground from "~/components/PatternedBackground"; import BoardDropdown from "./components/BoardDropdown"; import { DeleteBoardConfirmation } from "./components/DeleteBoardConfirmation"; import { DeleteListConfirmation } from "./components/DeleteListConfirmation"; import List from "./components/List"; import { NewWorkspaceForm } from "~/components/NewWorkspaceForm"; import { NewCardForm } from "./components/NewCardForm"; import { NewListForm } from "./components/NewListForm"; import Filters from "./components/Filters"; import { type UpdateBoardInput } from "~/types/router.types"; type PublicListId = string; export default function BoardPage() { const params = useParams(); const router = useRouter(); const { boardData, setBoardData, updateCard, updateList } = useBoard(); const { openModal, modalContentType } = useModal(); const [selectedPublicListId, setSelectedPublicListId] = useState(""); const boardId = params?.boardId?.length ? params.boardId[0] : null; const updateBoard = api.board.update.useMutation(); const { register, handleSubmit, setValue } = useForm({ values: { boardPublicId: boardId ?? "", name: "", }, }); const onSubmit = (values: UpdateBoardInput) => { updateBoard.mutate({ boardPublicId: values.boardPublicId, name: values.name, }); }; const { data, isSuccess, isLoading } = api.board.byId.useQuery( { boardPublicId: boardId ?? "", members: formatToArray(router.query.members), labels: formatToArray(router.query.labels), }, { enabled: !!boardId, }, ); useEffect(() => { if (isSuccess && data) { setBoardData(data); setValue("name", data.name || ""); } }, [isSuccess, data, setBoardData, setValue]); if (!boardId || !boardData) return <>; const openNewListForm = (publicBoardId: string) => { openModal("NEW_LIST"); setSelectedPublicListId(publicBoardId); }; const onDragEnd = ({ source, destination, draggableId, type, }: DropResult): void => { if (!destination) { return; } if (type === "LIST") { const updatedLists = Array.from(boardData.lists); const removedList = updatedLists.splice(source.index, 1)[0]; if (removedList) { updatedLists.splice(destination.index, 0, removedList); setBoardData({ ...boardData, lists: updatedLists }); } updateList({ listPublicId: draggableId, currentIndex: source.index, newIndex: destination.index, }); } if (type === "CARD") { const updatedLists = Array.from(boardData.lists); const sourceList = updatedLists.find( (list) => list.publicId === source.droppableId, ); const destinationList = updatedLists.find( (list) => list.publicId === destination.droppableId, ); const removedCard = sourceList?.cards.splice(source.index, 1)[0]; if (sourceList && destinationList && removedCard) { destinationList.cards.splice(destination.index, 0, removedCard); setBoardData({ ...boardData, lists: updatedLists }); } updateCard({ cardPublicId: draggableId, newListPublicId: destination.droppableId, newIndex: destination.index, }); } }; return (
{isLoading ? (
) : (
)}
{isLoading ? (
) : ( {(provided) => (
{boardData?.lists?.map((list, index) => ( setSelectedPublicListId(publicListId) } > {(provided) => (
{list.cards?.map((card, index) => ( {(provided) => ( { if ( card.publicId.startsWith("PLACEHOLDER") ) e.preventDefault(); }} key={card.publicId} href={`/cards/${card.publicId}`} className={`mb-2 flex !cursor-pointer flex-col rounded-md border border-light-200 bg-light-50 px-3 py-2 text-sm text-neutral-900 dark:border-dark-200 dark:bg-dark-300 dark:text-dark-1000 dark:hover:bg-dark-400 ${ card.publicId.startsWith("PLACEHOLDER") ? "pointer-events-none" : "" }`} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps} >
{card.title}
{(card.labels?.length ?? 0) || (card.members?.length ?? 0) ? (
{card.labels?.map((label) => (
{label.name}
))}
{card.members?.map((member) => ( {member?.user?.name ?.split(" ") .map((namePart) => namePart .charAt(0) .toUpperCase(), ) .join("")} ))}
) : null} )}
))} {provided.placeholder}
)}
))}
{provided.placeholder}
)} )}
{modalContentType === "DELETE_BOARD" && } {modalContentType === "DELETE_LIST" && ( )} {modalContentType === "NEW_CARD" && ( )} {modalContentType === "NEW_LIST" && ( )} {modalContentType === "NEW_WORKSPACE" && }
); }