fix: use RichEditor with readOnly prop instead of raw HTML for locked/invalidated offers

RichEditor now supports readOnly prop — hides toolbar and disables
editing via ReactQuill's built-in readOnly. Content renders with
proper Quill CSS (list margins, indentation, fonts) instead of
broken browser defaults from dangerouslySetInnerHTML.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-03-24 11:23:34 +01:00
parent b1aaec4fb6
commit 9e6ce4359a
2 changed files with 13 additions and 19 deletions

View File

@@ -64,23 +64,25 @@ interface RichEditorProps {
onChange: (value: string) => void
placeholder?: string
minHeight?: string
readOnly?: boolean
}
export default function RichEditor({
value,
onChange,
placeholder = 'Obsah...',
minHeight = '120px'
minHeight = '120px',
readOnly = false,
}: RichEditorProps) {
const quillRef = useRef<ReactQuill>(null)
const lastValueRef = useRef(value)
const modules = useMemo(() => ({
toolbar: TOOLBAR,
toolbar: readOnly ? false : TOOLBAR,
clipboard: {
matchVisual: false,
},
}), [])
}), [readOnly])
const handleChange = useCallback((content: string, _delta: any, source: string) => {
if (source !== 'user') return
@@ -99,6 +101,7 @@ export default function RichEditor({
modules={modules}
formats={FORMATS}
placeholder={placeholder}
readOnly={readOnly}
/>
</div>
)

View File

@@ -1097,22 +1097,13 @@ export default function OfferDetail() {
<div style={{ marginTop: '0.5rem' }}>
<label className="admin-form-label">Obsah</label>
{(isInvalidated || isLockedByOther) ? (
<div className="rich-editor">
<div
className="ql-editor"
style={{ minHeight: '80px', background: 'var(--bg-primary)', border: '1px solid var(--border-color)', borderRadius: 'var(--border-radius-sm)', cursor: 'default', overflowWrap: 'anywhere', wordBreak: 'break-word' }}
dangerouslySetInnerHTML={{ __html: section.content || '<em style="color: var(--text-tertiary)">Prázdný obsah</em>' }}
/>
</div>
) : (
<RichEditor
value={section.content}
onChange={(val) => setSections(prev => prev.map((s, i) => i === idx ? { ...s, content: val } : s))}
placeholder="Obsah sekce..."
minHeight="120px"
/>
)}
<RichEditor
value={section.content}
onChange={(val) => setSections(prev => prev.map((s, i) => i === idx ? { ...s, content: val } : s))}
placeholder="Obsah sekce..."
minHeight="120px"
readOnly={isInvalidated || isLockedByOther}
/>
</div>
</div>
))}