fix: add error handling and loading state to tariff save
This commit is contained in:
@@ -151,13 +151,15 @@ const EMPTY_TARIFF: Omit<Tariff, 'id'> = {
|
||||
}
|
||||
|
||||
function TariffModal({
|
||||
tariff, onSave, onClose, mealPlans, allInclusions,
|
||||
tariff, onSave, onClose, mealPlans, allInclusions, saving, error,
|
||||
}: {
|
||||
tariff?: Tariff
|
||||
onSave: (t: Omit<Tariff, 'id'>) => void
|
||||
onClose: () => void
|
||||
mealPlans: Array<{ id: string; label: string; description: string; inclusions: string[] }>
|
||||
allInclusions: Array<{ id: string; label: string; icon: React.ElementType }>
|
||||
saving?: boolean
|
||||
error?: string
|
||||
}) {
|
||||
const [form, setForm] = useState<Omit<Tariff, 'id'>>(
|
||||
tariff ? { ...tariff } : { ...EMPTY_TARIFF }
|
||||
@@ -214,16 +216,18 @@ function TariffModal({
|
||||
size="2xl"
|
||||
footer={
|
||||
<>
|
||||
<button onClick={onClose} className="btn-secondary">Отмена</button>
|
||||
{error && <p className="text-sm text-red-600 dark:text-red-400 mr-auto">{error}</p>}
|
||||
<button onClick={onClose} className="btn-secondary" disabled={saving}>Отмена</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
if (!form.name) return
|
||||
if (!form.name || saving) return
|
||||
const code = form.code || autoCode(form.name) || `T${Date.now().toString(36).toUpperCase().slice(-4)}`
|
||||
onSave({ ...form, code })
|
||||
}}
|
||||
className="btn-primary"
|
||||
disabled={!form.name}
|
||||
className="btn-primary gap-1.5 disabled:opacity-50"
|
||||
disabled={!form.name || saving}
|
||||
>
|
||||
{saving && <Loader2 size={14} className="animate-spin" />}
|
||||
{tariff ? 'Сохранить' : 'Создать тариф'}
|
||||
</button>
|
||||
</>
|
||||
@@ -412,6 +416,8 @@ export function TariffsPage() {
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [modal, setModal] = useState<'create' | Tariff | null>(null)
|
||||
const [deleteTarget, setDeleteTarget] = useState<Tariff | null>(null)
|
||||
const [saveError, setSaveError] = useState('')
|
||||
const [saving, setSaving] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (!slug) return
|
||||
@@ -442,6 +448,9 @@ export function TariffsPage() {
|
||||
|
||||
const save = async (data: Omit<Tariff, 'id'>) => {
|
||||
if (!slug) return
|
||||
setSaving(true)
|
||||
setSaveError('')
|
||||
try {
|
||||
const payload = {
|
||||
name: data.name, code: data.code, meal_plan: data.mealPlan,
|
||||
inclusions: data.inclusions, modifier_type: data.modifierType,
|
||||
@@ -451,14 +460,19 @@ export function TariffsPage() {
|
||||
}
|
||||
const isEdit = typeof modal === 'object' && modal !== null
|
||||
const saved = isEdit
|
||||
? await api.tariffs.update(slug, modal.id, payload)
|
||||
? await api.tariffs.update(slug, (modal as Tariff).id, payload)
|
||||
: await api.tariffs.create(slug, payload)
|
||||
const converted = fromApi(saved)
|
||||
setTariffs(prev => isEdit
|
||||
? prev.map(t => t.id === modal.id ? converted : t)
|
||||
? prev.map(t => t.id === (modal as Tariff).id ? converted : t)
|
||||
: [...prev, converted],
|
||||
)
|
||||
setModal(null)
|
||||
} catch (err) {
|
||||
setSaveError(err instanceof Error ? err.message : 'Ошибка сохранения')
|
||||
} finally {
|
||||
setSaving(false)
|
||||
}
|
||||
}
|
||||
|
||||
const toggleActive = async (id: string) => {
|
||||
@@ -740,9 +754,11 @@ export function TariffsPage() {
|
||||
<TariffModal
|
||||
tariff={typeof modal === 'object' ? modal : undefined}
|
||||
onSave={save}
|
||||
onClose={() => setModal(null)}
|
||||
onClose={() => { setModal(null); setSaveError('') }}
|
||||
mealPlans={mealPlans}
|
||||
allInclusions={allInclusions}
|
||||
saving={saving}
|
||||
error={saveError}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user