import 'package:flutter/material.dart'; import 'package:manager_api_new/api.dart'; import 'package:manager_app/constants.dart'; import 'package:manager_app/Components/check_input_container.dart'; import 'package:manager_app/Components/multi_string_input_container.dart'; import 'package:manager_app/Components/single_select_container.dart'; import 'package:manager_app/Components/message_notification.dart'; import 'package:provider/provider.dart'; import 'package:manager_app/app_context.dart'; import 'package:manager_app/Models/managerContext.dart'; import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; import 'showNewOrUpdateEventAgenda.dart'; class AgendaConfig extends StatefulWidget { final String? color; final String? label; final AgendaDTO initialValue; final ValueChanged onChanged; const AgendaConfig({ Key? key, this.color, this.label, required this.initialValue, required this.onChanged, }) : super(key: key); @override _AgendaConfigState createState() => _AgendaConfigState(); } class _AgendaConfigState extends State { late AgendaDTO agendaDTO; List events = []; @override void initState() { super.initState(); agendaDTO = widget.initialValue; WidgetsBinding.instance.addPostFrameCallback((_) => _loadFromApi()); } Future _loadFromApi() async { if (agendaDTO.id == null || !mounted) return; final appContext = Provider.of(context, listen: false); final api = (appContext.getContext() as ManagerAppContext) .clientAPI! .sectionAgendaApi!; try { final fetched = await api.sectionAgendaGetAllEventAgendaFromSection(agendaDTO.id!); if (fetched == null || !mounted) return; setState(() { events = List.from(fetched); }); } catch (e) { // Silently keep empty on error } } SectionAgendaApi _api(BuildContext ctx) { final appContext = Provider.of(ctx, listen: false); return (appContext.getContext() as ManagerAppContext) .clientAPI! .sectionAgendaApi!; } @override Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; var mapProviderIn = ""; switch (agendaDTO.agendaMapProvider) { case MapProvider.Google: mapProviderIn = "Google"; break; case MapProvider.MapBox: mapProviderIn = "MapBox"; break; default: mapProviderIn = "Google"; break; } return Column( mainAxisSize: MainAxisSize.min, children: [ _buildAgendaHeader(size, mapProviderIn), if (agendaDTO.isOnlineAgenda == false) ...[ const Divider(height: 32), Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text("Évènements Manuels", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), ElevatedButton.icon( icon: const Icon(Icons.add), label: const Text("Ajouter un évènement"), onPressed: agendaDTO.id == null ? null : () { showNewOrUpdateEventAgenda( context, null, agendaDTO.id!, (newEvent) async { try { final created = await _api(context) .sectionAgendaCreateEventAgenda( agendaDTO.id!, newEvent); if (created != null && mounted) { setState(() => events.add(created)); showNotification(kSuccess, kWhite, 'Évènement créé avec succès', context, null); } } catch (e) { showNotification( kError, kWhite, 'Erreur lors de la création de l\'évènement', context, null); rethrow; } }, ); }, style: ElevatedButton.styleFrom( backgroundColor: kSuccess, foregroundColor: kWhite, padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), ), ), ], ), ), Container( height: 600, padding: const EdgeInsets.symmetric(vertical: 8), child: events.isEmpty ? const Center( child: Text("Aucun évènement manuel", style: TextStyle(fontStyle: FontStyle.italic))) : ListView.builder( itemCount: events.length, itemBuilder: (context, index) { final event = events[index]; return Card( elevation: 2, margin: const EdgeInsets.symmetric( horizontal: 16, vertical: 6), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12)), child: ListTile( contentPadding: const EdgeInsets.symmetric( horizontal: 16, vertical: 8), leading: CircleAvatar( backgroundColor: kPrimaryColor.withOpacity(0.1), child: const Icon(Icons.event, color: kPrimaryColor), ), title: HtmlWidget( (event.label != null && event.label!.isNotEmpty) ? (event.label!.firstWhere( (t) => t.language == 'FR', orElse: () => event.label![0])).value ?? "Évènement $index" : "Évènement $index", textStyle: const TextStyle(fontWeight: FontWeight.bold), ), subtitle: Padding( padding: const EdgeInsets.only(top: 4), child: Text(event.address?.address ?? "Pas d'adresse"), ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( icon: const Icon(Icons.edit, color: kPrimaryColor), onPressed: () { showNewOrUpdateEventAgenda( context, event, agendaDTO.id ?? "", (updatedEvent) async { try { final result = await _api(context) .sectionAgendaUpdateEventAgenda( updatedEvent); if (result != null && mounted) { setState( () => events[index] = result); showNotification( kSuccess, kWhite, 'Évènement mis à jour avec succès', context, null); } } catch (e) { showNotification( kError, kWhite, 'Erreur lors de la mise à jour de l\'évènement', context, null); rethrow; } }, ); }, ), IconButton( icon: const Icon(Icons.delete, color: kError), onPressed: () async { try { if (event.id != null) { await _api(context) .sectionAgendaDeleteEventAgenda( event.id!); } if (mounted) { setState(() => events.removeAt(index)); showNotification( kSuccess, kWhite, 'Évènement supprimé avec succès', context, null); } } catch (e) { showNotification( kError, kWhite, 'Erreur lors de la suppression de l\'évènement', context, null); } }, ), ], ), ), ); }, ), ), ], ], ); } Widget _buildAgendaHeader(Size size, String mapProviderIn) { return Container( padding: const EdgeInsets.all(16.0), margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.1), spreadRadius: 2, blurRadius: 5, offset: const Offset(0, 3), ), ], border: Border.all(color: kPrimaryColor.withOpacity(0.2)), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ CheckInputContainer( label: "En ligne :", isChecked: agendaDTO.isOnlineAgenda ?? true, onChanged: (value) { setState(() { agendaDTO.isOnlineAgenda = value; widget.onChanged(agendaDTO); }); }, ), SingleSelectContainer( label: "Service carte :", color: Colors.black, initialValue: mapProviderIn, inputValues: const ["Google", "MapBox"], onChanged: (String value) { setState(() { switch (value) { case "Google": agendaDTO.agendaMapProvider = MapProvider.Google; break; case "MapBox": agendaDTO.agendaMapProvider = MapProvider.MapBox; break; } widget.onChanged(agendaDTO); }); }, ), if (agendaDTO.isOnlineAgenda == true) MultiStringInputContainer( label: "Fichiers json :", resourceTypes: const [ResourceType.Json, ResourceType.JsonUrl], modalLabel: "JSON", color: kPrimaryColor, initialValue: agendaDTO.resourceIds ?? [], isTitle: false, onGetResult: (value) { setState(() { agendaDTO.resourceIds = value; widget.onChanged(agendaDTO); }); }, maxLines: 1, ), ], ), ); } }