| | import 'dart:ui';
|
| | import 'package:flutter/material.dart';
|
| |
|
| | void main() {
|
| | runApp(const Profil());
|
| | }
|
| |
|
| |
|
| | const Color primaryColor = Colors.deepPurple;
|
| | const Color accentColor = Colors.deepOrange;
|
| | const Color backgroundColor = Colors.white;
|
| |
|
| | class Profil extends StatelessWidget {
|
| | const Profil({super.key});
|
| |
|
| | @override
|
| | Widget build(BuildContext context) {
|
| | return MaterialApp(
|
| | debugShowCheckedModeBanner: false,
|
| | home: const DashboardScreen(),
|
| | );
|
| | }
|
| | }
|
| |
|
| | class DashboardScreen extends StatefulWidget {
|
| | const DashboardScreen({super.key});
|
| |
|
| | @override
|
| | State<DashboardScreen> createState() => _DashboardScreenState();
|
| | }
|
| |
|
| | class _DashboardScreenState extends State<DashboardScreen>
|
| | with SingleTickerProviderStateMixin {
|
| | late AnimationController _controller;
|
| | late Animation<double> _animation;
|
| |
|
| | bool isLoading = false;
|
| | List<String> children =
|
| | [];
|
| |
|
| | @override
|
| | void initState() {
|
| | super.initState();
|
| | _controller = AnimationController(
|
| | duration: const Duration(milliseconds: 800),
|
| | vsync: this,
|
| | );
|
| | _animation = CurvedAnimation(parent: _controller, curve: Curves.easeInOut);
|
| | _controller.forward();
|
| | }
|
| |
|
| | @override
|
| | void dispose() {
|
| | _controller.dispose();
|
| | super.dispose();
|
| | }
|
| |
|
| | Widget buildDrawer(BuildContext context) {
|
| | return Drawer(
|
| | child: ListView(
|
| | padding: EdgeInsets.zero,
|
| | children: const [
|
| | DrawerHeader(
|
| | decoration: BoxDecoration(color: Color.fromARGB(255, 54, 199, 32)),
|
| | child: Text(
|
| | 'Menu',
|
| | style: TextStyle(color: Colors.white, fontSize: 24),
|
| | ),
|
| | ),
|
| | ListTile(leading: Icon(Icons.home), title: Text('Accueil')),
|
| | ],
|
| | ),
|
| | );
|
| | }
|
| |
|
| | @override
|
| | Widget build(BuildContext context) {
|
| | return Scaffold(
|
| | backgroundColor: backgroundColor,
|
| | extendBodyBehindAppBar: true,
|
| | appBar: AppBar(
|
| | title: const Text(
|
| | 'Tableau de bord',
|
| | style: TextStyle(
|
| | color: Colors.white,
|
| | fontWeight: FontWeight.w700,
|
| | fontSize: 22,
|
| | ),
|
| | ),
|
| | backgroundColor: primaryColor.withOpacity(0.9),
|
| | elevation: 0,
|
| | shape: const RoundedRectangleBorder(
|
| | borderRadius: BorderRadius.vertical(bottom: Radius.circular(20)),
|
| | ),
|
| | iconTheme: const IconThemeData(color: Colors.white),
|
| | flexibleSpace: ClipRRect(
|
| | borderRadius: const BorderRadius.vertical(
|
| | bottom: Radius.circular(20),
|
| | ),
|
| | child: BackdropFilter(
|
| | filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
|
| | child: Container(
|
| | decoration: BoxDecoration(
|
| | gradient: LinearGradient(
|
| | colors: [
|
| | const Color.fromARGB(255, 7, 139, 47).withOpacity(0.9),
|
| | const Color.fromARGB(255, 34, 255, 144).withOpacity(0.8),
|
| | ],
|
| | begin: Alignment.topLeft,
|
| | end: Alignment.bottomRight,
|
| | ),
|
| | ),
|
| | ),
|
| | ),
|
| | ),
|
| | actions: [
|
| | Stack(
|
| | alignment: Alignment.center,
|
| | children: [
|
| | IconButton(
|
| | icon: const Icon(Icons.notifications_rounded, size: 28),
|
| | onPressed: () {},
|
| | ),
|
| | Positioned(
|
| | right: 12,
|
| | top: 14,
|
| | child: Container(
|
| | padding: const EdgeInsets.all(2),
|
| | decoration: BoxDecoration(
|
| | color: Colors.red,
|
| | borderRadius: BorderRadius.circular(6),
|
| | ),
|
| | constraints: const BoxConstraints(
|
| | minWidth: 16,
|
| | minHeight: 16,
|
| | ),
|
| | child: const Text(
|
| | '3',
|
| | style: TextStyle(
|
| | color: Colors.white,
|
| | fontSize: 10,
|
| | fontWeight: FontWeight.bold,
|
| | ),
|
| | textAlign: TextAlign.center,
|
| | ),
|
| | ),
|
| | ),
|
| | ],
|
| | ),
|
| | ],
|
| | ),
|
| | drawer: buildDrawer(context),
|
| | body: Container(
|
| | decoration: BoxDecoration(
|
| | gradient: LinearGradient(
|
| | begin: Alignment.topCenter,
|
| | end: Alignment.bottomCenter,
|
| | colors: [backgroundColor, Colors.white],
|
| | ),
|
| | ),
|
| | child: FadeTransition(
|
| | opacity: _animation,
|
| | child:
|
| | isLoading
|
| | ? const Center(child: CircularProgressIndicator())
|
| | : children.isEmpty
|
| | ? buildNoChildrenView()
|
| | : buildChildrenDashboard(),
|
| | ),
|
| | ),
|
| | floatingActionButton:
|
| | children.isEmpty
|
| | ? null
|
| | : FloatingActionButton(
|
| | onPressed: () {
|
| |
|
| | },
|
| | backgroundColor: accentColor,
|
| | elevation: 4,
|
| | child: const Icon(
|
| | Icons.add_rounded,
|
| | color: Colors.white,
|
| | size: 28,
|
| | ),
|
| | ),
|
| | );
|
| | }
|
| |
|
| | Widget buildNoChildrenView() {
|
| | return SingleChildScrollView(
|
| | physics: const BouncingScrollPhysics(),
|
| | padding: const EdgeInsets.symmetric(horizontal: 20),
|
| | child: Column(
|
| | mainAxisAlignment: MainAxisAlignment.center,
|
| | children: [
|
| | const SizedBox(height: 150),
|
| | Container(
|
| | width: 150,
|
| | height: 150,
|
| | decoration: BoxDecoration(
|
| | color: const Color.fromARGB(255, 16, 205, 47).withOpacity(0.1),
|
| | shape: BoxShape.circle,
|
| | ),
|
| | child: Icon(
|
| | Icons.person,
|
| | size: 80,
|
| | color: const Color.fromARGB(255, 152, 210, 59),
|
| | ),
|
| | ),
|
| | const SizedBox(height: 30),
|
| | Text(
|
| | 'Profil User',
|
| | style: TextStyle(
|
| | fontSize: 24,
|
| | fontWeight: FontWeight.bold,
|
| | color: const Color.fromARGB(255, 140, 197, 80),
|
| | ),
|
| | ),
|
| | const SizedBox(height: 15),
|
| | Text(
|
| | 'Vous n\'avez pas encore inscrit d\'enfant. Commencez par inscrire votre enfant pour accéder à son suivi scolaire.',
|
| | textAlign: TextAlign.center,
|
| | style: TextStyle(fontSize: 16, color: Colors.grey.shade700),
|
| | ),
|
| | const SizedBox(height: 30),
|
| | ElevatedButton.icon(
|
| | onPressed: () {},
|
| | icon: const Icon(Icons.person_add_rounded),
|
| | label: const Text(
|
| | 'Changer votre Profil',
|
| | style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
| | ),
|
| | style: ElevatedButton.styleFrom(
|
| | backgroundColor: const Color.fromARGB(255, 34, 255, 119),
|
| | foregroundColor: const Color.fromARGB(255, 17, 17, 17),
|
| | padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
| | shape: RoundedRectangleBorder(
|
| | borderRadius: BorderRadius.circular(15),
|
| | ),
|
| | elevation: 3,
|
| | ),
|
| | ),
|
| | ],
|
| | ),
|
| | );
|
| | }
|
| |
|
| | Widget buildChildrenDashboard() {
|
| | return Column(
|
| | children: [
|
| | const SizedBox(height: 110),
|
| | buildChildSelector(),
|
| | const SizedBox(height: 20),
|
| | Expanded(
|
| | child: SingleChildScrollView(
|
| | physics: const BouncingScrollPhysics(),
|
| | padding: const EdgeInsets.fromLTRB(20, 0, 20, 30),
|
| | child: Column(
|
| | crossAxisAlignment: CrossAxisAlignment.start,
|
| | children: [
|
| | buildChildSummary(),
|
| | const SizedBox(height: 20),
|
| | buildActionCards(),
|
| | const SizedBox(height: 25),
|
| | buildRecentActivities(),
|
| | const SizedBox(height: 25),
|
| | buildUpcomingEvents(),
|
| | ],
|
| | ),
|
| | ),
|
| | ),
|
| | ],
|
| | );
|
| | }
|
| |
|
| | Widget buildChildSelector() => const Text("Sélecteur d'enfant (à compléter)");
|
| | Widget buildChildSummary() => const Text("Résumé enfant (à compléter)");
|
| | Widget buildActionCards() => const Text("Actions (à compléter)");
|
| | Widget buildRecentActivities() =>
|
| | const Text("Activités récentes (à compléter)");
|
| | Widget buildUpcomingEvents() =>
|
| | const Text("Événements à venir (à compléter)");
|
| | }
|
| |
|