import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../controller/export_controller.dart'; import '../helper/storage_keys.dart'; import '../widgets/entry_panel.dart'; class ExportView extends GetView { static const routeName = '/export-view'; const ExportView({super.key}); @override Widget build(BuildContext context) => Scaffold( appBar: AppBar(title: const Text('Datensicherung')), body: SafeArea( child: Align( alignment: Alignment.topCenter, child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 760), child: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Obx(() { final busy = controller.isBusy.value; final backup = controller.pendingBackup.value; return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ EntryPanel( title: 'Daten exportieren', subtitle: 'Sichere Filamente, Verarbeitungsprofile, Bauteile inklusive Fotos und Verbrauch sowie deine Materialarten und Abfalleinträge in einer JSON-Datei.\n\nSpeichere die Datei außerhalb der App, zum Beispiel in Dokumente oder in deiner Cloud. So kannst du sie nach einer Neuinstallation wieder importieren.', child: FilledButton.icon( onPressed: busy ? null : controller.exportData, icon: const Icon(Icons.file_download_outlined), label: const Text('Als JSON exportieren'), ), ), const SizedBox(height: 20), EntryPanel( title: 'Daten importieren', subtitle: 'Wähle eine JSON-Datensicherung dieser App. Beim Import werden alle aktuell gespeicherten Daten durch den Inhalt der Datei ersetzt. Exportiere bei Bedarf vorher deinen aktuellen Bestand.', child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ OutlinedButton.icon( onPressed: busy ? null : controller.selectImport, icon: const Icon(Icons.file_upload_outlined), label: const Text('JSON-Datei auswählen'), ), if (backup != null) ...[ const SizedBox(height: 16), const Text('Geprüfte Datensicherung:'), Text( '${backup.data[StorageKeys.filamente]!.length} Filamente', ), Text( '${backup.data[StorageKeys.anwendungen]!.length} Profile', ), Text( '${backup.data[StorageKeys.bauteile]!.length} Bauteile', ), Text( backup.data[StorageKeys.materialien]!.isEmpty ? 'Materialarten: Standardliste' : '${(backup.data[StorageKeys.materialien]!.single['werte'] as List).length} Materialarten', ), Text( '${backup.data[StorageKeys.abfaelle]!.length} Abfalleinträge', ), const SizedBox(height: 16), FilledButton.icon( onPressed: busy ? null : () => _confirmImport(context), icon: const Icon(Icons.restore), label: const Text('Daten ersetzen und importieren'), ), ], ], ), ), if (busy) ...[ const SizedBox(height: 20), const LinearProgressIndicator(), ], EntryMessage( message: controller.message.value, hasError: controller.hasError.value, ), ], ); }), ), ), ), ), ); Future _confirmImport(BuildContext context) async { final confirmed = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Alle Daten ersetzen?'), content: const Text( 'Der aktuelle Bestand wird vollständig durch die ausgewählte Datensicherung ersetzt. Auch eine leere Sicherung ersetzt den Bestand.', ), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), child: const Text('Abbrechen'), ), FilledButton( onPressed: () => Navigator.pop(context, true), child: const Text('Daten ersetzen'), ), ], ), ); if (confirmed == true) await controller.importData(); } }