feat(backup): fold .picpeak restore into the Restore wizard's Upload source
Removes the redundant standalone .picpeak card. The wizard's 'Upload Backup' source now splits into two kinds: '.picpeak backup' (the working portable restore — renders the upload + destructive-confirm flow inline) and 'Manifest + files' (legacy, still 'Manifest Upload functionality coming soon'). en + de strings added.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { PicpeakRestoreCard } from './PicpeakBackupCard';
|
||||||
import {
|
import {
|
||||||
RefreshCw,
|
RefreshCw,
|
||||||
AlertTriangle,
|
AlertTriangle,
|
||||||
@@ -283,12 +284,47 @@ export const RestoreWizard = ({ onVerifyIntegrity } = {}) => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{restoreData.source === 'upload' && (
|
{restoreData.source === 'upload' && (
|
||||||
<Card className="p-4">
|
<div className="space-y-4">
|
||||||
<div className="text-center py-8">
|
{/* Two upload kinds: the working portable .picpeak restore, and the
|
||||||
<Upload className="h-12 w-12 mx-auto mb-3 text-neutral-400" />
|
legacy manifest+files upload (still a stub). */}
|
||||||
<p className="text-sm text-neutral-600 dark:text-neutral-400">{t('backup.restore.source.upload.comingSoon')}</p>
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<button
|
||||||
|
onClick={() => setRestoreData(prev => ({ ...prev, uploadType: 'picpeak' }))}
|
||||||
|
className={`p-6 rounded-lg border-2 transition-all ${
|
||||||
|
restoreData.uploadType === 'picpeak'
|
||||||
|
? 'border-primary bg-accent-dark/15'
|
||||||
|
: 'border-neutral-200 dark:border-neutral-600 hover:border-neutral-300 dark:hover:border-neutral-500'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<FileArchive className={`h-10 w-10 mb-2 mx-auto ${restoreData.uploadType === 'picpeak' ? 'text-primary' : 'text-neutral-400'}`} />
|
||||||
|
<h4 className="font-medium text-neutral-900 dark:text-neutral-100">{t('backup.restore.source.upload.picpeak.name', '.picpeak backup')}</h4>
|
||||||
|
<p className="text-xs text-neutral-500 dark:text-neutral-400 mt-1">{t('backup.restore.source.upload.picpeak.description', 'Portable full backup — restores everything (full override, keeps your current account).')}</p>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setRestoreData(prev => ({ ...prev, uploadType: 'manifest' }))}
|
||||||
|
className={`p-6 rounded-lg border-2 transition-all ${
|
||||||
|
restoreData.uploadType === 'manifest'
|
||||||
|
? 'border-primary bg-accent-dark/15'
|
||||||
|
: 'border-neutral-200 dark:border-neutral-600 hover:border-neutral-300 dark:hover:border-neutral-500'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<Upload className={`h-10 w-10 mb-2 mx-auto ${restoreData.uploadType === 'manifest' ? 'text-primary' : 'text-neutral-400'}`} />
|
||||||
|
<h4 className="font-medium text-neutral-900 dark:text-neutral-100">{t('backup.restore.source.upload.manifest.name', 'Manifest + files')}</h4>
|
||||||
|
<p className="text-xs text-neutral-500 dark:text-neutral-400 mt-1">{t('backup.restore.source.upload.manifest.description', 'Upload a manifest and its backup files (legacy format).')}</p>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
|
||||||
|
{restoreData.uploadType === 'picpeak' && <PicpeakRestoreCard />}
|
||||||
|
|
||||||
|
{restoreData.uploadType === 'manifest' && (
|
||||||
|
<Card className="p-4">
|
||||||
|
<div className="text-center py-8">
|
||||||
|
<Upload className="h-12 w-12 mx-auto mb-3 text-neutral-400" />
|
||||||
|
<p className="text-sm text-neutral-600 dark:text-neutral-400">{t('backup.restore.source.upload.manifestComingSoon', 'Manifest Upload functionality coming soon')}</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -634,7 +634,16 @@
|
|||||||
"upload": {
|
"upload": {
|
||||||
"name": "Backup hochladen",
|
"name": "Backup hochladen",
|
||||||
"description": "Eine Backup-Datei hochladen",
|
"description": "Eine Backup-Datei hochladen",
|
||||||
"comingSoon": "Upload-Funktion kommt bald"
|
"comingSoon": "Upload-Funktion kommt bald",
|
||||||
|
"manifestComingSoon": "Manifest-Upload-Funktion kommt bald",
|
||||||
|
"picpeak": {
|
||||||
|
"name": ".picpeak-Backup",
|
||||||
|
"description": "Portables Voll-Backup — stellt alles wieder her (vollständige Überschreibung, Ihr aktuelles Konto bleibt erhalten)."
|
||||||
|
},
|
||||||
|
"manifest": {
|
||||||
|
"name": "Manifest + Dateien",
|
||||||
|
"description": "Ein Manifest und die zugehörigen Backup-Dateien hochladen (Legacy-Format)."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"configuration": {
|
"configuration": {
|
||||||
"s3": "S3-Konfiguration",
|
"s3": "S3-Konfiguration",
|
||||||
|
|||||||
@@ -3022,7 +3022,16 @@
|
|||||||
"upload": {
|
"upload": {
|
||||||
"name": "Upload Backup",
|
"name": "Upload Backup",
|
||||||
"description": "Upload a backup file",
|
"description": "Upload a backup file",
|
||||||
"comingSoon": "Upload functionality coming soon"
|
"comingSoon": "Upload functionality coming soon",
|
||||||
|
"manifestComingSoon": "Manifest Upload functionality coming soon",
|
||||||
|
"picpeak": {
|
||||||
|
"name": ".picpeak backup",
|
||||||
|
"description": "Portable full backup — restores everything (full override, keeps your current account)."
|
||||||
|
},
|
||||||
|
"manifest": {
|
||||||
|
"name": "Manifest + files",
|
||||||
|
"description": "Upload a manifest and its backup files (legacy format)."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"configuration": {
|
"configuration": {
|
||||||
"s3": "S3 Configuration",
|
"s3": "S3 Configuration",
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import { BackupDashboard } from '../../components/admin/BackupDashboard';
|
|||||||
import { BackupConfiguration } from '../../components/admin/BackupConfiguration';
|
import { BackupConfiguration } from '../../components/admin/BackupConfiguration';
|
||||||
import { BackupHistory } from '../../components/admin/BackupHistory';
|
import { BackupHistory } from '../../components/admin/BackupHistory';
|
||||||
import { RestoreWizard } from '../../components/admin/RestoreWizard';
|
import { RestoreWizard } from '../../components/admin/RestoreWizard';
|
||||||
import { PicpeakExportCard, PicpeakRestoreCard } from '../../components/admin/PicpeakBackupCard';
|
import { PicpeakExportCard } from '../../components/admin/PicpeakBackupCard';
|
||||||
import { BackupIntegrityCard } from '../../components/admin/BackupIntegrityCard';
|
import { BackupIntegrityCard } from '../../components/admin/BackupIntegrityCard';
|
||||||
import { BackupCoverageCard } from '../../components/admin/BackupCoverageCard';
|
import { BackupCoverageCard } from '../../components/admin/BackupCoverageCard';
|
||||||
import { api } from '../../config/api';
|
import { api } from '../../config/api';
|
||||||
@@ -229,10 +229,7 @@ export const BackupManagement: React.FC = () => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === 'restore' && (
|
{activeTab === 'restore' && (
|
||||||
<div className="space-y-6">
|
<RestoreWizard onVerifyIntegrity={() => setActiveTab('integrity')} />
|
||||||
<PicpeakRestoreCard />
|
|
||||||
<RestoreWizard onVerifyIntegrity={() => setActiveTab('integrity')} />
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === 'integrity' && (
|
{activeTab === 'integrity' && (
|
||||||
|
|||||||
Reference in New Issue
Block a user