etm-powersync-app/lib/theme/etm_theme.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

142 lines
5.1 KiB
Dart

import 'package:flutter/material.dart';
/// Système de design ETM PowerSync
/// Complète AppTheme (couleurs énergie) avec les couleurs de marque ETM.
class ETMTheme {
// ── Couleurs de marque ────────────────────────────────────────────────────────
static const Color primaryColor = Color(0xFF1B3A5C); // ETM dark blue
static const Color accentColor = Color(0xFF2E75B6); // ETM mid blue
static const Color successColor = Color(0xFF1E6B3C); // green
static const Color warningColor = Color(0xFFC55A11); // orange
static const Color errorColor = Color(0xFFB71C1C); // red
static const Color proColor = Color(0xFF5B2C8D); // purple (Pro features)
// ── Drawer ───────────────────────────────────────────────────────────────────
static const Color drawerBackground = Color(0xFF0F2133);
static const Color drawerSurface = Color(0xFF1A3249);
static const Color drawerItemActive = Color(0xFF2E75B6);
static const Color drawerTextPrimary = Color(0xFFEEF2F7);
static const Color drawerTextMuted = Color(0xFF8FA9C4);
static const double drawerWidth = 285.0;
// ── Badge "INSTALLATEUR" ─────────────────────────────────────────────────────
static const Color installerBadgeColor = Color(0xFFE65100);
// ── Widget Pro Lock ──────────────────────────────────────────────────────────
static Widget proLock(
BuildContext context,
String featureName, {
Widget? child,
}) {
return GestureDetector(
onTap: () => _showProBottomSheet(context, featureName),
child: Stack(
children: [
if (child != null)
Opacity(opacity: 0.5, child: child),
Positioned(
top: 2,
right: 2,
child: _ProBadge(),
),
],
),
);
}
static void _showProBottomSheet(BuildContext context, String featureName) {
showModalBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
builder: (_) => _ProBottomSheet(featureName: featureName),
);
}
}
class _ProBadge extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 2),
decoration: BoxDecoration(
color: ETMTheme.proColor,
borderRadius: BorderRadius.circular(6),
),
child: const Text(
'🔒 Pro',
style: TextStyle(
color: Colors.white,
fontSize: 9,
fontWeight: FontWeight.bold,
),
),
);
}
}
class _ProBottomSheet extends StatelessWidget {
final String featureName;
const _ProBottomSheet({required this.featureName});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(24, 20, 24, 32),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 36, height: 4,
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(height: 20),
Container(
width: 56, height: 56,
decoration: BoxDecoration(
color: ETMTheme.proColor.withValues(alpha: 0.12),
shape: BoxShape.circle,
),
child: const Icon(Icons.lock_rounded, color: ETMTheme.proColor, size: 28),
),
const SizedBox(height: 16),
Text(
featureName,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Color(0xFF1A1A2E),
),
),
const SizedBox(height: 8),
const Text(
'Cette fonctionnalité est disponible en version Pro.',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 14, color: Color(0xFF6B7280)),
),
const SizedBox(height: 24),
SizedBox(
width: double.infinity,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: ETMTheme.proColor,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
padding: const EdgeInsets.symmetric(vertical: 14),
),
onPressed: () => Navigator.pop(context),
child: const Text('En savoir plus'),
),
),
],
),
);
}
}