bonpoint/mobile/lib/features/dashboard/dashboard_screen.dart
Julien Martin aac3a729a2 Initialise l'app Flutter mobile : BDD Drift, onboarding sans compte et tableau de bord.
Phase 1 du MVP : schéma SQLite porté depuis le prototype web, seed des règles/récompenses, flux d'onboarding en 4 étapes et écran d'accueil minimal.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-12 12:12:01 +02:00

126 lines
4.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../core/theme/app_theme.dart';
import '../../providers/database_provider.dart';
class DashboardScreen extends ConsumerWidget {
const DashboardScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final childrenAsync = ref.watch(childrenProvider);
return DecoratedBox(
decoration: const BoxDecoration(gradient: AppTheme.primaryGradient),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
title: const Text('Bons Points'),
actions: [
IconButton(
icon: const Icon(Icons.lock_outline),
tooltip: 'Espace parent',
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Espace parent — bientôt disponible'),
),
);
},
),
],
),
body: SafeArea(
child: childrenAsync.when(
loading: () => const Center(
child: CircularProgressIndicator(color: Colors.white),
),
error: (e, _) => Center(
child: Text(
'Erreur de chargement',
style: TextStyle(color: Colors.white.withValues(alpha: 0.9)),
),
),
data: (children) {
if (children.isEmpty) {
return const Center(
child: Text(
'Aucun enfant',
style: TextStyle(color: Colors.white),
),
);
}
return ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: children.length,
itemBuilder: (context, index) {
final child = children[index];
return Card(
margin: const EdgeInsets.only(bottom: 12),
child: ListTile(
contentPadding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 12,
),
leading: CircleAvatar(
radius: 28,
backgroundColor: AppTheme.parseColor(child.couleur),
child: Text(
child.prenom[0].toUpperCase(),
style: const TextStyle(
color: Colors.white,
fontSize: 22,
fontWeight: FontWeight.bold,
),
),
),
title: Text(
child.prenom,
style: const TextStyle(
fontWeight: FontWeight.w700,
fontSize: 18,
),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'${child.score}',
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
color: AppTheme.parseColor(child.couleur),
),
),
const SizedBox(width: 4),
const Text('', style: TextStyle(fontSize: 20)),
const SizedBox(width: 8),
Icon(
Icons.chevron_right,
color: Colors.grey.shade400,
),
],
),
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Fiche ${child.prenom} — bientôt disponible',
),
),
);
},
),
);
},
);
},
),
),
),
);
}
}