feat: delete lists

This commit is contained in:
Henry
2024-01-02 11:24:08 +00:00
parent 0a0bfe9c76
commit 8fdacd1388
11 changed files with 852 additions and 18 deletions

View File

@@ -29,7 +29,7 @@ export default async function Layout(props: { children: React.ReactNode }) {
<div className="flex h-full w-full">
<nav className="flex w-72 flex-col justify-between border-r border-dark-600 px-5 py-5">
<div>
<ul role="list" className="-mx-2 my-6 space-y-1">
<ul role="list" className="-mx-2 my-3 space-y-1">
{navigation.map((item) => (
<li key={item.name}>
<ReactiveButton
@@ -42,7 +42,6 @@ export default async function Layout(props: { children: React.ReactNode }) {
))}
</ul>
</div>
<button className="flex items-center">
{session?.user.image ? (
<Image
@@ -52,12 +51,23 @@ export default async function Layout(props: { children: React.ReactNode }) {
height={30}
alt=""
/>
) : null}
<p className="ml-2 truncate text-sm text-dark-1000">
) : (
<span className="inline-block h-6 w-6 overflow-hidden rounded-full bg-dark-400">
<svg
className="h-full w-full text-dark-700"
fill="currentColor"
viewBox="0 0 24 24"
>
<path d="M24 20.993V24H0v-2.996A14.977 14.977 0 0112.004 15c4.904 0 9.26 2.354 11.996 5.993zM16.002 8.999a4 4 0 11-8 0 4 4 0 018 0z" />
</svg>
</span>
)}
<p className="ml-2 truncate text-sm text-dark-900">
{session?.user.email}
</p>
</button>
</nav>
<div className="w-full overflow-hidden">{props.children}</div>
</div>
</main>

View File

@@ -0,0 +1,58 @@
"use client";
import { api } from "~/trpc/react";
import { useBoard } from "~/app/providers/board";
import { useModal } from "~/app/providers/modal";
interface DeleteListConfirmationProps {
listPublicId: string;
}
export function DeleteListConfirmation({
listPublicId,
}: DeleteListConfirmationProps) {
const utils = api.useUtils();
const { boardData } = useBoard();
const { closeModal } = useModal();
const refetchBoard = () =>
utils.board.byId.refetch({ id: boardData.publicId });
const deleteList = api.list.delete.useMutation({
onSuccess: async () => {
closeModal();
await refetchBoard();
},
});
return (
<>
<div className="flex w-full flex-col justify-between pb-4">
<h2 className="text-md pb-4 font-medium text-dark-1000">
Are you sure you want to delete this list?
</h2>
<p className="text-sm font-medium text-dark-900">
{"This action can't be undone."}
</p>
</div>
<div className="mt-5 flex justify-end sm:mt-6">
<button
className="mr-4 inline-flex justify-center rounded-md border-[1px] border-dark-600 bg-dark-300 px-3 py-2 text-sm font-semibold text-dark-1000 shadow-sm focus-visible:outline-none"
onClick={() => closeModal()}
>
Cancel
</button>
<button
onClick={() =>
deleteList.mutate({
listPublicId,
})
}
className="inline-flex justify-center rounded-md bg-dark-1000 px-3 py-2 text-sm font-semibold text-dark-50 shadow-sm focus-visible:outline-none"
>
Delete
</button>
</div>
</>
);
}

View File

@@ -0,0 +1,54 @@
import { Fragment } from "react";
import { Menu, Transition } from "@headlessui/react";
import { HiEllipsisHorizontal } from "react-icons/hi2";
import { useModal } from "~/app/providers/modal";
interface ListDropdownProps {
setSelectedPublicListId: () => void;
}
export default function ListDropdown({
setSelectedPublicListId,
}: ListDropdownProps) {
const { openModal } = useModal();
const handleOpenDeleteListConfirmation = () => {
setSelectedPublicListId();
openModal("DELETE_LIST");
};
return (
<Menu as="div" className="relative inline-block text-left">
<div>
<Menu.Button className="mr-1 inline-flex h-fit items-center rounded-md p-1 px-1 text-sm font-semibold text-dark-50 hover:bg-dark-400">
<HiEllipsisHorizontal className="h-5 w-5 text-dark-900" />
</Menu.Button>
</div>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="absolute right-0 z-10 mt-2 w-56 origin-top-right rounded-md border border-dark-400 bg-dark-300 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
<div className="flex">
<Menu.Item>
{() => (
<button
onClick={handleOpenDeleteListConfirmation}
className="m-1 w-full rounded-[5px] px-3 py-2 text-left text-sm text-dark-1000 hover:bg-dark-400"
>
Delete list
</button>
)}
</Menu.Item>
</div>
</Menu.Items>
</Transition>
</Menu>
);
}

View File

@@ -18,6 +18,8 @@ import { useModal } from "~/app/providers/modal";
import Modal from "~/app/_components/modal";
import { DeleteListConfirmation } from "./DeleteListConfirmation";
import ListDropdown from "./ListDropdown";
import { NewCardForm } from "./NewCardForm";
import { NewListForm } from "./NewListForm";
@@ -210,15 +212,22 @@ export default function BoardPage() {
<p className="mb-4 px-4 pt-1 text-sm font-medium text-dark-1000">
{list.name}
</p>
<button
className="mx-1 inline-flex h-fit items-center rounded-md p-1 px-1 text-sm font-semibold text-dark-50 hover:bg-dark-400"
onClick={() => openNewCardForm(list.publicId)}
>
<HiOutlinePlusSmall
className="h-5 w-5 text-dark-900"
aria-hidden="true"
<div>
<button
className="mx-1 inline-flex h-fit items-center rounded-md p-1 px-1 text-sm font-semibold text-dark-50 hover:bg-dark-400"
onClick={() => openNewCardForm(list.publicId)}
>
<HiOutlinePlusSmall
className="h-5 w-5 text-dark-900"
aria-hidden="true"
/>
</button>
<ListDropdown
setSelectedPublicListId={() =>
setSelectedPublicListId(list.publicId)
}
/>
</button>
</div>
</div>
<Droppable droppableId={`${list.publicId}`} type="CARD">
{(provided) => (
@@ -283,6 +292,9 @@ export default function BoardPage() {
</DragDropContext>
</div>
<Modal>
{modalContentType === "DELETE_LIST" && (
<DeleteListConfirmation listPublicId={selectedPublicListId} />
)}
{modalContentType === "NEW_CARD" && (
<NewCardForm listPublicId={selectedPublicListId} />
)}

View File

@@ -26,7 +26,7 @@ export default function RootLayout({
}) {
return (
<html lang="en" className={`${jakarta.variable}`}>
<body>
<body className="h-screen overflow-hidden">
<TRPCReactProvider headers={headers()}>
<ModalProvider>
<BoardProvider>{children}</BoardProvider>