feat: P7 FormField komponenta + migrace Vehicles
- FormField.jsx: wrapper pro label + input + error pattern (aria-invalid podpora) - Vehicles.jsx: migrovano na FormField (demonstrace patternu) - Postupna migrace dalsich formularovych stranek v budoucnu Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
23
src/admin/components/FormField.jsx
Normal file
23
src/admin/components/FormField.jsx
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Formularovy wrapper pro label + input + error.
|
||||
* Nahrazuje opakovany pattern admin-form-group + has-error + admin-form-error.
|
||||
*
|
||||
* @param {string} label - Text labelu
|
||||
* @param {string} [error] - Chybova zprava (zobrazi se pod inputem)
|
||||
* @param {boolean} [required] - Zobrazi cervenu hvezdicku
|
||||
* @param {string} [className] - Extra CSS trida na wrapperu
|
||||
* @param {React.ReactNode} children - Input/select/textarea element
|
||||
*/
|
||||
export default function FormField({ label, error, required, className, children }) {
|
||||
const groupClass = `admin-form-group${error ? ' has-error' : ''}${className ? ` ${className}` : ''}`
|
||||
|
||||
return (
|
||||
<div className={groupClass}>
|
||||
<label className={`admin-form-label${required ? ' required' : ''}`}>
|
||||
{label}
|
||||
</label>
|
||||
{children}
|
||||
{error && <span className="admin-form-error">{error}</span>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import useModalLock from '../hooks/useModalLock'
|
||||
|
||||
import { formatKm } from '../utils/formatters'
|
||||
import apiFetch from '../utils/api'
|
||||
import FormField from '../components/FormField'
|
||||
const API_BASE = '/api/admin'
|
||||
|
||||
export default function Vehicles() {
|
||||
@@ -338,8 +339,7 @@ export default function Vehicles() {
|
||||
<div className="admin-modal-body">
|
||||
<div className="admin-form">
|
||||
<div className="admin-form-row">
|
||||
<div className={`admin-form-group${errors.spz ? ' has-error' : ''}`}>
|
||||
<label className="admin-form-label required">SPZ</label>
|
||||
<FormField label="SPZ" error={errors.spz} required>
|
||||
<input
|
||||
type="text"
|
||||
value={form.spz}
|
||||
@@ -349,12 +349,11 @@ export default function Vehicles() {
|
||||
}}
|
||||
className="admin-form-input"
|
||||
placeholder="1AB 2345"
|
||||
aria-invalid={!!errors.spz}
|
||||
/>
|
||||
{errors.spz && <span className="admin-form-error">{errors.spz}</span>}
|
||||
</div>
|
||||
</FormField>
|
||||
|
||||
<div className={`admin-form-group${errors.name ? ' has-error' : ''}`}>
|
||||
<label className="admin-form-label required">Název</label>
|
||||
<FormField label="Název" error={errors.name} required>
|
||||
<input
|
||||
type="text"
|
||||
value={form.name}
|
||||
@@ -364,14 +363,13 @@ export default function Vehicles() {
|
||||
}}
|
||||
className="admin-form-input"
|
||||
placeholder="Služební #1"
|
||||
aria-invalid={!!errors.name}
|
||||
/>
|
||||
{errors.name && <span className="admin-form-error">{errors.name}</span>}
|
||||
</div>
|
||||
</FormField>
|
||||
</div>
|
||||
|
||||
<div className="admin-form-row">
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Značka</label>
|
||||
<FormField label="Značka">
|
||||
<input
|
||||
type="text"
|
||||
value={form.brand}
|
||||
@@ -379,10 +377,9 @@ export default function Vehicles() {
|
||||
className="admin-form-input"
|
||||
placeholder="Škoda"
|
||||
/>
|
||||
</div>
|
||||
</FormField>
|
||||
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Model</label>
|
||||
<FormField label="Model">
|
||||
<input
|
||||
type="text"
|
||||
value={form.model}
|
||||
@@ -390,7 +387,7 @@ export default function Vehicles() {
|
||||
className="admin-form-input"
|
||||
placeholder="Octavia Combi"
|
||||
/>
|
||||
</div>
|
||||
</FormField>
|
||||
</div>
|
||||
|
||||
<div className="admin-form-group">
|
||||
|
||||
Reference in New Issue
Block a user