import { useCallback, useEffect, useState } from 'react' import { ChevronDown, ChevronUp, Lock, Pencil, Trash2 } from 'lucide-react' import { fetchEntries as fetchEntriesFromPb } from '@/lib/pocketbase' import { toEditorHtml } from '@/lib/instructionHtml' import { buildPrintDocumentHtml } from '@/lib/buildPrintDocumentHtml' import { RichTextEditor } from '@/components/RichTextEditor' const ADDRESS_PLACEHOLDER = '101- 444 Concession St\nHamilton, ON\nL9A 1C2' const cardStyle = { padding: 12, borderRadius: 8, background: '#18181b', border: '1px solid #27272a', } const buttonStyle = { padding: '6px 12px', borderRadius: 6, border: 'none', background: '#3f3f46', color: '#e4e4e7', fontSize: '0.8125rem', fontWeight: 500, cursor: 'pointer', } const primaryButtonStyle = { ...buttonStyle, background: '#7c3aed' } const iconButtonStyle = { ...buttonStyle, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', padding: 6, lineHeight: 0, } const removeButtonStyle = { ...iconButtonStyle, background: '#dc2626', color: '#fff', } function slotId() { return typeof crypto !== 'undefined' && crypto.randomUUID ? crypto.randomUUID() : `slot-${Date.now()}-${Math.random().toString(36).slice(2)}` } export function Instructions() { const [entries, setEntries] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [canvasItems, setCanvasItems] = useState([]) const [pdfLoading, setPdfLoading] = useState(false) const [pdfError, setPdfError] = useState(null) const [editingSlotId, setEditingSlotId] = useState(null) const [editBaseline, setEditBaseline] = useState(null) const fetchEntries = useCallback(async () => { setLoading(true) setError(null) try { const list = await fetchEntriesFromPb() setEntries(list) } catch (e) { const msg = e instanceof Error ? e.message : String(e) setError(msg) setEntries([]) } finally { setLoading(false) } }, []) useEffect(() => { fetchEntries() }, [fetchEntries]) function addToCanvas(entry) { setCanvasItems((prev) => [ ...prev, { slotId: slotId(), id: entry.id, vaccine: entry.vaccine, instruction: entry.instruction ?? '' }, ]) } function moveUp(index) { if (index <= 0) return setCanvasItems((prev) => { const next = [...prev] ;[next[index - 1], next[index]] = [next[index], next[index - 1]] return next }) } function moveDown(index) { if (index >= canvasItems.length - 1) return setCanvasItems((prev) => { const next = [...prev] ;[next[index], next[index + 1]] = [next[index + 1], next[index]] return next }) } function startPreviewEdit(slotId) { const item = canvasItems.find((it) => it.slotId === slotId) if (item) { setEditBaseline({ instruction: item.instruction ?? '' }) } setEditingSlotId(slotId) } function cancelPreviewEdit() { if (editingSlotId && editBaseline) { updateCanvasInstruction(editingSlotId, editBaseline.instruction) } setEditBaseline(null) setEditingSlotId(null) } function lockPreviewEdit() { setEditBaseline(null) setEditingSlotId(null) } function remove(index) { const removedId = canvasItems[index]?.slotId setCanvasItems((prev) => prev.filter((_, i) => i !== index)) if (removedId != null) { setEditingSlotId((current) => (current === removedId ? null : current)) if (editingSlotId === removedId) setEditBaseline(null) } } function updateCanvasInstruction(slotId, instruction) { setCanvasItems((prev) => prev.map((it) => (it.slotId === slotId ? { ...it, instruction } : it)) ) } const editingItem = editingSlotId ? canvasItems.find((it) => it.slotId === editingSlotId) : null async function handleDownloadPdf() { if (canvasItems.length === 0 || pdfLoading) return setPdfLoading(true) setPdfError(null) try { const { base64: logoBase64 } = await window.ipcRenderer.invoke('pdf:getLogo') const html = buildPrintDocumentHtml({ items: canvasItems, logoBase64, address: ADDRESS_PLACEHOLDER, }) const { base64 } = await window.ipcRenderer.invoke('pdf:generate', { html }) const res = await window.ipcRenderer.invoke('pdf:save', { base64, defaultName: 'vaccine-instructions.pdf', }) if (res && !res.ok) { setPdfError('Save cancelled') } } catch (e) { const msg = e instanceof Error ? e.message : String(e) setPdfError(msg || 'PDF export failed') console.error('PDF export failed:', e) } finally { setPdfLoading(false) } } return (
{it.vaccine}
{editingSlotId ? 'Editing one instruction | Lock when done.' : 'Edits here apply to this document and PDF only.'}
{editingItem.vaccine}
{it.vaccine}