import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; class SettingsScreen extends StatefulWidget { const SettingsScreen({super.key}); @override State createState() => _SettingsScreenState(); } class _SettingsScreenState extends State { final _urlController = TextEditingController(); final _keyController = TextEditingController(); bool _isSaving = false; bool _obscureKey = true; static const _urlPrefKey = 'server_url'; static const _apiKeyPrefKey = 'api_key'; @override void initState() { super.initState(); _loadSettings(); } @override void dispose() { _urlController.dispose(); _keyController.dispose(); super.dispose(); } Future _loadSettings() async { final prefs = await SharedPreferences.getInstance(); _urlController.text = prefs.getString(_urlPrefKey) ?? ''; _keyController.text = prefs.getString(_apiKeyPrefKey) ?? ''; } Future _saveSettings() async { setState(() => _isSaving = true); try { final prefs = await SharedPreferences.getInstance(); await prefs.setString(_urlPrefKey, _urlController.text.trim()); await prefs.setString(_apiKeyPrefKey, _keyController.text.trim()); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Settings saved')), ); Navigator.pop(context, true); // true = settings changed } } finally { if (mounted) setState(() => _isSaving = false); } } Future _clearSettings() async { final confirmed = await showDialog( context: context, builder: (_) => AlertDialog( title: const Text('Clear settings?'), content: const Text('Server URL and API key will be removed.'), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), child: const Text('Cancel'), ), TextButton( onPressed: () => Navigator.pop(context, true), child: const Text('Clear', style: TextStyle(color: Colors.red)), ), ], ), ); if (confirmed == true) { final prefs = await SharedPreferences.getInstance(); await prefs.remove(_urlPrefKey); await prefs.remove(_apiKeyPrefKey); _urlController.clear(); _keyController.clear(); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Settings cleared')), ); } } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Backup settings'), actions: [ IconButton( icon: const Icon(Icons.delete_outline), tooltip: 'Clear settings', onPressed: _clearSettings, ), ], ), body: ListView( padding: const EdgeInsets.all(16), children: [ Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Theme.of(context).colorScheme.secondaryContainer, borderRadius: BorderRadius.circular(8), ), child: Row( children: [ Icon( Icons.info_outline, color: Theme.of(context).colorScheme.onSecondaryContainer, size: 20, ), const SizedBox(width: 8), Expanded( child: Text( 'Point to your running Python server. ' 'Leave blank to use local storage only.', style: TextStyle( color: Theme.of(context).colorScheme.onSecondaryContainer, fontSize: 13, ), ), ), ], ), ), const SizedBox(height: 24), TextField( controller: _urlController, keyboardType: TextInputType.url, autocorrect: false, decoration: const InputDecoration( labelText: 'Server URL', hintText: 'http://192.168.1.x:8000', prefixIcon: Icon(Icons.dns_outlined), border: OutlineInputBorder(), ), ), const SizedBox(height: 16), TextField( controller: _keyController, obscureText: _obscureKey, autocorrect: false, enableSuggestions: false, decoration: InputDecoration( labelText: 'API Key', hintText: 'Your X-API-Key value', prefixIcon: const Icon(Icons.key_outlined), border: const OutlineInputBorder(), suffixIcon: IconButton( icon: Icon( _obscureKey ? Icons.visibility_outlined : Icons.visibility_off_outlined, ), onPressed: () => setState(() => _obscureKey = !_obscureKey), ), ), ), const SizedBox(height: 32), FilledButton.icon( onPressed: _isSaving ? null : _saveSettings, icon: _isSaving ? const SizedBox( width: 16, height: 16, child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.save_outlined), label: Text(_isSaving ? 'Saving...' : 'Save'), ), ], ), ); } } class AppSettings { static const _urlPrefKey = 'server_url'; static const _apiKeyPrefKey = 'api_key'; static Future<({String url, String apiKey})> load() async { final prefs = await SharedPreferences.getInstance(); return ( url: prefs.getString(_urlPrefKey) ?? '', apiKey: prefs.getString(_apiKeyPrefKey) ?? '', ); } static bool isConfigured({required String url, required String apiKey}) { return url.isNotEmpty && apiKey.isNotEmpty; } }