JavaScript 56.7%
TypeScript 42.6%
1"use client";23import type { LucideIcon } from "lucide-react";45interface PageHeaderProps {6 title: string;7 subtitle?: string;8 icon?: LucideIcon;9 /** Classe de teinte de l'icône, ex. "text-amber-500 bg-amber-500/10" */10 tone?: string;11 actions?: React.ReactNode;12 className?: string;13 /** Style compact (barre d'explorateur) */14 compact?: boolean;15}1617/** En-tête de page standard SPB Cloud v3. */18export default function PageHeader({ title, subtitle, icon: Icon, tone = "text-blue-600 bg-blue-500/10 dark:text-blue-300", actions, className = "", compact }: PageHeaderProps) {19 return (20 <div className={`flex items-start sm:items-center justify-between gap-3 ${compact ? "py-3" : "py-4 sm:py-5"} ${className}`}>21 <div className="flex items-center gap-3 min-w-0">22 {Icon && (23 <div className={`w-10 h-10 rounded-2xl flex items-center justify-center shrink-0 ${tone}`}>24 <Icon className="w-5 h-5" />25 </div>26 )}27 <div className="min-w-0">28 <h1 className={`${compact ? "text-lg" : "text-xl sm:text-2xl"} font-semibold tracking-tight text-gray-900 dark:text-white truncate`}>{title}</h1>29 {subtitle && <p className="text-[13px] text-gray-500 dark:text-gray-400 mt-0.5 truncate">{subtitle}</p>}30 </div>31 </div>32 {actions && <div className="flex items-center gap-2 shrink-0">{actions}</div>}33 </div>34 );35}3637export function EmptyState({ icon: Icon, title, description, action }: { icon: LucideIcon; title: string; description?: string; action?: React.ReactNode }) {38 return (39 <div className="flex flex-col items-center justify-center text-center py-16 px-6">40 <div className="relative mb-5">41 <div className="absolute inset-0 rounded-full bg-blue-500/10 blur-2xl scale-150" />42 <div className="relative w-16 h-16 rounded-3xl bg-gray-100 dark:bg-white/5 border border-line dark:border-white/10 flex items-center justify-center">43 <Icon className="w-7 h-7 text-gray-400 dark:text-gray-500" />44 </div>45 </div>46 <p className="text-base font-medium text-gray-800 dark:text-gray-200">{title}</p>47 {description && <p className="text-sm text-gray-500 dark:text-gray-400 mt-1 max-w-sm">{description}</p>}48 {action && <div className="mt-5">{action}</div>}49 </div>50 );51}52