Revert "Merge pull request 'Complete Housekeeping migration and /ase cutover' (#52) from codex/housekeeping-complete into main"
This reverts commit488b6e57c4, reversing changes made tob506b4499a.
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
"use client";
|
||||
|
||||
import { Pencil } from "lucide-react";
|
||||
import { deleteCatalogPage, toggleCatalogPage } from "@/actions/catalog";
|
||||
import { deleteBcTreePage, toggleBcPage } from "@/actions/catalog-bc";
|
||||
import { DataTable } from "@/components/admin/data-table";
|
||||
import Link from "@/components/link";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useServerAction } from "@/hooks/use-server-action";
|
||||
import type { DataTableColumn, PaginatedResult } from "@/types/common";
|
||||
|
||||
interface CatalogPageRow {
|
||||
id: number;
|
||||
caption: string;
|
||||
parentId: number;
|
||||
parentCaption: string;
|
||||
pageLayout: string;
|
||||
enabled: string;
|
||||
visible: string;
|
||||
minRank: number;
|
||||
orderNum: number;
|
||||
itemCount: number;
|
||||
childCount: number;
|
||||
}
|
||||
|
||||
interface CatalogTableProps {
|
||||
data: PaginatedResult<CatalogPageRow>;
|
||||
canEdit: boolean;
|
||||
catalogType?: "normal" | "bc";
|
||||
}
|
||||
|
||||
export function CatalogTable({
|
||||
data,
|
||||
canEdit,
|
||||
catalogType = "normal",
|
||||
}: CatalogTableProps) {
|
||||
const { run, isPending } = useServerAction();
|
||||
const isBc = catalogType === "bc";
|
||||
|
||||
// Parent URLs stay in the same catalog; root takes you to the catalog index.
|
||||
const detailHref = (id: number) =>
|
||||
isBc ? `/admin/catalog/builder-club/${id}` : `/admin/catalog/${id}`;
|
||||
|
||||
function handleToggle(id: number, action: "toggleEnabled" | "toggleVisible") {
|
||||
if (isBc) {
|
||||
const field = action === "toggleEnabled" ? "enabled" : "visible";
|
||||
run(() => toggleBcPage({ id, field }), { successMessage: "Updated." });
|
||||
} else {
|
||||
run(() => toggleCatalogPage({ id, action }), {
|
||||
successMessage: "Updated.",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const columns: DataTableColumn<CatalogPageRow>[] = [
|
||||
{ key: "id", label: "ID", sortable: true },
|
||||
{
|
||||
key: "caption",
|
||||
label: "Caption",
|
||||
sortable: true,
|
||||
render: (value, row) => (
|
||||
<Link
|
||||
href={detailHref(row.id)}
|
||||
className="font-medium text-primary hover:underline"
|
||||
>
|
||||
{String(value)}
|
||||
</Link>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "parentId",
|
||||
label: "Parent",
|
||||
sortable: true,
|
||||
render: (_, row) =>
|
||||
row.parentId === -1 ? (
|
||||
<span className="text-xs text-muted-foreground">Root</span>
|
||||
) : (
|
||||
<Link
|
||||
href={detailHref(row.parentId)}
|
||||
className="text-xs hover:underline"
|
||||
>
|
||||
{row.parentCaption}
|
||||
</Link>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "pageLayout",
|
||||
label: "Layout",
|
||||
render: (value) => <Badge variant="secondary">{String(value)}</Badge>,
|
||||
},
|
||||
{
|
||||
key: "enabled",
|
||||
label: "Enabled",
|
||||
sortable: true,
|
||||
filterKey: "filter_enabled",
|
||||
filterOptions: [
|
||||
{ label: "Enabled", value: "1" },
|
||||
{ label: "Disabled", value: "0" },
|
||||
],
|
||||
render: (value, row) =>
|
||||
canEdit ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleToggle(row.id, "toggleEnabled")}
|
||||
disabled={isPending}
|
||||
className="cursor-pointer disabled:opacity-50"
|
||||
>
|
||||
<Badge variant={value === "1" ? "default" : "outline"}>
|
||||
{value === "1" ? "Yes" : "No"}
|
||||
</Badge>
|
||||
</button>
|
||||
) : (
|
||||
<Badge variant={value === "1" ? "default" : "outline"}>
|
||||
{value === "1" ? "Yes" : "No"}
|
||||
</Badge>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "visible",
|
||||
label: "Visible",
|
||||
sortable: true,
|
||||
filterKey: "filter_visible",
|
||||
filterOptions: [
|
||||
{ label: "Visible", value: "1" },
|
||||
{ label: "Hidden", value: "0" },
|
||||
],
|
||||
render: (value, row) =>
|
||||
canEdit ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleToggle(row.id, "toggleVisible")}
|
||||
disabled={isPending}
|
||||
className="cursor-pointer disabled:opacity-50"
|
||||
>
|
||||
<Badge variant={value === "1" ? "default" : "outline"}>
|
||||
{value === "1" ? "Yes" : "No"}
|
||||
</Badge>
|
||||
</button>
|
||||
) : (
|
||||
<Badge variant={value === "1" ? "default" : "outline"}>
|
||||
{value === "1" ? "Yes" : "No"}
|
||||
</Badge>
|
||||
),
|
||||
},
|
||||
...(isBc
|
||||
? []
|
||||
: [
|
||||
{
|
||||
key: "minRank" as const,
|
||||
label: "Min Rank",
|
||||
sortable: true,
|
||||
} satisfies DataTableColumn<CatalogPageRow>,
|
||||
]),
|
||||
{
|
||||
key: "itemCount",
|
||||
label: "Items",
|
||||
render: (value) => <span>{String(value)}</span>,
|
||||
},
|
||||
{
|
||||
key: "childCount",
|
||||
label: "Children",
|
||||
render: (value) => <span>{String(value)}</span>,
|
||||
},
|
||||
{
|
||||
key: "actions",
|
||||
label: "Actions",
|
||||
render: (_, row) => (
|
||||
<Button variant="ghost" size="icon" asChild>
|
||||
<Link href={detailHref(row.id)}>
|
||||
<Pencil className="h-4 w-4" />
|
||||
</Link>
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
async function handleBulkAction(action: string, ids: (number | string)[]) {
|
||||
if (action !== "delete" || ids.length === 0) return;
|
||||
for (const id of ids) {
|
||||
const numId = typeof id === "string" ? Number(id) : id;
|
||||
if (Number.isInteger(numId) && numId > 0) {
|
||||
run(() =>
|
||||
isBc
|
||||
? deleteBcTreePage({ pageId: numId, mode: "reparent" })
|
||||
: deleteCatalogPage({ id: numId }),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<DataTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
searchPlaceholder="Search by caption, layout or item..."
|
||||
bulkActions={
|
||||
canEdit
|
||||
? [
|
||||
{
|
||||
label: "Delete Selected",
|
||||
value: "delete",
|
||||
variant: "destructive",
|
||||
},
|
||||
]
|
||||
: undefined
|
||||
}
|
||||
onBulkAction={canEdit ? handleBulkAction : undefined}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user