import type { ReactNode } from "react"; import Box from "@mui/material/Box"; import Typography from "@mui/material/Typography"; import IconButton from "@mui/material/IconButton"; import RichEditor from "../RichEditor"; import { Button, Card, TextField, Field, StatusChip, EmptyState, } from "../../ui"; /** One bilingual rich-text PDF section (offers' scope ≡ issued orders' sections). */ export interface DocumentSection { title: string; title_cz: string; content: string; } export const emptyDocumentSection = (): DocumentSection => ({ title: "", title_cz: "", content: "", }); const RemoveIcon = ( ); const UpIcon = ( ); const DownIcon = ( ); interface SectionsEditorProps { sections: DocumentSection[]; onChange: (sections: DocumentSection[]) => void; readOnly: boolean; /** Card heading. */ title?: string; /** * Document language — "CZ"/"cs" prefers the Czech section title in the * "Sekce N — …" header line, anything else the English one. */ language?: string; /** Optional page-specific control (e.g. scope-template Select) next to the add button. */ templatesSlot?: ReactNode; } /** * Bilingual rich-text sections editor shared by the document detail pages * (lifted from OfferDetail's "Rozsah projektu" card): bordered section boxes * with EN/CZ title fields (StatusChip badges), Quill content, up/down * reorder and add/remove. Offers pass their template Select via * `templatesSlot`; issued orders don't (no templates on POs). */ export default function SectionsEditor({ sections, onChange, readOnly, title = "Rozsah projektu", language, templatesSlot, }: SectionsEditorProps) { const preferCz = (language ?? "").toLowerCase().startsWith("cs") || (language ?? "").toUpperCase() === "CZ"; const updateSection = ( index: number, field: keyof DocumentSection, value: string, ) => onChange( sections.map((s, i) => (i === index ? { ...s, [field]: value } : s)), ); const moveSection = (index: number, delta: -1 | 1) => { const target = index + delta; if (target < 0 || target >= sections.length) return; const arr = [...sections]; [arr[index], arr[target]] = [arr[target], arr[index]]; onChange(arr); }; return ( {title} {!readOnly && ( {templatesSlot} )} {sections.length === 0 ? ( ) : ( {sections.map((section, idx) => ( Sekce {idx + 1} {(preferCz ? section.title_cz : section.title) && ( —{" "} {preferCz ? section.title_cz || section.title : section.title} )} {!readOnly && ( {idx > 0 && ( moveSection(idx, -1)} title="Posunout nahoru" aria-label="Posunout nahoru" > {UpIcon} )} {idx < sections.length - 1 && ( moveSection(idx, 1)} title="Posunout dolů" aria-label="Posunout dolů" > {DownIcon} )} onChange(sections.filter((_, i) => i !== idx)) } title="Odebrat sekci" aria-label="Odebrat sekci" > {RemoveIcon} )} Název sekce updateSection(idx, "title", e.target.value) } placeholder="Název sekce (anglicky)" InputProps={{ readOnly }} slotProps={{ htmlInput: { maxLength: 500 } }} /> Název sekce updateSection(idx, "title_cz", e.target.value) } placeholder="Název sekce (česky)" InputProps={{ readOnly }} slotProps={{ htmlInput: { maxLength: 500 } }} /> updateSection(idx, "content", val)} placeholder="Obsah sekce..." minHeight="120px" readOnly={readOnly} /> ))} )} ); }