diff --git a/backend/src/routes/export.ts b/backend/src/routes/export.ts index 494e74c..ff0e228 100644 --- a/backend/src/routes/export.ts +++ b/backend/src/routes/export.ts @@ -233,11 +233,12 @@ export async function exportRoutes(app: FastifyInstance) { // --------------------------------------------------------------------------- // GET /export - Export all user data // --------------------------------------------------------------------------- - app.get<{ Querystring: { includeSensitive?: string } }>( + app.get<{ Querystring: { includeSensitive?: string; includeImages?: string } }>( "/export", async (request, reply) => { const userId = await getUserId(request, reply); const includeSensitive = request.query.includeSensitive === "true"; + const includeImages = request.query.includeImages !== "false"; // Default to true // 1. Load all medications const meds = await db.select().from(medications).where(eq(medications.userId, userId)).orderBy(medications.id); @@ -264,7 +265,7 @@ export async function exportRoutes(app: FastifyInstance) { expiryDate: med.expiryDate, notes: med.notes, intakeRemindersEnabled: med.intakeRemindersEnabled ?? false, - image: imageToBase64(med.imageUrl), + image: includeImages ? imageToBase64(med.imageUrl) : null, }; }); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index e7908a0..81c914b 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -366,6 +366,7 @@ function AppContent() { // Export/Import state const [exporting, setExporting] = useState(false); const [importing, setImporting] = useState(false); + const [exportIncludeImages, setExportIncludeImages] = useState(true); // User dropdown state (for mobile click-based behavior) const [userDropdownOpen, setUserDropdownOpen] = useState(false); @@ -1087,10 +1088,10 @@ function AppContent() { } // Export data to JSON file - async function handleExport() { + async function handleExport(includeImages: boolean = true) { setExporting(true); try { - const res = await fetch('/api/export?includeSensitive=true', { + const res = await fetch(`/api/export?includeSensitive=true&includeImages=${includeImages}`, { credentials: "include", }); if (!res.ok) throw new Error("Export failed"); @@ -2847,20 +2848,32 @@ function AppContent() {
{/* Export */} -
+
+
{t('exportImport.exportTitle')} {t('exportImport.exportDesc')}
-
+ + +
{/* Import */}
diff --git a/frontend/src/i18n/de.json b/frontend/src/i18n/de.json index 63f6389..1781486 100644 --- a/frontend/src/i18n/de.json +++ b/frontend/src/i18n/de.json @@ -372,6 +372,8 @@ "selectFile": "Datei auswählen", "includeSensitive": "Sensible Daten einschließen (Benachrichtigungs-URLs)", "sensitiveWarning": "Benachrichtigungs-URLs können Passwörter enthalten und werden im Klartext gespeichert.", + "includeImages": "Medikamentenbilder einschließen", + "includeImagesHint": "Bilder vergrößern die Datei erheblich. Deaktivieren für kleinere Exports (~50 KB statt mehrere MB).", "confirmImport": "Alle Daten ersetzen?", "confirmImportMessage": "Dies löscht dauerhaft alle deine aktuellen Medikamente, Einnahmehistorie, Einstellungen und Teilen-Links und ersetzt sie durch die importierten Daten.", "confirmImportWarning": "Diese Aktion kann nicht rückgängig gemacht werden!", diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index 76372af..d72b6a9 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -374,6 +374,8 @@ "selectFile": "Select File", "includeSensitive": "Include sensitive data (notification URLs)", "sensitiveWarning": "Notification URLs may contain passwords and will be stored in plain text.", + "includeImages": "Include medication images", + "includeImagesHint": "Images significantly increase file size. Uncheck for smaller exports (~50 KB instead of several MB).", "confirmImport": "Replace All Data?", "confirmImportMessage": "This will permanently delete all your current medications, dose history, settings, and share links, then replace them with the imported data.", "confirmImportWarning": "This action cannot be undone!",