feat(archive): archived card list with unarchive
This commit is contained in:
parent
7ec075567b
commit
6112db1bb6
3 changed files with 99 additions and 1 deletions
|
|
@ -203,3 +203,27 @@ export async function archiveCard(input: {
|
|||
|
||||
revalidatePath(boardPath(input.clientSlug, input.projectSlug));
|
||||
}
|
||||
|
||||
export async function unarchiveCard(input: {
|
||||
cardId: string;
|
||||
clientSlug: string;
|
||||
projectSlug: string;
|
||||
}): Promise<void> {
|
||||
const session = await requireOwner();
|
||||
const pb = await getServerPb();
|
||||
|
||||
const card = await pb.collection("cards").getOne<CardRecord>(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`);
|
||||
}
|
||||
66
src/app/p/[clientSlug]/[projectSlug]/archive/page.tsx
Normal file
66
src/app/p/[clientSlug]/[projectSlug]/archive/page.tsx
Normal file
|
|
@ -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<CardRecord>({
|
||||
filter: `project = "${board.project.id}" && archived = true`,
|
||||
sort: "-updated",
|
||||
});
|
||||
|
||||
const boardHref = `/p/${clientSlug}/${projectSlug}`;
|
||||
|
||||
return (
|
||||
<AppShell role={session.role} currentPath={boardHref}>
|
||||
<TopBar title="Archive" subtitle={board.project.name} />
|
||||
|
||||
<div className="flex-1 space-y-4 overflow-y-auto p-6">
|
||||
<Link
|
||||
href={boardHref}
|
||||
className="inline-flex items-center gap-1.5 text-xs text-text-muted hover:text-text-secondary"
|
||||
>
|
||||
<ArrowLeft size={13} strokeWidth={2} />
|
||||
Back to board
|
||||
</Link>
|
||||
|
||||
<AdminTable
|
||||
headers={["Card", "Archived", ""]}
|
||||
empty="Nothing has been archived on this project."
|
||||
>
|
||||
{cards.map((card) => (
|
||||
<tr key={card.id}>
|
||||
<AdminCell className="font-medium text-text-primary">
|
||||
<Link href={`${boardHref}/c/${card.id}`} className="hover:text-brand">
|
||||
{card.title}
|
||||
</Link>
|
||||
</AdminCell>
|
||||
<AdminCell>{relativeTime(card.updated)}</AdminCell>
|
||||
<AdminCell align="right">{""}</AdminCell>
|
||||
</tr>
|
||||
))}
|
||||
</AdminTable>
|
||||
</div>
|
||||
</AppShell>
|
||||
);
|
||||
}
|
||||
|
|
@ -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}`}
|
||||
>
|
||||
<TopBar title={board.project.name} subtitle={board.client.name} />
|
||||
<TopBar title={board.project.name} subtitle={board.client.name}>
|
||||
<Link
|
||||
href={`/p/${clientSlug}/${projectSlug}/archive`}
|
||||
className="text-xs text-text-muted hover:text-text-secondary"
|
||||
>
|
||||
Archive
|
||||
</Link>
|
||||
</TopBar>
|
||||
<Board
|
||||
role={session.role}
|
||||
projectId={board.project.id}
|
||||
|
|
|
|||
Loading…
Reference in a new issue