From 6112db1bb6bad365435d8a5fa65f55b65eb116cd Mon Sep 17 00:00:00 2001 From: Dave Date: Wed, 16 Sep 2026 11:31:00 +0200 Subject: [PATCH] feat(archive): archived card list with unarchive --- src/app/actions/cards.ts | 24 +++++++ .../[projectSlug]/archive/page.tsx | 66 +++++++++++++++++++ src/app/p/[clientSlug]/[projectSlug]/page.tsx | 10 ++- 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 src/app/p/[clientSlug]/[projectSlug]/archive/page.tsx diff --git a/src/app/actions/cards.ts b/src/app/actions/cards.ts index 256b2ac..6ae492c 100644 --- a/src/app/actions/cards.ts +++ b/src/app/actions/cards.ts @@ -202,4 +202,28 @@ export async function archiveCard(input: { }); revalidatePath(boardPath(input.clientSlug, input.projectSlug)); +} + +export async function unarchiveCard(input: { + cardId: string; + clientSlug: string; + projectSlug: string; +}): Promise { + const session = await requireOwner(); + const pb = await getServerPb(); + + const card = await pb.collection("cards").getOne(input.cardId); + + await pb.collection("cards").update(input.cardId, { archived: false }); + + await logActivity({ + project: card.project, + card: card.id, + actor: session.userId, + action: "card_updated", + field: "archived", + }); + + revalidatePath(boardPath(input.clientSlug, input.projectSlug)); + revalidatePath(`${boardPath(input.clientSlug, input.projectSlug)}/archive`); } \ No newline at end of file diff --git a/src/app/p/[clientSlug]/[projectSlug]/archive/page.tsx b/src/app/p/[clientSlug]/[projectSlug]/archive/page.tsx new file mode 100644 index 0000000..7bedb06 --- /dev/null +++ b/src/app/p/[clientSlug]/[projectSlug]/archive/page.tsx @@ -0,0 +1,66 @@ +import Link from "next/link"; +import { notFound, redirect } from "next/navigation"; +import { ArrowLeft } from "lucide-react"; + +import { AppShell } from "@/components/shell/app-shell"; +import { TopBar } from "@/components/shell/top-bar"; +import { AdminTable, AdminCell } from "@/components/admin/admin-table"; +import { getSession } from "@/lib/auth/session"; +import { getServerPb } from "@/lib/pb/server"; +import { loadBoard } from "@/lib/data/board"; +import { relativeTime } from "@/lib/time/relative"; +import type { CardRecord } from "@/lib/pb/types"; + +export default async function ArchivePage({ + params, +}: { + params: Promise<{ clientSlug: string; projectSlug: string }>; +}) { + const session = await getSession(); + if (!session) redirect("/login"); + + const { clientSlug, projectSlug } = await params; + const board = await loadBoard(clientSlug, projectSlug); + if (!board) notFound(); + + const pb = await getServerPb(); + const cards = await pb.collection("cards").getFullList({ + filter: `project = "${board.project.id}" && archived = true`, + sort: "-updated", + }); + + const boardHref = `/p/${clientSlug}/${projectSlug}`; + + return ( + + + +
+ + + Back to board + + + + {cards.map((card) => ( + + + + {card.title} + + + {relativeTime(card.updated)} + {""} + + ))} + +
+
+ ); +} \ No newline at end of file diff --git a/src/app/p/[clientSlug]/[projectSlug]/page.tsx b/src/app/p/[clientSlug]/[projectSlug]/page.tsx index 7ec55de..ca8f23f 100644 --- a/src/app/p/[clientSlug]/[projectSlug]/page.tsx +++ b/src/app/p/[clientSlug]/[projectSlug]/page.tsx @@ -1,3 +1,4 @@ +import Link from "next/link"; import { notFound, redirect } from "next/navigation"; import { AppShell } from "@/components/shell/app-shell"; @@ -27,7 +28,14 @@ export default async function BoardPage({ role={session.role} currentPath={`/p/${clientSlug}/${projectSlug}`} > - + + + Archive + +