import { ReactNode } from 'react'; import { LucideIcon } from 'lucide-react'; import { motion } from 'framer-motion'; import { cn } from '../../lib/utils'; /** * 777 Wolfpack UI Primitives * High-performance, high-density components for operational management. */ // Page header with title and optional actions interface PageHeaderProps { title: string; subtitle?: string; actions?: ReactNode; className?: string; } export function PageHeader({ title, subtitle, actions, className }: PageHeaderProps) { return (

{title}

{subtitle && (

{subtitle}

)}
{actions && (
{actions}
)}
); } // Section header for groupings interface SectionHeaderProps { icon?: LucideIcon; title: string; count?: number; accent?: 'default' | 'accent' | 'success' | 'warning' | 'destructive'; } export function SectionHeader({ icon: Icon, title, count, accent = 'default' }: SectionHeaderProps) { const accentClasses = { default: 'text-slate-500 bg-slate-100 dark:bg-slate-800/50', accent: 'text-indigo-500 bg-indigo-500/10', success: 'text-emerald-500 bg-emerald-500/10', warning: 'text-amber-500 bg-amber-500/10', destructive: 'text-rose-500 bg-rose-500/10', }; return (
{Icon && (
)}

{title}

{count !== undefined && ( {count} )}
); } // Empty state component interface EmptyStateProps { icon: LucideIcon; title: string; description?: string; action?: ReactNode; } export function EmptyState({ icon: Icon, title, description, action }: EmptyStateProps) { return (

{title}

{description && (

{description}

)} {action &&
{action}
}
); } // Metric card for dashboards interface MetricCardProps { icon: LucideIcon; label: string; value: string | number; subtitle?: string; accent?: 'default' | 'accent' | 'success' | 'warning' | 'destructive'; trend?: { value: number; positive: boolean }; } export function MetricCard({ icon: Icon, label, value, subtitle, accent = 'default', trend }: MetricCardProps) { const accentColor = { default: 'text-slate-500 dark:text-slate-400', accent: 'text-indigo-500', success: 'text-emerald-500', warning: 'text-amber-500', destructive: 'text-rose-500', }; return (
{trend && (
{trend.positive ? '↑' : '↓'} {trend.value}%
)}

{value}

{label}

{subtitle && (

{subtitle}

)}
); } // List item for tables/lists interface ListItemProps { children: ReactNode; onClick?: () => void; active?: boolean; className?: string; } export function ListItem({ children, onClick, active, className }: ListItemProps) { return (
{children}
); } // Action button (icon button) interface ActionButtonProps { icon: LucideIcon; label: string; onClick: (e: React.MouseEvent) => void; variant?: 'default' | 'accent' | 'success' | 'warning' | 'destructive'; } export function ActionButton({ icon: Icon, label, onClick, variant = 'default' }: ActionButtonProps) { const variants = { default: 'text-slate-500 hover:bg-slate-100 dark:text-slate-400 dark:hover:bg-slate-800', accent: 'text-indigo-500 hover:bg-indigo-500/10', success: 'text-emerald-500 hover:bg-emerald-500/10', warning: 'text-amber-500 hover:bg-amber-500/10', destructive: 'text-rose-500 hover:bg-rose-500/10', }; return ( ); } // Status badge interface StatusBadgeProps { status: 'active' | 'pending' | 'completed' | 'error' | 'default'; label?: string; className?: string; } export function StatusBadge({ status, label, className }: StatusBadgeProps) { const variants = { active: 'text-emerald-600 bg-emerald-500/10 border-emerald-500/20', pending: 'text-amber-600 bg-amber-500/10 border-amber-500/20', completed: 'text-indigo-600 bg-indigo-500/10 border-indigo-500/20', error: 'text-rose-600 bg-rose-500/10 border-rose-500/20', default: 'text-slate-500 bg-slate-100 border-slate-200 dark:bg-slate-800 dark:border-slate-700', }; return ( {label || status.charAt(0).toUpperCase() + status.slice(1)} ); } // Skeleton loader export function Skeleton({ className }: { className?: string }) { return
; } // Card skeleton export function CardSkeleton() { return (
); } // Divider export function Divider({ className }: { className?: string }) { return
; }