feat(catalog): SSR stats in Visual Manager, honest deletes, newPageParent
Pass DB totals into StatsBar, mirror Catalog Structure delete copy, and open New Page with ?newPageParent= for shop and BC. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
b7fd19b6d9
commit
8d1cf86105
7 files changed
+118
-38
No files matched your search
@@ -1,45 +1,50 @@
|
||||
"use client";
|
||||
|
||||
import { FolderTree, Keyboard, Package, ToggleRight } from "lucide-react";
|
||||
import { useMemo } from "react";
|
||||
import { useCatalogManager } from "./use-catalog-store";
|
||||
|
||||
export function StatsBar() {
|
||||
const { state } = useCatalogManager();
|
||||
export interface CatalogStatsTotals {
|
||||
totalPages: number;
|
||||
enabledPages: number;
|
||||
totalItems: number;
|
||||
}
|
||||
|
||||
const stats = useMemo(() => {
|
||||
const nodes = Array.from(state.nodes.values());
|
||||
const enabled = nodes.filter((n) => n.enabled === "1").length;
|
||||
const totalItems = nodes.reduce((sum, n) => sum + n.itemCount, 0);
|
||||
return {
|
||||
rootTabs: state.rootPages.length,
|
||||
totalPages: nodes.length,
|
||||
enabled,
|
||||
totalItems,
|
||||
};
|
||||
}, [state.nodes, state.rootPages]);
|
||||
export function StatsBar({ totals }: { totals?: CatalogStatsTotals | null }) {
|
||||
const { state } = useCatalogManager();
|
||||
const selected = state.multiSelectedIds.size;
|
||||
const rootTabs = state.rootPages.length;
|
||||
|
||||
const pages = totals?.totalPages ?? state.nodes.size;
|
||||
const enabled = totals?.enabledPages ?? null;
|
||||
const items = totals?.totalItems ?? null;
|
||||
const loadedOnly = !totals;
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-between gap-4 px-4 py-1.5 border-t bg-muted/30 text-[11px] text-muted-foreground shrink-0">
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="flex items-center gap-1">
|
||||
<FolderTree className="h-3 w-3" />
|
||||
{stats.rootTabs} root
|
||||
{rootTabs} root
|
||||
</span>
|
||||
<span>{stats.totalPages} pages</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<ToggleRight className="h-3 w-3" />
|
||||
{stats.enabled} enabled
|
||||
<span>
|
||||
{pages} pages
|
||||
{loadedOnly ? " loaded" : ""}
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<Package className="h-3 w-3" />
|
||||
{stats.totalItems} items
|
||||
</span>
|
||||
{state.multiSelectedIds.size > 0 && (
|
||||
<span className="text-primary font-medium">
|
||||
{state.multiSelectedIds.size} selected
|
||||
{enabled !== null && (
|
||||
<span className="flex items-center gap-1">
|
||||
<ToggleRight className="h-3 w-3" />
|
||||
{enabled} enabled
|
||||
</span>
|
||||
)}
|
||||
{items !== null && (
|
||||
<span className="flex items-center gap-1">
|
||||
<Package className="h-3 w-3" />
|
||||
{items} items
|
||||
</span>
|
||||
)}
|
||||
{selected > 0 && (
|
||||
<span className="text-primary font-medium">{selected} selected</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<Keyboard className="h-3 w-3" />
|
||||
|
||||
Reference in new issue
Block a user