refactor(mui): migrate OrderConfirmationModal to kit Modal

Replace legacy FormModal with the MUI kit Modal. Map the two-step
flow (choose/edit) onto the kit footer: submitText + onSubmit switch
per step, submitDisabled gates "Vygenerovat PDF" when there are no
items. Re-skin lang/VAT toggles (kit Button variants), item editor
(kit TextField + IconButton inside a Box table). All generate/preview
logic, props, and Czech text preserved verbatim.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-06-07 08:43:10 +02:00
parent 6f428b2297
commit e13f977c4d

View File

@@ -1,5 +1,8 @@
import { useState, useCallback } from "react";
import FormModal from "./FormModal";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import IconButton from "@mui/material/IconButton";
import { Modal, Button, TextField, Field } from "../ui";
import { useAlert } from "../context/AlertContext";
interface ConfirmationItem {
@@ -103,119 +106,111 @@ export default function OrderConfirmationModal({
}, [defaultVatRate]);
return (
<FormModal
<Modal
isOpen={isOpen}
onClose={onClose}
title={`Potvrzení objednávky ${orderNumber}`}
size={step === "edit" ? "lg" : "md"}
maxWidth={step === "edit" ? "lg" : "md"}
loading={loading}
hideFooter
submitText={
step === "choose" ? "Použít položky z objednávky" : "Vygenerovat PDF"
}
submitDisabled={step === "edit" && items.length === 0}
onSubmit={step === "choose" ? handleUseExisting : handleEditGenerate}
>
{step === "choose" ? (
<div className="admin-form">
<div className="admin-form-group">
<label className="admin-form-label">Jazyk dokumentu</label>
<div className="flex-row gap-2">
<button
type="button"
<Box>
<Field label="Jazyk dokumentu">
<Box sx={{ display: "flex", gap: 1 }}>
<Button
size="small"
variant={lang === "cs" ? "contained" : "outlined"}
color={lang === "cs" ? "primary" : "inherit"}
onClick={() => setLang("cs")}
className={
lang === "cs"
? "admin-btn admin-btn-primary admin-btn-sm"
: "admin-btn admin-btn-secondary admin-btn-sm"
}
>
Čeština
</button>
<button
type="button"
</Button>
<Button
size="small"
variant={lang === "en" ? "contained" : "outlined"}
color={lang === "en" ? "primary" : "inherit"}
onClick={() => setLang("en")}
className={
lang === "en"
? "admin-btn admin-btn-primary admin-btn-sm"
: "admin-btn admin-btn-secondary admin-btn-sm"
}
>
English
</button>
</div>
</div>
</Button>
</Box>
</Field>
<div className="admin-form-group">
<label className="admin-form-label">DPH</label>
<div className="flex-row gap-2">
<button
type="button"
<Field label="DPH">
<Box sx={{ display: "flex", gap: 1 }}>
<Button
size="small"
variant={applyVatState ? "contained" : "outlined"}
color={applyVatState ? "primary" : "inherit"}
onClick={() => setApplyVatState(true)}
className={
applyVatState
? "admin-btn admin-btn-primary admin-btn-sm"
: "admin-btn admin-btn-secondary admin-btn-sm"
}
>
S DPH
</button>
<button
type="button"
</Button>
<Button
size="small"
variant={!applyVatState ? "contained" : "outlined"}
color={!applyVatState ? "primary" : "inherit"}
onClick={() => setApplyVatState(false)}
className={
!applyVatState
? "admin-btn admin-btn-primary admin-btn-sm"
: "admin-btn admin-btn-secondary admin-btn-sm"
}
>
Bez DPH
</button>
</div>
</div>
</Button>
</Box>
</Field>
<div className="admin-form-group">
<label className="admin-form-label">Obsah potvrzení</label>
<p className="text-secondary" style={{ marginBottom: "0.75rem" }}>
<Field label="Obsah potvrzení">
<Typography variant="body2" color="text.secondary" sx={{ mb: 1.5 }}>
Jak chcete připravit potvrzení objednávky?
</p>
<button
onClick={handleUseExisting}
disabled={loading}
className="admin-btn admin-btn-primary w-full"
style={{ marginBottom: "0.5rem" }}
>
{loading ? (
<>
<div className="admin-spinner admin-spinner-sm" />
Generuji...
</>
) : (
"Použít položky z objednávky"
)}
</button>
<button
</Typography>
<Button
fullWidth
onClick={() => {
setItems(initialItems.length > 0 ? initialItems : []);
setStep("edit");
}}
disabled={loading}
className="admin-btn admin-btn-secondary w-full"
variant="outlined"
color="inherit"
>
Upravit položky
</button>
</div>
<div className="admin-modal-footer">
<button
type="button"
onClick={onClose}
className="admin-btn admin-btn-secondary"
</Button>
</Field>
</Box>
) : (
<Box>
<Box sx={{ mb: 1.5 }}>
<Button
size="small"
variant="outlined"
color="inherit"
onClick={() => setStep("choose")}
disabled={loading}
>
Zrušit
</button>
</div>
</div>
) : (
<div className="admin-form">
<div className="admin-table-responsive">
<table className="admin-table">
Zt
</Button>
</Box>
<Box sx={{ overflowX: "auto" }}>
<Box
component="table"
sx={{
width: "100%",
borderCollapse: "collapse",
"& th": {
textAlign: "left",
fontSize: ".7rem",
textTransform: "uppercase",
letterSpacing: ".05em",
fontWeight: 700,
color: "text.secondary",
pb: 1,
},
"& td": { py: 0.5, pr: 1, verticalAlign: "middle" },
}}
>
<thead>
<tr>
<th>Popis</th>
@@ -230,39 +225,34 @@ export default function OrderConfirmationModal({
{items.map((item, i) => (
<tr key={i}>
<td>
<input
type="text"
<TextField
value={item.description}
onChange={(e) =>
updateItem(i, "description", e.target.value)
}
className="admin-form-input"
style={{ minWidth: "200px" }}
sx={{ minWidth: 200 }}
/>
</td>
<td>
<input
<TextField
type="number"
value={item.quantity}
onChange={(e) =>
updateItem(i, "quantity", Number(e.target.value) || 0)
}
className="admin-form-input"
style={{ width: "80px" }}
step="0.001"
sx={{ width: 90 }}
slotProps={{ htmlInput: { step: "0.001" } }}
/>
</td>
<td>
<input
type="text"
<TextField
value={item.unit}
onChange={(e) => updateItem(i, "unit", e.target.value)}
className="admin-form-input"
style={{ width: "60px" }}
sx={{ width: 70 }}
/>
</td>
<td>
<input
<TextField
type="number"
value={item.unit_price}
onChange={(e) =>
@@ -272,28 +262,28 @@ export default function OrderConfirmationModal({
Number(e.target.value) || 0,
)
}
className="admin-form-input"
style={{ width: "100px" }}
step="0.01"
sx={{ width: 110 }}
slotProps={{ htmlInput: { step: "0.01" } }}
/>
</td>
<td>
<input
<TextField
type="number"
value={item.vat_rate}
onChange={(e) =>
updateItem(i, "vat_rate", Number(e.target.value) || 0)
}
className="admin-form-input"
style={{ width: "70px" }}
step="1"
sx={{ width: 80 }}
slotProps={{ htmlInput: { step: "1" } }}
/>
</td>
<td>
<button
<IconButton
size="small"
color="error"
onClick={() => removeItem(i)}
className="admin-btn-icon danger"
title="Odstranit"
aria-label="Odstranit"
>
<svg
width="16"
@@ -306,47 +296,25 @@ export default function OrderConfirmationModal({
<polyline points="3 6 5 6 21 6" />
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
</svg>
</button>
</IconButton>
</td>
</tr>
))}
</tbody>
</table>
</div>
<button
onClick={addItem}
className="admin-btn admin-btn-secondary admin-btn-sm"
>
+ Přidat položku
</button>
<div className="admin-modal-footer">
<button
type="button"
onClick={() => setStep("choose")}
className="admin-btn admin-btn-secondary"
disabled={loading}
</Box>
</Box>
<Box sx={{ mt: 1.5 }}>
<Button
size="small"
variant="outlined"
color="inherit"
onClick={addItem}
>
Zpět
</button>
<button
type="button"
onClick={handleEditGenerate}
className="admin-btn admin-btn-primary"
disabled={loading || items.length === 0}
>
{loading ? (
<>
<div className="admin-spinner admin-spinner-sm" />
Generuji...
</>
) : (
"Vygenerovat PDF"
)}
</button>
</div>
</div>
+ Přidat položku
</Button>
</Box>
</Box>
)}
</FormModal>
</Modal>
);
}