mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 08:31:12 -05:00
Expand help text for complex fields
Add user-facing guidance texts and tooltips to additional complex form fields beyond date precision, including ParkForm and RideForm enhancements: - Introduce contextual help sections with Info icons for Park Type, Status, Location, Operator/Owner, Source URL, and Submission Notes - Add guidance for RideForm fields such as Category, Status, Manufacturer/Model context, and Technical specifications - Ensure consistent muted help text styling and accessibility across forms - Extend lines with inline Help/Info components to improve user understanding and reduce input errors
This commit is contained in:
@@ -17,7 +17,7 @@ import { FlexibleDateInput, type DatePrecision } from '@/components/ui/flexible-
|
||||
import { SlugField } from '@/components/ui/slug-field';
|
||||
import { toast } from '@/hooks/use-toast';
|
||||
import { handleError } from '@/lib/errorHandler';
|
||||
import { MapPin, Save, X, Plus, AlertCircle } from 'lucide-react';
|
||||
import { MapPin, Save, X, Plus, AlertCircle, Info } from 'lucide-react';
|
||||
import { toDateOnly, parseDateOnly, toDateWithPrecision } from '@/lib/dateUtils';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Combobox } from '@/components/ui/combobox';
|
||||
@@ -370,6 +370,10 @@ export function ParkForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<div className="flex items-start gap-2 text-xs text-muted-foreground">
|
||||
<Info className="h-3.5 w-3.5 mt-0.5 flex-shrink-0" />
|
||||
<p>Choose the primary classification. Theme parks have themed areas, while amusement parks focus on rides.</p>
|
||||
</div>
|
||||
{errors.park_type && (
|
||||
<p className="text-sm text-destructive">{errors.park_type.message}</p>
|
||||
)}
|
||||
@@ -395,6 +399,10 @@ export function ParkForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
})}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<div className="flex items-start gap-2 text-xs text-muted-foreground">
|
||||
<Info className="h-3.5 w-3.5 mt-0.5 flex-shrink-0" />
|
||||
<p>Current operational status. Use "Closed Temporarily" for seasonal closures or renovations.</p>
|
||||
</div>
|
||||
{errors.status && (
|
||||
<p className="text-sm text-destructive">{errors.status.message}</p>
|
||||
)}
|
||||
@@ -446,6 +454,10 @@ export function ParkForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
}}
|
||||
initialLocationId={watch('location_id')}
|
||||
/>
|
||||
<div className="flex items-start gap-2 text-xs text-muted-foreground">
|
||||
<Info className="h-3.5 w-3.5 mt-0.5 flex-shrink-0" />
|
||||
<p>Search by park name, address, or city. Select from results to auto-fill coordinates and timezone.</p>
|
||||
</div>
|
||||
{errors.location && (
|
||||
<p className="text-sm text-destructive flex items-center gap-1">
|
||||
<AlertCircle className="w-4 h-4" />
|
||||
@@ -462,6 +474,10 @@ export function ParkForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
{/* Operator & Property Owner Selection */}
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-semibold">Operator & Property Owner</h3>
|
||||
<div className="flex items-start gap-2 text-xs text-muted-foreground mb-3">
|
||||
<Info className="h-3.5 w-3.5 mt-0.5 flex-shrink-0" />
|
||||
<p>The operator runs the park, while the property owner owns the land. Often the same entity.</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-2 mb-4">
|
||||
<Checkbox
|
||||
|
||||
@@ -23,7 +23,7 @@ import { SlugField } from '@/components/ui/slug-field';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { toast } from '@/hooks/use-toast';
|
||||
import { handleError } from '@/lib/errorHandler';
|
||||
import { Plus, Zap, Save, X, Building2, AlertCircle } from 'lucide-react';
|
||||
import { Plus, Zap, Save, X, Building2, AlertCircle, Info } from 'lucide-react';
|
||||
import { toDateOnly, parseDateOnly, toDateWithPrecision } from '@/lib/dateUtils';
|
||||
import { useUnitPreferences } from '@/hooks/useUnitPreferences';
|
||||
import { useManufacturers, useRideModels, useParks } from '@/hooks/useAutocompleteData';
|
||||
@@ -529,6 +529,10 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<div className="flex items-start gap-2 text-xs text-muted-foreground">
|
||||
<Info className="h-3.5 w-3.5 mt-0.5 flex-shrink-0" />
|
||||
<p>Primary ride type. Choose roller coaster for any coaster, flat ride for spinners/swings, water ride for flumes/rapids.</p>
|
||||
</div>
|
||||
{errors.category && (
|
||||
<p className="text-sm text-destructive">{errors.category.message}</p>
|
||||
)}
|
||||
@@ -541,6 +545,10 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
{...register('ride_sub_type')}
|
||||
placeholder="e.g. Inverted Coaster, Log Flume"
|
||||
/>
|
||||
<div className="flex items-start gap-2 text-xs text-muted-foreground">
|
||||
<Info className="h-3.5 w-3.5 mt-0.5 flex-shrink-0" />
|
||||
<p>Specific type within category (e.g., "Inverted Coaster", "Flume").</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
@@ -563,6 +571,10 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
})}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<div className="flex items-start gap-2 text-xs text-muted-foreground">
|
||||
<Info className="h-3.5 w-3.5 mt-0.5 flex-shrink-0" />
|
||||
<p>Current state. Use "Relocated" if moved to another park.</p>
|
||||
</div>
|
||||
{errors.status && (
|
||||
<p className="text-sm text-destructive">{errors.status.message}</p>
|
||||
)}
|
||||
@@ -572,6 +584,10 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
{/* Manufacturer & Model Selection */}
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-semibold">Manufacturer & Model</h3>
|
||||
<div className="flex items-start gap-2 text-xs text-muted-foreground mb-3">
|
||||
<Info className="h-3.5 w-3.5 mt-0.5 flex-shrink-0" />
|
||||
<p>The company that built the ride. Model is the specific product line (e.g., "B&M" makes "Inverted Coaster" models).</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{/* Manufacturer Column */}
|
||||
@@ -747,6 +763,10 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
{...register('height_requirement', { setValueAs: (v) => v === "" ? undefined : parseFloat(v) })}
|
||||
placeholder={measurementSystem === 'imperial' ? 'e.g. 47' : 'e.g. 120'}
|
||||
/>
|
||||
<div className="flex items-start gap-2 text-xs text-muted-foreground">
|
||||
<Info className="h-3.5 w-3.5 mt-0.5 flex-shrink-0" />
|
||||
<p>Minimum height to ride. Values automatically convert to {measurementSystem === 'imperial' ? 'inches' : 'cm'}.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
@@ -758,6 +778,10 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
{...register('age_requirement', { setValueAs: (v) => v === "" ? undefined : parseFloat(v) })}
|
||||
placeholder="e.g. 8"
|
||||
/>
|
||||
<div className="flex items-start gap-2 text-xs text-muted-foreground">
|
||||
<Info className="h-3.5 w-3.5 mt-0.5 flex-shrink-0" />
|
||||
<p>Minimum age in years, if different from height requirement.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -765,6 +789,10 @@ export function RideForm({ onSubmit, onCancel, initialData, isEditing = false }:
|
||||
{selectedCategory === 'roller_coaster' && (
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-semibold">Roller Coaster Details</h3>
|
||||
<div className="flex items-start gap-2 text-xs text-muted-foreground mb-3">
|
||||
<Info className="h-3.5 w-3.5 mt-0.5 flex-shrink-0" />
|
||||
<p>Specific attributes for roller coasters. Track/support materials help classify hybrid coasters.</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div className="space-y-2">
|
||||
|
||||
Reference in New Issue
Block a user