69 lines
1.7 KiB
TypeScript
69 lines
1.7 KiB
TypeScript
import { ReactNode } from "react";
|
|
import { Button } from "@/components/ui/button";
|
|
import { TreeSearchControls } from "@/components/admin";
|
|
import { TreeViewContainer } from "@/components/admin";
|
|
|
|
interface TreeViewPageProps {
|
|
title: string;
|
|
description: string;
|
|
searchTerm: string;
|
|
onSearchChange: (term: string) => void;
|
|
onExpandAll: () => void;
|
|
onCollapseAll: () => void;
|
|
searchPlaceholder: string;
|
|
hasContent: boolean;
|
|
isLoading?: boolean;
|
|
loadingMessage?: string;
|
|
emptyState: ReactNode;
|
|
headerActions?: ReactNode;
|
|
children: ReactNode;
|
|
}
|
|
|
|
export function TreeViewPage({
|
|
title,
|
|
description,
|
|
searchTerm,
|
|
onSearchChange,
|
|
onExpandAll,
|
|
onCollapseAll,
|
|
searchPlaceholder,
|
|
hasContent,
|
|
isLoading = false,
|
|
loadingMessage = "Chargement...",
|
|
emptyState,
|
|
headerActions,
|
|
children,
|
|
}: TreeViewPageProps) {
|
|
return (
|
|
<div className="space-y-4">
|
|
{/* Header */}
|
|
<div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3">
|
|
<div>
|
|
<h2 className="text-2xl font-bold text-white">{title}</h2>
|
|
<p className="text-slate-400">{description}</p>
|
|
</div>
|
|
{headerActions}
|
|
</div>
|
|
|
|
{/* Filtres et contrôles */}
|
|
<TreeSearchControls
|
|
searchTerm={searchTerm}
|
|
onSearchChange={onSearchChange}
|
|
onExpandAll={onExpandAll}
|
|
onCollapseAll={onCollapseAll}
|
|
placeholder={searchPlaceholder}
|
|
/>
|
|
|
|
{/* Vue arborescente */}
|
|
<TreeViewContainer
|
|
isLoading={isLoading}
|
|
loadingMessage={loadingMessage}
|
|
hasContent={hasContent}
|
|
emptyState={emptyState}
|
|
>
|
|
{children}
|
|
</TreeViewContainer>
|
|
</div>
|
|
);
|
|
}
|