diff --git a/client/src/components/Packing/PackingListPanel.tsx b/client/src/components/Packing/PackingListPanel.tsx index 243ba34..aa6abf9 100644 --- a/client/src/components/Packing/PackingListPanel.tsx +++ b/client/src/components/Packing/PackingListPanel.tsx @@ -775,10 +775,25 @@ export default function PackingListPanel({ tripId, items }: PackingListPanelProp } } + // Parse CSV line respecting quoted values (e.g. "Shirt, blue" stays as one field) + const parseCsvLine = (line: string): string[] => { + const parts: string[] = [] + let current = '' + let inQuotes = false + for (let i = 0; i < line.length; i++) { + const ch = line[i] + if (ch === '"') { inQuotes = !inQuotes; continue } + if (!inQuotes && (ch === ',' || ch === ';' || ch === '\t')) { parts.push(current.trim()); current = ''; continue } + current += ch + } + parts.push(current.trim()) + return parts + } + const parseImportLines = (text: string) => { return text.split('\n').map(line => line.trim()).filter(Boolean).map(line => { // Format: Category, Name, Weight (optional), Bag (optional), checked/unchecked (optional) - const parts = line.split(/[,;\t]/).map(s => s.trim()) + const parts = parseCsvLine(line) if (parts.length >= 2) { const category = parts[0] const name = parts[1] @@ -1187,18 +1202,29 @@ export default function PackingListPanel({ tripId, items }: PackingListPanelProp }} onClick={e => e.stopPropagation()}>
{t('packing.importTitle')}
{t('packing.importHint')}
-