"use client";
import * as LucideIcons from "lucide-react";
import { cn } from "~/lib/utils";
import { type ReactNode } from "react";
import { Badge } from "~/components/ui/badge";
import { Button } from "~/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "~/components/ui/card";
type IconName = keyof typeof LucideIcons;
function getIcon(iconName: IconName) {
const Icon = LucideIcons[iconName] as React.ComponentType<{
className?: string;
}>;
return Icon;
}
interface EntityViewHeaderProps {
title: string;
subtitle?: string;
icon: IconName;
status?: {
label: string;
variant: "default" | "secondary" | "destructive" | "outline";
icon?: IconName;
};
actions?: ReactNode;
}
interface EntityViewSectionProps {
title: string;
icon: IconName;
description?: string;
actions?: ReactNode;
children: ReactNode;
}
interface EntityViewSidebarProps {
children: ReactNode;
}
interface EntityViewProps {
children: ReactNode;
layout?: "default" | "full-width";
}
// ... existing code ...
export function EntityViewHeader({
title,
subtitle,
icon,
status,
actions,
}: EntityViewHeaderProps) {
const Icon = getIcon(icon);
const StatusIcon = status?.icon ? getIcon(status.icon) : null;
return (
{title}
{status && (
{StatusIcon && }
{status.label}
)}
{subtitle && (
{subtitle}
)}
{actions &&
{actions}
}
);
}
export function EntityViewSection({
title,
icon,
description,
actions,
children,
}: EntityViewSectionProps) {
const Icon = getIcon(icon);
return (
{title}
{actions && actions}
{description && {description} }
{children}
);
}
export function EntityViewSidebar({ children }: EntityViewSidebarProps) {
return {children}
;
}
export function EntityView({ children, layout = "default" }: EntityViewProps) {
// Simplification: Always take full width of the parent container provided by DashboardLayout
// The DashboardLayout already provides padding (p-4).
// We remove 'container mx-auto max-w-5xl' to stop it from shrinking.
return {children}
;
}
// Utility component for empty states
interface EmptyStateProps {
icon: IconName;
title: string;
description: string;
action?: ReactNode;
}
export function EmptyState({
icon,
title,
description,
action,
}: EmptyStateProps) {
const Icon = getIcon(icon);
return (
{title}
{description}
{action && action}
);
}
// Utility component for key-value information display
interface InfoGridProps {
items: Array<{
label: string;
value: ReactNode;
fullWidth?: boolean;
}>;
columns?: 1 | 2 | 3;
}
export function InfoGrid({ items, columns = 2 }: InfoGridProps) {
return (
{items.map((item, index) => (
{item.label}
{item.value}
))}
);
}
// Utility component for statistics display
interface StatsGridProps {
stats: Array<{
label: string;
value: string | number;
color?: "default" | "success" | "warning" | "error";
}>;
}
export function StatsGrid({ stats }: StatsGridProps) {
const getValueColor = (color?: string) => {
switch (color) {
case "success":
return "text-green-600";
case "warning":
return "text-amber-600";
case "error":
return "text-red-600";
default:
return "font-medium";
}
};
return (
{stats.map((stat, index) => (
{stat.label}:
{stat.value}
))}
);
}
// Utility component for quick actions
interface QuickActionsProps {
actions: Array<{
label: string;
icon: IconName;
href?: string;
onClick?: () => void;
variant?: "default" | "outline" | "secondary" | "destructive";
}>;
}
export function QuickActions({ actions }: QuickActionsProps) {
return (
{actions.map((action, index) => {
const ActionIcon = getIcon(action.icon);
return (
{action.href ? (
{action.label}
) : (
<>
{action.label}
>
)}
);
})}
);
}