diff --git a/apps/mana/apps/web/src/lib/modules/invoices/components/SenderProfileForm.svelte b/apps/mana/apps/web/src/lib/modules/invoices/components/SenderProfileForm.svelte index f4de1016b..d56dcd9ed 100644 --- a/apps/mana/apps/web/src/lib/modules/invoices/components/SenderProfileForm.svelte +++ b/apps/mana/apps/web/src/lib/modules/invoices/components/SenderProfileForm.svelte @@ -6,10 +6,49 @@ import { invoiceSettingsStore } from '../stores/settings.svelte'; import type { InvoiceSettings, Currency } from '../types'; import { VAT_RATES_CH, VAT_RATES_DE, CURRENCIES } from '../constants'; + import { uploadLogo, logoPreviewUrl } from '../pdf/logo'; let settings = $state(null); let saving = $state(false); let savedAt = $state(null); + let uploadingLogo = $state(false); + let logoError = $state(null); + let logoInput: HTMLInputElement | undefined = $state(); + + async function onLogoSelect(e: Event) { + const input = e.target as HTMLInputElement; + const file = input.files?.[0]; + if (!file || !settings) return; + uploadingLogo = true; + logoError = null; + try { + const mediaId = await uploadLogo(file); + // Persist immediately — user doesn't need to hit "Speichern" separately + // for logo changes. The in-memory settings state stays in sync so + // further edits don't lose the mediaId. + await invoiceSettingsStore.update({ logoMediaId: mediaId }); + settings.logoMediaId = mediaId; + } catch (e) { + logoError = e instanceof Error ? e.message : 'Upload fehlgeschlagen'; + } finally { + uploadingLogo = false; + input.value = ''; + } + } + + async function removeLogo() { + if (!settings) return; + uploadingLogo = true; + logoError = null; + try { + await invoiceSettingsStore.update({ logoMediaId: null }); + settings.logoMediaId = null; + } catch (e) { + logoError = e instanceof Error ? e.message : 'Entfernen fehlgeschlagen'; + } finally { + uploadingLogo = false; + } + } $effect(() => { invoiceSettingsStore.get().then((s) => { @@ -66,6 +105,56 @@

Absender

Erscheint im Kopf jeder Rechnung.

+
+ Logo +
+ {#if settings.logoMediaId} + Logo-Vorschau +
+ + +
+ {:else} + + {/if} + +
+ {#if logoError} + {logoError} + {/if} +
+