diff --git a/backend/src/routes/export.ts b/backend/src/routes/export.ts index cbc6295..ecab9ab 100644 --- a/backend/src/routes/export.ts +++ b/backend/src/routes/export.ts @@ -475,7 +475,11 @@ export async function exportRoutes(app: FastifyInstance) { }; // Set download headers - const filename = `medassist-export-${new Date().toISOString().split("T")[0]}.json`; + const now = new Date(); + const dateStr = now.toISOString().replace(/[-:]/g, "").replace(/T/, "-").slice(0, 13); + const authUser = env.AUTH_ENABLED ? (request.user as unknown as AuthUser | null) : null; + const userPart = authUser?.username ? `-${authUser.username}` : ""; + const filename = `medassist-export${userPart}-${dateStr}.json`; reply.header("Content-Type", "application/json"); reply.header("Content-Disposition", `attachment; filename="${filename}"`); diff --git a/frontend/src/context/AppContext.tsx b/frontend/src/context/AppContext.tsx index 19cc60a..df02199 100644 --- a/frontend/src/context/AppContext.tsx +++ b/frontend/src/context/AppContext.tsx @@ -522,9 +522,11 @@ export function AppProvider({ children }: { children: React.ReactNode }) { const blob = new Blob([JSON.stringify(data, null, 2)], { type: "application/json" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); - const dateStr = new Date().toISOString().split("T")[0]; + const now = new Date(); + const dateStr = now.toISOString().replace(/[-:]/g, "").replace(/T/, "-").slice(0, 13); + const userPart = user?.username ? `-${user.username}` : ""; a.href = url; - a.download = `${t("exportImport.downloadFilename")}-${dateStr}.json`; + a.download = `${t("exportImport.downloadFilename")}${userPart}-${dateStr}.json`; document.body.appendChild(a); a.click(); document.body.removeChild(a); diff --git a/frontend/src/i18n/de.json b/frontend/src/i18n/de.json index f467c71..e57a41e 100644 --- a/frontend/src/i18n/de.json +++ b/frontend/src/i18n/de.json @@ -500,6 +500,9 @@ "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!", "confirmButton": "Ja, alles ersetzen", + "confirmImportEmpty": "Daten importieren?", + "confirmImportEmptyMessage": "Alle Medikamente, Einnahmehistorie, Einstellungen und Teilen-Links aus der ausgewählten Datei werden importiert.", + "confirmButtonEmpty": "Importieren", "cancelButton": "Abbrechen", "exportSuccess": "Daten erfolgreich exportiert", "importSuccess": "Daten erfolgreich importiert", diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index 86299d4..abbad43 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -500,6 +500,9 @@ "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!", "confirmButton": "Yes, Replace All", + "confirmImportEmpty": "Import Data?", + "confirmImportEmptyMessage": "This will import all medications, dose history, settings, and share links from the selected file.", + "confirmButtonEmpty": "Import", "cancelButton": "Cancel", "exportSuccess": "Data exported successfully", "importSuccess": "Data imported successfully", diff --git a/frontend/src/pages/SettingsPage.tsx b/frontend/src/pages/SettingsPage.tsx index 9bbac4e..bbca0c8 100644 --- a/frontend/src/pages/SettingsPage.tsx +++ b/frontend/src/pages/SettingsPage.tsx @@ -30,8 +30,11 @@ export function SettingsPage() { handleImportConfirm, importResult, setImportResult, + meds, } = useAppContext(); + const hasExistingData = meds.length > 0; + return (
{settingsLoading ? ( @@ -799,21 +802,25 @@ export function SettingsPage() { {/* Import Confirmation Modal */} {showImportConfirm && ( -

{t("exportImport.confirmImportMessage")}

-

⚠️ {t("exportImport.confirmImportWarning")}

- + hasExistingData ? ( + <> +

{t("exportImport.confirmImportMessage")}

+

⚠️ {t("exportImport.confirmImportWarning")}

+ + ) : ( +

{t("exportImport.confirmImportEmptyMessage")}

+ ) } - confirmLabel={t("exportImport.confirmButton")} + confirmLabel={t(hasExistingData ? "exportImport.confirmButton" : "exportImport.confirmButtonEmpty")} cancelLabel={t("exportImport.cancelButton")} onConfirm={handleImportConfirm} onCancel={() => { setShowImportConfirm(false); setPendingImportData(null); }} - confirmVariant="danger" + confirmVariant={hasExistingData ? "danger" : "primary"} /> )} diff --git a/frontend/src/test/pages/SettingsPage.test.tsx b/frontend/src/test/pages/SettingsPage.test.tsx index 943727b..79144e1 100644 --- a/frontend/src/test/pages/SettingsPage.test.tsx +++ b/frontend/src/test/pages/SettingsPage.test.tsx @@ -86,6 +86,7 @@ const createMockContext = (overrides = {}) => ({ handleImportConfirm: vi.fn(), importResult: null, setImportResult: vi.fn(), + meds: [], ...overrides, });