Files
2026-07-06 18:01:38 +02:00

241 lines
9.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/auth_provider.dart';
import '../providers/schedule_provider.dart';
import '../widgets/event_card.dart';
import '../widgets/filter_dropdown.dart';
import '../widgets/loading_indicator.dart';
import 'event_detail_screen.dart';
import 'login_screen.dart';
class ScheduleScreen extends StatefulWidget {
const ScheduleScreen({super.key});
@override
State<ScheduleScreen> createState() => _ScheduleScreenState();
}
class _ScheduleScreenState extends State<ScheduleScreen> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
final scheduleProvider = context.read<ScheduleProvider>();
scheduleProvider.loadAccounts().then((_) {
scheduleProvider.loadCachedSchedule();
});
});
}
void _logout() async {
await context.read<AuthProvider>().logout();
await context.read<ScheduleProvider>().clearCache();
if (mounted) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (_) => const LoginScreen()),
);
}
}
Future<void> _refresh() async {
await context.read<ScheduleProvider>().refreshSchedule();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('MyIce'),
actions: [
Consumer<AuthProvider>(
builder: (context, auth, child) {
if (auth.userInfo != null) {
return Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(auth.userInfo!.email),
),
);
}
return const SizedBox.shrink();
},
),
IconButton(
icon: const Icon(Icons.refresh),
onPressed: _refresh,
),
IconButton(
icon: const Icon(Icons.logout),
onPressed: _logout,
),
],
),
body: Consumer<ScheduleProvider>(
builder: (context, schedule, child) {
if (schedule.isLoading && schedule.events.isEmpty) {
return const LoadingIndicator();
}
if (schedule.error != null && schedule.events.isEmpty) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
schedule.error!,
style: const TextStyle(color: Colors.red),
),
ElevatedButton(
onPressed: schedule.refreshSchedule,
child: const Text('Reessayer'),
),
],
),
);
}
return Stack(
children: [
Column(
children: [
Card(
margin: const EdgeInsets.all(16),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
FilterDropdown(
label: 'Compte',
value: schedule.selectedAccount,
items: schedule.accounts.map((a) => a.name).toList(),
onChanged: (value) {
if (value != null) {
schedule.setAccount(value);
}
},
),
const SizedBox(height: 8),
FilterDropdown(
label: 'Age',
value: schedule.selectedAgegroup,
items: schedule.agegroups,
onChanged: (value) {
schedule.setAgegroup(value);
},
),
const SizedBox(height: 8),
FilterDropdown(
label: 'Sous-groupe',
value: schedule.selectedSubgroup,
items: schedule.subgroups,
onChanged: (value) {
schedule.setSubgroup(value);
},
),
],
),
),
),
Expanded(
child: schedule.filteredEvents.isEmpty
? Center(
child: schedule.events.isEmpty
? const Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Aucun evenement disponible',
),
SizedBox(height: 8),
Text(
'Appuyez sur le bouton de rafraichissement pour charger les evenements',
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
],
)
: const Text('Aucun evenement disponible'),
)
: ListView.builder(
itemCount: schedule.filteredEvents.length,
itemBuilder: (context, index) {
final event = schedule.filteredEvents[index];
return EventCard(
event: event,
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => EventDetailScreen(
gameId: event.idEvent,
account: schedule.selectedAccount!,
eventTitle: event.title,
),
),
);
},
);
},
),
),
],
),
if (schedule.isRefreshing)
Positioned.fill(
child: AnimatedOpacity(
duration: const Duration(milliseconds: 300),
opacity: schedule.isRefreshing ? 1.0 : 0.0,
child: AbsorbPointer(
absorbing: true,
child: Container(
color: Colors.black.withValues(alpha: 0.4),
child: Center(
child: Container(
padding: const EdgeInsets.all(32),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.3),
blurRadius: 15,
spreadRadius: 2,
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(
width: 48,
height: 48,
child: CircularProgressIndicator(
strokeWidth: 4,
),
),
const SizedBox(height: 16),
Text(
'Chargement...',
style: TextStyle(
color: Colors.grey[800],
fontWeight: FontWeight.w600,
fontSize: 16,
),
),
],
),
),
),
),
),
),
),
],
);
},
),
);
}
}