diff --git a/web/src/lib/components/admin/ResearchPanel.svelte b/web/src/lib/components/admin/ResearchPanel.svelte index 9f45441..2ebbdd8 100644 --- a/web/src/lib/components/admin/ResearchPanel.svelte +++ b/web/src/lib/components/admin/ResearchPanel.svelte @@ -41,10 +41,21 @@ return JSON.stringify(val, null, 2); } + type LLMOeffnungszeit = { datum_von: string; datum_bis: string; von: string; bis: string }; + type LLMEintrittspreis = { name: string; betrag: number; waehrung: string }; + + function isLLMOeffnungszeiten(val: unknown): val is LLMOeffnungszeit[] { + return Array.isArray(val) && val.length > 0 && 'datum_von' in (val[0] as object); + } + + function isLLMEintrittspreise(val: unknown): val is LLMEintrittspreis[] { + return Array.isArray(val) && val.length > 0 && 'betrag' in (val[0] as object); + } + function isOpeningHours( val: unknown ): val is Array<{ day: string; open: string; close: string }> { - return Array.isArray(val) && val.length > 0 && 'day' in val[0]; + return Array.isArray(val) && val.length > 0 && 'day' in (val[0] as object); } function isAdmissionInfo(val: unknown): val is { @@ -111,7 +122,26 @@ {/if}
- {#if suggestion.field === 'opening_hours' && isOpeningHours(suggestion.suggested_value)} + {#if suggestion.field === 'opening_hours' && isLLMOeffnungszeiten(suggestion.suggested_value)} + + + + + + + + + + {#each suggestion.suggested_value as entry} + + + + + + {/each} + +
DatumVonBis
{entry.datum_von}{entry.von}{entry.bis}
+ {:else if suggestion.field === 'opening_hours' && isOpeningHours(suggestion.suggested_value)} @@ -130,6 +160,12 @@ {/each}
+ {:else if suggestion.field === 'admission_info' && isLLMEintrittspreise(suggestion.suggested_value)} + {:else if suggestion.field === 'admission_info' && isAdmissionInfo(suggestion.suggested_value)}
Erwachsene
diff --git a/web/src/routes/admin/maerkte/[id]/bearbeiten/+page.svelte b/web/src/routes/admin/maerkte/[id]/bearbeiten/+page.svelte index 080e714..890990f 100644 --- a/web/src/routes/admin/maerkte/[id]/bearbeiten/+page.svelte +++ b/web/src/routes/admin/maerkte/[id]/bearbeiten/+page.svelte @@ -33,7 +33,18 @@ 'Samstag' ]; + // LLM opening hours entry shape (researcher_schema_simple.json) + type LLMOeffnungszeit = { datum_von: string; datum_bis: string; von: string; bis: string }; + // LLM admission entry shape + type LLMEintrittspreis = { name: string; betrag: number; waehrung: string }; + function normalizeDayName(day: string): string { + // ISO date YYYY-MM-DD + if (/^\d{4}-\d{2}-\d{2}$/.test(day)) { + const [y, m, d] = day.split('-').map(Number); + return validDays[new Date(y, m - 1, d).getDay()]; + } + // German date DD.MM.YYYY const dateMatch = day.match(/(\d{2})\.(\d{2})\.(\d{4})/); if (dateMatch) { const d = new Date(+dateMatch[3], +dateMatch[2] - 1, +dateMatch[1]); @@ -46,19 +57,31 @@ function applyResearch(suggestions: FieldSuggestion[]) { for (const s of suggestions) { if (s.field === 'opening_hours' && Array.isArray(s.suggested_value)) { - const normalized = (s.suggested_value as OpeningHoursEntry[]).map((entry) => ({ - ...entry, - day: normalizeDayName(entry.day) - })); + const entries = s.suggested_value as Array; + const normalized: OpeningHoursEntry[] = entries.map((entry) => { + if ('datum_von' in entry) { + return { day: normalizeDayName(entry.datum_von), open: entry.von, close: entry.bis }; + } + return { ...entry, day: normalizeDayName(entry.day) }; + }); marketForm.setHours(normalized); continue; } - if ( - s.field === 'admission_info' && - typeof s.suggested_value === 'object' && - s.suggested_value !== null - ) { - marketForm.setAdmission(s.suggested_value as AdmissionInfo); + if (s.field === 'admission_info') { + if (Array.isArray(s.suggested_value)) { + // LLM format: [{name, betrag, waehrung}] — put in notes, leave cents at 0 + const tickets = s.suggested_value as LLMEintrittspreis[]; + const notes = tickets.map((t) => `${t.name}: ${t.betrag} ${t.waehrung}`).join('\n'); + marketForm.setAdmission({ + adult_cents: 0, + child_cents: 0, + reduced_cents: 0, + free_under_age: 0, + notes + }); + } else if (typeof s.suggested_value === 'object' && s.suggested_value !== null) { + marketForm.setAdmission(s.suggested_value as AdmissionInfo); + } continue; } const el = document.querySelector(