etm-powersync-app/lib/screens/settings/app_settings_screen.dart
pakutz79 c19c9d1a98 feat: navigation drawer, EMS setup, scheduler, tarifs, paramètres app
- Drawer custom (overlay Stack) avec mode installateur PIN SHA-256
- GoRouter + ShellRoute : navigation préservée entre onglets
- 6 providers : NavigationProvider, InstallerModeProvider, AppSettingsProvider,
  EnergySetupProvider, SchedulerProvider, TariffProvider
- Écrans Energy Manager : RoleConfigFlow (3 étapes), Scheduler, Tarifs, Timeline
- Écrans Paramètres : Apparence, Écrans actifs, AppSettingsScreen
- DrawerMenuButton présent dans les 5 AppBars principaux
- Simulation : _thingClasses générées avec interfaces EMS pour filtrage des rôles
- Compteur solaire : ajout smartmeter aux interfaces compatibles
- Thème ETM (etm_theme.dart), ProLockBadge, widgets PowerBar/RoleCard/TimelineSlotCard
- Dépendances : go_router, shared_preferences, crypto, url_launcher

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:52:32 +01:00

169 lines
5.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import '../../providers/installer_mode_provider.dart';
import '../../theme/app_theme.dart';
import '../../theme/etm_theme.dart';
/// Écran racine "App Settings" — liste des catégories.
class AppSettingsScreen extends StatelessWidget {
const AppSettingsScreen({super.key});
@override
Widget build(BuildContext context) {
final installer = context.watch<InstallerModeProvider>();
return Scaffold(
backgroundColor: const Color(0xFFF0F2F5),
appBar: AppBar(
title: const Text('App Settings'),
backgroundColor: Colors.white,
foregroundColor: const Color(0xFF1A1A2E),
elevation: 0,
),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
_SettingsGroup(
title: 'PERSONNALISATION',
items: [
_SettingsItem(
icon: Icons.palette_rounded,
label: 'Apparence',
subtitle: 'Thème, couleurs, taille du texte',
onTap: () => context.push('/settings/app/appearance'),
),
_SettingsItem(
icon: Icons.view_list_rounded,
label: 'Écrans actifs',
subtitle: 'Choisir et ordonner les onglets',
onTap: () => context.push('/settings/app/screens'),
),
],
),
const SizedBox(height: 12),
_SettingsGroup(
title: 'DÉVELOPPEUR',
items: [
_SettingsItem(
icon: Icons.code_rounded,
label: 'Options développeur',
subtitle: 'Logs verbeux, PIN installateur',
onTap: () => context.push('/settings/app/developer'),
),
_SettingsItem(
icon: Icons.info_outline_rounded,
label: 'À propos PowerSync',
subtitle: 'Version, licences',
onTap: () => context.push('/settings/app/about'),
),
],
),
if (installer.isUnlocked) ...[
const SizedBox(height: 12),
_SettingsGroup(
title: 'INSTALLATEUR',
items: [
_SettingsItem(
icon: Icons.settings_rounded,
label: 'Configuration système',
subtitle: 'Réseau, protocoles, plugins',
onTap: () => context.push('/settings/system'),
),
],
),
],
],
),
);
}
}
class _SettingsGroup extends StatelessWidget {
final String title;
final List<_SettingsItem> items;
const _SettingsGroup({required this.title, required this.items});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(left: 4, bottom: 8),
child: Text(
title,
style: const TextStyle(
fontSize: 11,
fontWeight: FontWeight.bold,
letterSpacing: 0.8,
color: Color(0xFF6B7280),
),
),
),
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14)),
child: Column(
children: items.asMap().entries.map((e) {
final item = e.value;
final isLast = e.key == items.length - 1;
return Column(
children: [
ListTile(
dense: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 16, vertical: 4),
leading: Container(
width: 36, height: 36,
decoration: BoxDecoration(
color: ETMTheme.accentColor
.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(10),
),
child: Icon(item.icon,
color: ETMTheme.accentColor, size: 20),
),
title: Text(item.label,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500)),
subtitle: Text(item.subtitle,
style: const TextStyle(
fontSize: 12,
color: AppTheme.textLight)),
trailing: const Icon(Icons.chevron_right_rounded,
color: AppTheme.textLight),
onTap: item.onTap,
),
if (!isLast)
const Divider(
height: 1, indent: 68, endIndent: 16),
],
);
}).toList(),
),
),
],
);
}
}
class _SettingsItem {
final IconData icon;
final String label;
final String subtitle;
final VoidCallback onTap;
const _SettingsItem({
required this.icon,
required this.label,
required this.subtitle,
required this.onTap,
});
}