Validaciones mandatorias — Sección 8 — IDs concretos
This commit is contained in:
90
components/widgets/geo-select-widget.tsx
Normal file
90
components/widgets/geo-select-widget.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
'use client'
|
||||
import { DEPARTMENTS, getCities } from '@/lib/paraguay-geo'
|
||||
|
||||
interface GeoSelectWidgetProps {
|
||||
departmentValue: string
|
||||
cityValue: string
|
||||
onDepartmentChange: (value: string) => void
|
||||
onCityChange: (value: string) => void
|
||||
departmentError?: string
|
||||
cityError?: string
|
||||
}
|
||||
|
||||
export function GeoSelectWidget({
|
||||
departmentValue,
|
||||
cityValue,
|
||||
onDepartmentChange,
|
||||
onCityChange,
|
||||
departmentError,
|
||||
cityError,
|
||||
}: GeoSelectWidgetProps) {
|
||||
const cities = departmentValue ? getCities(departmentValue) : []
|
||||
const cityDisabled = !departmentValue
|
||||
|
||||
function handleDepartmentChange(val: string) {
|
||||
onDepartmentChange(val)
|
||||
onCityChange('') // limpiar ciudad al cambiar departamento
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="geo-select-wrapper">
|
||||
{/* Departamento */}
|
||||
<div className="geo-select-group">
|
||||
<label className="question-legend" htmlFor="A1">
|
||||
Departamento
|
||||
</label>
|
||||
<select
|
||||
id="A1"
|
||||
name="A1"
|
||||
value={departmentValue}
|
||||
onChange={(e) => handleDepartmentChange(e.target.value)}
|
||||
aria-invalid={!!departmentError}
|
||||
aria-describedby={departmentError ? 'A1-error' : undefined}
|
||||
className="geo-select"
|
||||
>
|
||||
<option value="">Seleccioná un departamento…</option>
|
||||
{DEPARTMENTS.map((dept) => (
|
||||
<option key={dept} value={dept}>{dept}</option>
|
||||
))}
|
||||
</select>
|
||||
{departmentError && (
|
||||
<p role="alert" className="field-error" id="A1-error">{departmentError}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Ciudad */}
|
||||
<div className="geo-select-group">
|
||||
<label
|
||||
className={`question-legend${cityDisabled ? ' geo-label-disabled' : ''}`}
|
||||
htmlFor="A2"
|
||||
>
|
||||
Ciudad
|
||||
{cityDisabled && (
|
||||
<span className="geo-disabled-hint"> (seleccioná un departamento primero)</span>
|
||||
)}
|
||||
</label>
|
||||
<select
|
||||
id="A2"
|
||||
name="A2"
|
||||
value={cityValue}
|
||||
onChange={(e) => onCityChange(e.target.value)}
|
||||
disabled={cityDisabled}
|
||||
aria-disabled={cityDisabled}
|
||||
aria-invalid={!!cityError}
|
||||
aria-describedby={cityError ? 'A2-error' : undefined}
|
||||
className={`geo-select${cityDisabled ? ' geo-select-disabled' : ''}`}
|
||||
>
|
||||
<option value="">
|
||||
{cityDisabled ? 'Primero seleccioná el departamento' : 'Seleccioná una ciudad…'}
|
||||
</option>
|
||||
{cities.map((city) => (
|
||||
<option key={city} value={city}>{city}</option>
|
||||
))}
|
||||
</select>
|
||||
{cityError && (
|
||||
<p role="alert" className="field-error" id="A2-error">{cityError}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user