"use client"; import React from "react"; type AdminInputProps = { label?: string; error?: string; helpText?: string; required?: boolean; className?: string; children: React.ReactNode; }; export function AdminInput({ label, error, helpText, required, className = "", children, id, }: AdminInputProps & { id?: string }) { // Generate a stable id for label association when label is provided const generatedId = id || (label ? `admin-input-${label.toLowerCase().replace(/[^a-z0-9]/g, "-")}` : undefined); // Clone child to inject id + aria props if it's a valid element (input/textarea/select) const enhancedChildren = React.isValidElement(children) ? React.cloneElement(children as React.ReactElement>, { id: (children as React.ReactElement<{ id?: string }>).props?.id || generatedId, "aria-required": required ? "true" : undefined, required: required ? true : undefined, "aria-describedby": error ? `${generatedId}-error` : helpText ? `${generatedId}-help` : undefined, }) : children; return (
{label && ( )} {enhancedChildren} {helpText && !error && (

{helpText}

)} {error && ( )}
); } // Styled text input wrapper type AdminTextInputProps = Omit, 'onChange' | 'value' | 'type'> & { value: string | number; onChange: (e: React.ChangeEvent) => void; type?: string; }; export function AdminTextInput({ value, onChange, type = "text", disabled, className = "", maxLength, autoComplete, step, min, max, ...rest }: AdminTextInputProps) { return ( ); } // Styled textarea wrapper type AdminTextareaProps = Omit, 'onChange' | 'value'> & { value: string | number; onChange: (e: React.ChangeEvent) => void; }; export function AdminTextarea({ value, onChange, disabled, className = "", ...rest }: AdminTextareaProps) { return (