"use client"; import { ArrowLeft, Lightbulb, type LucideIcon } from "lucide-react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { type ReactNode } from "react"; import { type FieldValues, type UseFormReturn } from "react-hook-form"; import { Button } from "~/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "~/components/ui/card"; import { PageHeader } from "~/components/ui/page-header"; import { Separator } from "~/components/ui/separator"; import { cn } from "~/lib/utils"; interface EntityFormProps { // Mode mode: "create" | "edit"; // Entity info entityName: string; // "Study", "Experiment", etc. entityNamePlural: string; // "Studies", "Experiments", etc. // Navigation backUrl: string; listUrl: string; // Header title: string; description: string; icon?: LucideIcon; // Form form: UseFormReturn; onSubmit: (data: T) => Promise | void; children: ReactNode; // Form fields // State isSubmitting?: boolean; error?: string | null; // Actions onDelete?: () => Promise | void; isDeleting?: boolean; // Sidebar content sidebar?: ReactNode; // Custom submit button text submitText?: string; submitButtonId?: string; // Additional header actions extraActions?: ReactNode; // Layout layout?: "default" | "full-width"; className?: string; } export function EntityForm({ mode, entityName, entityNamePlural, backUrl, listUrl: _listUrl, title, description, icon: Icon, form, onSubmit, children, isSubmitting = false, error, onDelete, isDeleting = false, sidebar, submitText, submitButtonId, extraActions, layout = "default", className, }: EntityFormProps) { const router = useRouter(); const handleSubmit = form.handleSubmit(async (data) => { await onSubmit(data); }); const defaultSubmitText = mode === "create" ? `Create ${entityName}` : `Save Changes`; return (
{/* Header */} {extraActions} {mode === "edit" && onDelete && ( )}
} /> {/* Form Layout */}
{/* Main Form */}
{mode === "create" ? `New ${entityName}` : `Edit ${entityName}`} {mode === "create" ? `Fill in the details to create a new ${entityName.toLowerCase()}.` : `Update the details for this ${entityName.toLowerCase()}.`}
{/* Form Fields */} {children} {/* Error Message */} {error && (

{error}

)} {/* Form Actions */}
{/* Sidebar */} {sidebar && layout === "default" && (
{sidebar}
)}
); } // Form field components for consistency interface FormFieldProps { children: ReactNode; className?: string; } export function FormField({ children, className }: FormFieldProps) { return
{children}
; } interface FormSectionProps { title: string; description?: string; children: ReactNode; className?: string; } export function FormSection({ title, description, children, className, }: FormSectionProps) { return (

{title}

{description && (

{description}

)}
{children}
); } // Sidebar components interface SidebarCardProps { title: string; icon?: LucideIcon; children: ReactNode; className?: string; } export function SidebarCard({ title, icon: Icon, children, className, }: SidebarCardProps) { return ( {Icon && } {title} {children} ); } interface NextStepsProps { steps: Array<{ title: string; description: string; completed?: boolean; }>; } export function NextSteps({ steps }: NextStepsProps) { return (
{steps.map((step, index) => (

{step.title}

{step.description}

))}
); } interface TipsProps { tips: string[]; } export function Tips({ tips }: TipsProps) { return (
{tips.map((tip, index) => (

{tip}

))}
); }