From a95ee473ae7fb2bf3c94c610724476701145d113 Mon Sep 17 00:00:00 2001 From: Luca <102960244+Luca-Timo@users.noreply.github.com> Date: Thu, 2 Jul 2026 21:57:50 +0200 Subject: [PATCH] feat(setup): add restore-from-backup branch to the first-run wizard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The usage step now offers 'Migrating from another PicPeak?' → a restore step that uploads a .picpeak (reusing PicpeakRestoreCard) to clone another instance onto this fresh one, preserving the account just created. en + de strings added. --- frontend/src/i18n/locales/de.json | 4 ++++ frontend/src/i18n/locales/en.json | 4 ++++ frontend/src/pages/SetupPage.tsx | 40 ++++++++++++++++++++++++++----- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/frontend/src/i18n/locales/de.json b/frontend/src/i18n/locales/de.json index befaace4..f704d13e 100644 --- a/frontend/src/i18n/locales/de.json +++ b/frontend/src/i18n/locales/de.json @@ -3505,6 +3505,10 @@ "usageSkip": "Nur mit Galerien fortfahren", "finish": "Einrichtung abschließen", "featuresSaveFailed": "Ihre Funktionsauswahl konnte nicht gespeichert werden — Sie können sie später unter Einstellungen → Funktionen festlegen.", + "restoreStepSubtitle": "Aus einem Backup wiederherstellen", + "restoreEntry": "Wechsel von einer anderen PicPeak-Instanz?", + "restoreEntryHint": "Stellen Sie stattdessen ein .picpeak-Backup wieder her, anstatt neu einzurichten.", + "restoreIntro": "Laden Sie ein .picpeak-Backup hoch, um eine andere Instanz auf diese zu klonen. Dies ersetzt alles außer dem gerade erstellten Konto.", "stepOf": "Schritt {{current}} von {{total}}", "continue": "Weiter", "back": "Zurück", diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json index 13d57bd0..d2e437e5 100644 --- a/frontend/src/i18n/locales/en.json +++ b/frontend/src/i18n/locales/en.json @@ -3401,6 +3401,10 @@ "usageSkip": "Continue with galleries only", "finish": "Finish setup", "featuresSaveFailed": "Could not save your feature choices — you can set them later in Settings → Features.", + "restoreStepSubtitle": "Restore from a backup", + "restoreEntry": "Migrating from another PicPeak?", + "restoreEntryHint": "Restore a .picpeak backup instead of setting up fresh.", + "restoreIntro": "Upload a .picpeak backup to clone another instance onto this one. This replaces everything except the account you just created.", "stepOf": "Step {{current}} of {{total}}", "continue": "Continue", "back": "Back", diff --git a/frontend/src/pages/SetupPage.tsx b/frontend/src/pages/SetupPage.tsx index c2747f0a..48fa2f0a 100644 --- a/frontend/src/pages/SetupPage.tsx +++ b/frontend/src/pages/SetupPage.tsx @@ -9,6 +9,7 @@ import { Button, Input, Card, Loading } from '../components/common'; import { useAdminAuth } from '../contexts'; import { setupService } from '../services/setup.service'; import { featureFlagsService, type FeatureFlags, type FeatureKey } from '../services/featureFlags.service'; +import { PicpeakRestoreCard } from '../components/admin/PicpeakBackupCard'; import { resolveLoginLogoClasses } from '../utils/loginLogoSize'; import type { AdminUser } from '../types'; @@ -51,7 +52,7 @@ export const SetupPage: React.FC = () => { staleTime: Infinity, }); - const [step, setStep] = useState<'token' | 'account' | 'usage'>('token'); + const [step, setStep] = useState<'token' | 'account' | 'usage' | 'restore'>('token'); const [form, setForm] = useState({ token: '', email: '', password: '', confirm: '' }); const [showPassword, setShowPassword] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); @@ -253,11 +254,15 @@ export const SetupPage: React.FC = () => { ? t('setup.tokenStepSubtitle') : step === 'account' ? t('setup.accountStepSubtitle') - : t('setup.usageSubtitle')} -
-- {t('setup.stepOf', { current: stepNumber, total: 3 })} + : step === 'restore' + ? t('setup.restoreStepSubtitle') + : t('setup.usageSubtitle')}
+ {step !== 'restore' && ( ++ {t('setup.stepOf', { current: stepNumber, total: 3 })} +
+ )}{t('setup.usageAlwaysOn')}
+ + {USAGE_GROUPS.map((group) => ({t('setup.restoreIntro')}
+