Enhance forms with validation and terminology

Implements enhanced inline validation with contextual messages and examples, adds a comprehensive theme park terminology tool (tooltip and glossary), and integrates these features into ParkForm and RideForm (including header actions and descriptive hints). Also introduces new helper modules and components to support validated inputs and glossary tooltips.
This commit is contained in:
gpt-engineer-app[bot]
2025-11-11 23:25:15 +00:00
parent 67ce8b5a88
commit 985454f0d9
8 changed files with 875 additions and 37 deletions

View File

@@ -0,0 +1,87 @@
import * as React from "react";
import { Check, AlertCircle } from "lucide-react";
import { cn } from "@/lib/utils";
import { Input } from "@/components/ui/input";
import { useDebouncedCallback } from "use-debounce";
export interface ValidatedInputProps extends React.ComponentProps<typeof Input> {
validation?: {
isValid?: boolean;
error?: string;
hint?: string;
};
showValidation?: boolean;
onValidate?: (value: string) => { isValid: boolean; error?: string };
}
const ValidatedInput = React.forwardRef<HTMLInputElement, ValidatedInputProps>(
({ className, validation, showValidation = true, onValidate, onChange, ...props }, ref) => {
const [localValidation, setLocalValidation] = React.useState<{
isValid?: boolean;
error?: string;
}>({});
const debouncedValidate = useDebouncedCallback((value: string) => {
if (onValidate) {
const result = onValidate(value);
setLocalValidation(result);
}
}, 300);
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
onChange?.(e);
if (onValidate && showValidation) {
debouncedValidate(e.target.value);
}
};
const validationState = validation || localValidation;
const showSuccess = showValidation && validationState.isValid && props.value;
const showError = showValidation && validationState.error;
return (
<div className="space-y-1">
<div className="relative">
<Input
ref={ref}
className={cn(
showError && "border-destructive focus-visible:ring-destructive",
showSuccess && "border-green-500 focus-visible:ring-green-500",
"pr-8",
className
)}
onChange={handleChange}
{...props}
/>
{showValidation && props.value && (
<div className="absolute right-3 top-1/2 transform -translate-y-1/2">
{validationState.isValid && (
<Check className="w-4 h-4 text-green-500" />
)}
{validationState.error && (
<AlertCircle className="w-4 h-4 text-destructive" />
)}
</div>
)}
</div>
{showValidation && validation?.hint && !validationState.error && (
<p className="text-xs text-muted-foreground">
{validation.hint}
</p>
)}
{showError && (
<p className="text-xs text-destructive flex items-center gap-1">
<AlertCircle className="w-3 h-3" />
{validationState.error}
</p>
)}
</div>
);
}
);
ValidatedInput.displayName = "ValidatedInput";
export { ValidatedInput };