refactor: migrace vsech formularu na FormField komponentu + JWT upgrade

- FormField.jsx: pridana podpora style prop
- 23 stranek migrovano na FormField (166 vyskytu, -246 radku)
- firebase/php-jwt upgrade v6.11 -> v7.0.3 (security advisory fix)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 19:33:36 +01:00
parent 37122579d0
commit 2328ba2840
26 changed files with 366 additions and 612 deletions

View File

@@ -5,6 +5,7 @@ import { useParams, useNavigate, Link } from 'react-router-dom'
import { motion, AnimatePresence } from 'framer-motion'
import ConfirmModal from '../components/ConfirmModal'
import FormField from '../components/FormField'
import Forbidden from '../components/Forbidden'
import AdminDatePicker from '../components/AdminDatePicker'
import OfferItemsSection from '../components/OfferItemsSection'
@@ -319,8 +320,7 @@ export default function OfferDetail() {
<h3 className="admin-card-title">Základní údaje</h3>
<div className="admin-form">
<div className="offers-form-row-3">
<div className="admin-form-group">
<label className="admin-form-label">Číslo nabídky</label>
<FormField label="Číslo nabídky">
<input
type="text"
value={form.quotation_number}
@@ -328,9 +328,8 @@ export default function OfferDetail() {
readOnly
style={{ backgroundColor: 'var(--bg-secondary)', cursor: 'default' }}
/>
</div>
<div className="admin-form-group">
<label className="admin-form-label">Kód projektu</label>
</FormField>
<FormField label="Kód projektu">
<input
type="text"
value={form.project_code}
@@ -339,7 +338,7 @@ export default function OfferDetail() {
placeholder="Volitelný kód projektu"
readOnly={isInvalidated}
/>
</div>
</FormField>
<OfferCustomerPicker
customers={customers}
customerId={form.customer_id}
@@ -352,8 +351,7 @@ export default function OfferDetail() {
</div>
<div className="admin-form-row">
<div className={`admin-form-group${errors.created_at ? ' has-error' : ''}`}>
<label className="admin-form-label required">Datum vytvoření</label>
<FormField label="Datum vytvoření" error={errors.created_at} required>
{isInvalidated ? (
<input type="text" value={form.created_at} className="admin-form-input" readOnly />
) : (
@@ -366,10 +364,8 @@ export default function OfferDetail() {
}}
/>
)}
{errors.created_at && <span className="admin-form-error">{errors.created_at}</span>}
</div>
<div className={`admin-form-group${errors.valid_until ? ' has-error' : ''}`}>
<label className="admin-form-label required">Platnost do</label>
</FormField>
<FormField label="Platnost do" error={errors.valid_until} required>
{isInvalidated ? (
<input type="text" value={form.valid_until} className="admin-form-input" readOnly />
) : (
@@ -382,13 +378,11 @@ export default function OfferDetail() {
}}
/>
)}
{errors.valid_until && <span className="admin-form-error">{errors.valid_until}</span>}
</div>
</FormField>
</div>
<div className="admin-form-row">
<div className="admin-form-group">
<label className="admin-form-label">Měna</label>
<FormField label="Měna">
<select
value={form.currency}
onChange={(e) => updateForm('currency', e.target.value)}
@@ -400,9 +394,8 @@ export default function OfferDetail() {
<option value="CZK">CZK ()</option>
<option value="GBP">GBP (&pound;)</option>
</select>
</div>
<div className="admin-form-group">
<label className="admin-form-label">Jazyk nabídky</label>
</FormField>
<FormField label="Jazyk nabídky">
<select
value={form.language}
onChange={(e) => updateForm('language', e.target.value)}
@@ -412,12 +405,11 @@ export default function OfferDetail() {
<option value="EN">English</option>
<option value="CZ">Čeština</option>
</select>
</div>
</FormField>
</div>
<div className="offers-form-row-3">
<div className="admin-form-group">
<label className="admin-form-label">Sazba DPH (%)</label>
<FormField label="Sazba DPH (%)">
<div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem' }}>
<input
type="number"
@@ -438,9 +430,8 @@ export default function OfferDetail() {
<span>Účtovat DPH</span>
</label>
</div>
</div>
<div className="admin-form-group">
<label className="admin-form-label">Směnný kurz</label>
</FormField>
<FormField label="Směnný kurz">
<input
type="number"
value={form.exchange_rate}
@@ -450,7 +441,7 @@ export default function OfferDetail() {
step="0.0001"
readOnly={isInvalidated}
/>
</div>
</FormField>
</div>
</div>
</motion.div>
@@ -510,8 +501,7 @@ export default function OfferDetail() {
</div>
<div className="admin-modal-body">
<div className="admin-form">
<div className="admin-form-group">
<label className="admin-form-label required">Číslo objednávky zákazníka</label>
<FormField label="Číslo objednávky zákazníka" required>
<input
type="text"
value={customerOrderNumber}
@@ -521,9 +511,8 @@ export default function OfferDetail() {
placeholder="Např. PO-2026-001"
autoFocus
/>
</div>
<div className="admin-form-group">
<label className="admin-form-label">Příloha (PDF)</label>
</FormField>
<FormField label="Příloha (PDF)">
{orderAttachment ? (
<div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--accent-color)" strokeWidth="2">
@@ -562,7 +551,7 @@ export default function OfferDetail() {
</label>
)}
<small className="admin-form-hint" style={{ marginTop: '0.25rem' }}>Max 10 MB</small>
</div>
</FormField>
</div>
</div>
<div className="admin-modal-footer">