"use client";
import {
AlertDialog,
AlertDialogClose,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogPopup,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/siteplane/components/alert-dialog";
import { Badge } from "@/siteplane/components/badge";
import { Button } from "@/siteplane/components/button";
import {
DataList,
DataListItem,
DataListLabel,
DataListValue,
} from "@/siteplane/components/data-list";
import {
DetailDrawer,
DetailDrawerBody,
DetailDrawerClose,
DetailDrawerDescription,
DetailDrawerFooter,
DetailDrawerHeader,
DetailDrawerPopup,
DetailDrawerTitle,
} from "@/siteplane/components/detail-drawer";
import {
FilterBar,
FilterBarControls,
FilterBarFilters,
FilterBarSearch,
} from "@/siteplane/components/filter-bar";
import { Input } from "@/siteplane/components/input";
import {
Select,
SelectItem,
SelectPopup,
SelectTrigger,
SelectValue,
} from "@/siteplane/components/select";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
type SortDescriptor,
} from "@/siteplane/components/table";
import { useState } from "react";
const statuses = [
{ value: "All", label: "All statuses" },
{ value: "Active", label: "Active" },
{ value: "Archived", label: "Archived" },
];
export default function Example() {
const [projects, setProjects] = useState([
{
id: "website",
name: "Website redesign",
owner: "Mara Ellis",
status: "Active",
},
{
id: "mobile",
name: "Mobile application",
owner: "Ben Carter",
status: "Active",
},
{
id: "research",
name: "Customer research",
owner: "Sofia Nguyen",
status: "Archived",
},
]);
const [query, setQuery] = useState("");
const [status, setStatus] = useState("All");
const [sort, setSort] = useState<SortDescriptor>({
column: "name",
direction: "ascending",
});
const [activeId, setActiveId] = useState<string>();
const [open, setOpen] = useState(false);
const [confirm, setConfirm] = useState(false);
const active = projects.find((project) => project.id === activeId);
const visible = projects
.filter(
(project) =>
project.name.toLowerCase().includes(query.toLowerCase()) &&
(status === "All" || project.status === status),
)
.sort((a, b) => {
const key = sort.column === "owner" ? "owner" : "name";
return (
a[key].localeCompare(b[key]) * (sort.direction === "ascending" ? 1 : -1)
);
});
return (
<div className="grid w-full min-w-0 gap-4">
<div>
<h2 className="text-lg font-semibold">Projects</h2>
<p className="text-sm text-foreground">
Find a project, review its details, or archive it.
</p>
</div>
<FilterBar aria-label="Project filters">
<FilterBarControls>
<FilterBarSearch>
<Input
aria-label="Search projects"
type="search"
placeholder="Search projects…"
value={query}
onChange={(event) => setQuery(event.target.value)}
/>
</FilterBarSearch>
<FilterBarFilters>
<Select
items={statuses}
value={status}
onValueChange={(value) => {
if (value) setStatus(value);
}}
>
<SelectTrigger aria-label="Filter by status">
<SelectValue />
</SelectTrigger>
<SelectPopup>
{statuses.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectPopup>
</Select>
</FilterBarFilters>
</FilterBarControls>
</FilterBar>
<Table aria-label="Projects" sortDescriptor={sort} onSortChange={setSort}>
<TableHeader>
<TableHead id="name" isRowHeader allowsSorting>
Project
</TableHead>
<TableHead id="owner" allowsSorting>
Owner
</TableHead>
<TableHead id="status">Status</TableHead>
<TableHead id="actions">Actions</TableHead>
</TableHeader>
<TableBody renderEmptyState={() => "No projects match your filters."}>
{visible.map((project) => (
<TableRow id={project.id} key={project.id} textValue={project.name}>
<TableCell>{project.name}</TableCell>
<TableCell>{project.owner}</TableCell>
<TableCell>
<Badge
variant={
project.status === "Active" ? "success" : "secondary"
}
>
{project.status}
</Badge>
</TableCell>
<TableCell>
<Button
variant="ghost"
size="sm"
aria-label={`View ${project.name}`}
onClick={() => {
setActiveId(project.id);
setOpen(true);
}}
>
View
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<DetailDrawer open={open} onOpenChange={setOpen}>
<DetailDrawerPopup>
<DetailDrawerHeader>
<DetailDrawerTitle>
{active?.name ?? "Project details"}
</DetailDrawerTitle>
<DetailDrawerDescription>
Owner and current status.
</DetailDrawerDescription>
</DetailDrawerHeader>
<DetailDrawerBody>
<DataList orientation="vertical">
<DataListItem>
<DataListLabel>Owner</DataListLabel>
<DataListValue>{active?.owner}</DataListValue>
</DataListItem>
<DataListItem>
<DataListLabel>Status</DataListLabel>
<DataListValue>{active?.status}</DataListValue>
</DataListItem>
</DataList>
</DetailDrawerBody>
<DetailDrawerFooter>
<DetailDrawerClose render={<Button variant="ghost" />}>
Close
</DetailDrawerClose>
<AlertDialog open={confirm} onOpenChange={setConfirm}>
<AlertDialogTrigger
render={
<Button
variant="destructive"
disabled={active?.status !== "Active"}
/>
}
>
Archive project
</AlertDialogTrigger>
<AlertDialogPopup>
<AlertDialogHeader>
<AlertDialogTitle>Archive {active?.name}?</AlertDialogTitle>
<AlertDialogDescription>
Archived projects no longer appear under Active. You can
still find them under Archived.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogClose render={<Button variant="ghost" />}>
Cancel
</AlertDialogClose>
<Button
variant="destructive"
onClick={() => {
setProjects((current) =>
current.map((project) =>
project.id === activeId
? { ...project, status: "Archived" }
: project,
),
);
setConfirm(false);
setOpen(false);
}}
>
Archive
</Button>
</AlertDialogFooter>
</AlertDialogPopup>
</AlertDialog>
</DetailDrawerFooter>
</DetailDrawerPopup>
</DetailDrawer>
</div>
);
}