mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-24 12:31:14 -05:00
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:
@@ -31,6 +31,9 @@ import { OperatorForm } from './OperatorForm';
|
||||
import { PropertyOwnerForm } from './PropertyOwnerForm';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { SubmissionHelpDialog } from '@/components/help/SubmissionHelpDialog';
|
||||
import { TerminologyDialog } from '@/components/help/TerminologyDialog';
|
||||
import { TooltipProvider } from '@/components/ui/tooltip';
|
||||
import { fieldHints } from '@/lib/enhancedValidation';
|
||||
|
||||
const parkSchema = z.object({
|
||||
name: z.string().min(1, 'Park name is required'),
|
||||
@@ -320,10 +323,14 @@ export function ParkForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
<MapPin className="w-5 h-5" />
|
||||
{isEditing ? 'Edit Park' : 'Create New Park'}
|
||||
</CardTitle>
|
||||
<SubmissionHelpDialog type="park" variant="icon" />
|
||||
<div className="flex gap-2">
|
||||
<TerminologyDialog />
|
||||
<SubmissionHelpDialog type="park" variant="icon" />
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<TooltipProvider>
|
||||
<form onSubmit={handleSubmit(handleFormSubmit)} className="space-y-6">
|
||||
{/* Basic Information */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
@@ -724,6 +731,7 @@ export function ParkForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
</TooltipProvider>
|
||||
|
||||
{/* Operator Modal */}
|
||||
<Dialog open={isOperatorModalOpen} onOpenChange={setIsOperatorModalOpen}>
|
||||
|
||||
@@ -36,6 +36,9 @@ import { TechnicalSpecsEditor, validateTechnicalSpecs } from './editors/Technica
|
||||
import { CoasterStatsEditor, validateCoasterStats } from './editors/CoasterStatsEditor';
|
||||
import { FormerNamesEditor } from './editors/FormerNamesEditor';
|
||||
import { SubmissionHelpDialog } from '@/components/help/SubmissionHelpDialog';
|
||||
import { TerminologyDialog } from '@/components/help/TerminologyDialog';
|
||||
import { TermTooltip } from '@/components/ui/term-tooltip';
|
||||
import { fieldHints } from '@/lib/enhancedValidation';
|
||||
import {
|
||||
convertValueToMetric,
|
||||
convertValueFromMetric,
|
||||
@@ -391,7 +394,10 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
<Zap className="w-5 h-5" />
|
||||
{isEditing ? 'Edit Ride' : 'Create New Ride'}
|
||||
</CardTitle>
|
||||
<SubmissionHelpDialog type="ride" variant="icon" />
|
||||
<div className="flex gap-2">
|
||||
<TerminologyDialog />
|
||||
<SubmissionHelpDialog type="ride" variant="icon" />
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
@@ -851,17 +857,15 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<Label>Track Material(s)</Label>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<HelpCircle className="h-4 w-4 text-muted-foreground cursor-help" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="max-w-xs">
|
||||
<p>Material used for the track. Select multiple if hybrid (e.g., wood track with steel supports).</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<Label>
|
||||
<TermTooltip term="ibox-track" showIcon={false}>
|
||||
Track Material(s)
|
||||
</TermTooltip>
|
||||
</Label>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground">Select all materials used in the track</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Common: <TermTooltip term="ibox-track" inline>Steel</TermTooltip>, Wood, <TermTooltip term="hybrid-coaster" inline>Hybrid (RMC IBox)</TermTooltip>
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{TRACK_MATERIALS.map((material) => (
|
||||
<div key={material.value} className="flex items-center space-x-2">
|
||||
@@ -888,16 +892,10 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<Label>Support Material(s)</Label>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<HelpCircle className="h-4 w-4 text-muted-foreground cursor-help" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="max-w-xs">
|
||||
<p>Material used for the support structure. Can be different from track material (e.g., wood track on steel supports).</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground">Select all materials used in the supports</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Materials used for support structure (can differ from track)
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{SUPPORT_MATERIALS.map((material) => (
|
||||
<div key={material.value} className="flex items-center space-x-2">
|
||||
@@ -923,23 +921,15 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<Label>Propulsion Method(s)</Label>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<HelpCircle className="h-4 w-4 text-muted-foreground cursor-help" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="max-w-xs">
|
||||
<p className="font-semibold mb-1">Common methods:</p>
|
||||
<ul className="text-xs space-y-1">
|
||||
<li>• <strong>LSM Launch:</strong> Linear Synchronous Motor (smooth, modern)</li>
|
||||
<li>• <strong>Chain Lift:</strong> Traditional lift hill</li>
|
||||
<li>• <strong>Hydraulic Launch:</strong> Fast, powerful (e.g., Kingda Ka)</li>
|
||||
<li>• <strong>Gravity:</strong> Free-fall or terrain-based</li>
|
||||
</ul>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<Label>
|
||||
<TermTooltip term="lsm" showIcon={false}>
|
||||
Propulsion Method(s)
|
||||
</TermTooltip>
|
||||
</Label>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground">Select all propulsion methods used</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Common: <TermTooltip term="lsm" inline>LSM Launch</TermTooltip>, <TermTooltip term="chain-lift" inline>Chain Lift</TermTooltip>, <TermTooltip term="hydraulic-launch" inline>Hydraulic Launch</TermTooltip>
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{PROPULSION_METHODS.map((method) => (
|
||||
<div key={method.value} className="flex items-center space-x-2">
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Card } from "@/components/ui/card";
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import { useUnitPreferences } from "@/hooks/useUnitPreferences";
|
||||
import { toast } from "sonner";
|
||||
import { fieldHints } from "@/lib/enhancedValidation";
|
||||
import {
|
||||
convertValueToMetric,
|
||||
convertValueFromMetric,
|
||||
|
||||
Reference in New Issue
Block a user