From 9a894c3a952e8929ca2275736111f36c02b1a3a5 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Thu, 11 Jun 2026 12:46:46 +0200 Subject: [PATCH] refactor: move export to its own settings page under Data group --- spa/src/routes/_app/settings/export.tsx | 88 +++++++++++++++++++++++++ spa/src/routes/_app/settings/index.tsx | 72 ++------------------ 2 files changed, 94 insertions(+), 66 deletions(-) create mode 100644 spa/src/routes/_app/settings/export.tsx diff --git a/spa/src/routes/_app/settings/export.tsx b/spa/src/routes/_app/settings/export.tsx new file mode 100644 index 0000000..da3fb4d --- /dev/null +++ b/spa/src/routes/_app/settings/export.tsx @@ -0,0 +1,88 @@ +import { createFileRoute, Link } from "@tanstack/react-router" +import { useState } from "react" +import { useTranslation } from "react-i18next" +import { ArrowLeft, Upload } from "lucide-react" +import { Button } from "@/components/ui/button" +import { API_URL } from "@/lib/api/client" +import { getToken } from "@/lib/auth" +import { useDocumentTitle } from "@/hooks/use-document-title" + +export const Route = createFileRoute("/_app/settings/export")({ + component: ExportPage, +}) + +function ExportPage() { + const { t } = useTranslation() + useDocumentTitle(t("settings.export")) + const [exporting, setExporting] = useState(null) + + async function handleExport(format: "csv" | "json") { + setExporting(format) + try { + const res = await fetch(`${API_URL}/api/v1/diary/export?format=${format}`, { + headers: { Authorization: `Bearer ${getToken()}` }, + }) + const blob = await res.blob() + const url = URL.createObjectURL(blob) + const a = document.createElement("a") + a.href = url + a.download = `diary.${format}` + a.click() + URL.revokeObjectURL(url) + } finally { + setExporting(null) + } + } + + return ( +
+
+ + + +

{t("settings.export")}

+
+ +
+
+ + + +
+

{t("settings.exportCsv")}

+

+ {t("settings.exportDesc")} +

+
+ +
+
+ + + +
+

{t("settings.exportJson")}

+

+ {t("settings.exportDesc")} +

+
+ +
+
+
+ ) +} diff --git a/spa/src/routes/_app/settings/index.tsx b/spa/src/routes/_app/settings/index.tsx index a789409..c6b0c53 100644 --- a/spa/src/routes/_app/settings/index.tsx +++ b/spa/src/routes/_app/settings/index.tsx @@ -1,5 +1,4 @@ import { createFileRoute, Link, useNavigate } from "@tanstack/react-router" -import { useState } from "react" import { useTranslation } from "react-i18next" import { useMutation } from "@tanstack/react-query" import { @@ -18,8 +17,6 @@ import { import { Button } from "@/components/ui/button" import { Switch } from "@/components/ui/switch" import { useAuth, useIsAdmin } from "@/components/auth-provider" -import { API_URL } from "@/lib/api/client" -import { getToken } from "@/lib/auth" import { reindexSearch } from "@/lib/api/users" import { useSettings, useUpdateSettings } from "@/hooks/use-goals" import { useDocumentTitle } from "@/hooks/use-document-title" @@ -58,6 +55,12 @@ function SettingsPage() { to: "/settings/import", icon: , }, + { + label: t("settings.export"), + description: t("settings.exportDesc"), + to: "/settings/export", + icon: , + }, { label: t("settings.yearWrapUp"), description: t("settings.yearWrapUpDesc"), @@ -100,7 +103,6 @@ function SettingsPage() { - @@ -186,68 +188,6 @@ function AdminActions() { ) } -function ExportSection() { - const { t } = useTranslation() - const [exporting, setExporting] = useState(null) - - async function handleExport(format: "csv" | "json") { - setExporting(format) - try { - const res = await fetch(`${API_URL}/api/v1/diary/export?format=${format}`, { - headers: { Authorization: `Bearer ${getToken()}` }, - }) - const blob = await res.blob() - const url = URL.createObjectURL(blob) - const a = document.createElement("a") - a.href = url - a.download = `diary.${format}` - a.click() - URL.revokeObjectURL(url) - } finally { - setExporting(null) - } - } - - return ( -
-

- {t("settings.export")} -

-
-
- - - -
-

{t("settings.export")}

-

- {t("settings.exportDesc")} -

-
-
- - -
-
-
-
- ) -} - function SettingsGroup({ label, items,