375 lines
16 KiB
Dart

import 'package:flutter/material.dart';
import 'package:manager_api_new/api.dart';
import 'package:manager_app/constants.dart';
import 'package:intl/intl.dart';
import 'showNewOrUpdateProgrammeBlock.dart';
import 'package:provider/provider.dart';
import 'package:manager_app/app_context.dart';
import 'package:manager_app/Models/managerContext.dart';
import 'package:manager_app/Components/message_notification.dart';
class EventConfig extends StatefulWidget {
final SectionEventDTO initialValue;
final ValueChanged<SectionEventDTO> onChanged;
const EventConfig({
Key? key,
required this.initialValue,
required this.onChanged,
}) : super(key: key);
@override
_EventConfigState createState() => _EventConfigState();
}
class _EventConfigState extends State<EventConfig> {
late SectionEventDTO eventDTO;
@override
void initState() {
super.initState();
eventDTO = widget.initialValue;
WidgetsBinding.instance.addPostFrameCallback((_) => _loadProgrammeBlocks());
}
Future<void> _loadProgrammeBlocks() async {
if (eventDTO.id == null || !mounted) return;
final appContext = Provider.of<AppContext>(context, listen: false);
final api = (appContext.getContext() as ManagerAppContext).clientAPI!.sectionEventApi!;
try {
final blocks = await api.sectionEventGetAllProgrammeBlockFromSection(eventDTO.id!);
if (blocks == null || !mounted) return;
setState(() {
eventDTO.programme = blocks;
});
} catch (e) {
// Silently keep initial value on error
}
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
children: [
Expanded(
child: ListTile(
title: Text("Date de début"),
subtitle: Text(eventDTO.startDate != null
? DateFormat('dd/MM/yyyy HH:mm')
.format(eventDTO.startDate!.toLocal())
: "Non définie"),
trailing: Icon(Icons.calendar_today),
onTap: () async {
DateTime initialDate = eventDTO.startDate?.toLocal() ?? DateTime.now();
if (initialDate.isBefore(DateTime(2000))) {
initialDate = DateTime.now();
}
DateTime? picked = await showDatePicker(
context: context,
initialDate: initialDate,
firstDate: DateTime(2000),
lastDate: DateTime(2100),
builder: (context, child) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: ColorScheme.light(
primary: kPrimaryColor,
onPrimary: kWhite,
onSurface: kSecond,
),
),
child: child!,
);
},
);
if (picked != null) {
TimeOfDay? time = await showTimePicker(
context: context,
initialTime: TimeOfDay.fromDateTime(
eventDTO.startDate?.toLocal() ?? DateTime.now()),
builder: (context, child) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: ColorScheme.light(
primary: kPrimaryColor,
onPrimary: kWhite,
onSurface: kSecond,
),
),
child: child!,
);
},
);
if (time != null) {
setState(() {
eventDTO.startDate = DateTime(picked.year,
picked.month, picked.day, time.hour, time.minute);
widget.onChanged(eventDTO);
});
}
}
},
),
),
Expanded(
child: ListTile(
title: Text("Date de fin"),
subtitle: Text(eventDTO.endDate != null
? DateFormat('dd/MM/yyyy HH:mm').format(eventDTO.endDate!.toLocal())
: "Non définie"),
trailing: Icon(Icons.calendar_today),
onTap: () async {
DateTime initialDate = eventDTO.endDate?.toLocal() ??
DateTime.now().add(Duration(days: 1));
if (initialDate.isBefore(DateTime(2000))) {
initialDate = DateTime.now().add(Duration(days: 1));
}
DateTime? picked = await showDatePicker(
context: context,
initialDate: initialDate,
firstDate: DateTime(2000),
lastDate: DateTime(2100),
builder: (context, child) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: ColorScheme.light(
primary: kPrimaryColor,
onPrimary: kWhite,
onSurface: kSecond,
),
),
child: child!,
);
},
);
if (picked != null) {
TimeOfDay? time = await showTimePicker(
context: context,
initialTime: TimeOfDay.fromDateTime(eventDTO.endDate?.toLocal() ??
DateTime.now().add(Duration(days: 1))),
builder: (context, child) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: ColorScheme.light(
primary: kPrimaryColor,
onPrimary: kWhite,
onSurface: kSecond,
),
),
child: child!,
);
},
);
if (time != null) {
setState(() {
eventDTO.endDate = DateTime(picked.year, picked.month,
picked.day, time.hour, time.minute);
widget.onChanged(eventDTO);
});
}
}
},
),
),
],
),
),
Divider(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Programme",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
ElevatedButton.icon(
icon: Icon(Icons.add),
label: Text("Ajouter un bloc"),
onPressed: () {
final appContext =
Provider.of<AppContext>(context, listen: false);
showNewOrUpdateProgrammeBlock(
context,
null,
(newBlock) async {
try {
// The API expects ProgrammeBlockDTO, while eventDTO.programme is List<ProgrammeBlock>
// Usually they are structural equivalents in these generated APIs, but let's be safe.
final programmeBlockDTO =
ProgrammeBlockDTO.fromJson(newBlock.toJson());
if (programmeBlockDTO == null) return;
final createdBlockDTO =
await (appContext.getContext() as ManagerAppContext)
.clientAPI!
.sectionEventApi!
.sectionEventCreateProgrammeBlock(
eventDTO.id!, programmeBlockDTO);
if (createdBlockDTO != null) {
// Convert back if necessary
final createdBlock =
ProgrammeBlock.fromJson(createdBlockDTO.toJson());
if (createdBlock != null) {
setState(() {
eventDTO.programme = [
...(eventDTO.programme ?? []),
createdBlock
];
widget.onChanged(eventDTO);
});
showNotification(
kSuccess,
kWhite,
'Bloc de programme créé avec succès',
context,
null);
}
}
} catch (e) {
showNotification(
kError,
kWhite,
'Erreur lors de la création du bloc',
context,
null);
}
},
);
},
style: ElevatedButton.styleFrom(
backgroundColor: kSuccess, foregroundColor: kWhite),
),
],
),
),
Expanded(
child: (eventDTO.programme == null || eventDTO.programme!.isEmpty)
? Center(
child: Text("Aucun bloc de programme défini",
style: TextStyle(fontStyle: FontStyle.italic)))
: ListView.builder(
itemCount: eventDTO.programme!.length,
itemBuilder: (context, index) {
final block = eventDTO.programme![index];
return Card(
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 4),
child: ListTile(
title: Text(
block.title != null && block.title!.isNotEmpty
? block.title!
.firstWhere((t) => t.language == 'FR',
orElse: () => block.title![0])
.value ??
"Bloc ${index + 1}"
: "Bloc ${index + 1}"),
subtitle: Text(
"${block.startTime != null ? DateFormat('HH:mm').format(block.startTime!) : '??'} - ${block.endTime != null ? DateFormat('HH:mm').format(block.endTime!) : '??'}"),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(Icons.edit, color: kPrimaryColor),
onPressed: () {
final appContext = Provider.of<AppContext>(
context,
listen: false);
showNewOrUpdateProgrammeBlock(
context,
block,
(updatedBlock) async {
try {
final programmeBlockDTO =
ProgrammeBlockDTO.fromJson(
updatedBlock.toJson());
if (programmeBlockDTO == null) return;
final resultDTO =
await (appContext.getContext()
as ManagerAppContext)
.clientAPI!
.sectionEventApi!
.sectionEventUpdateProgrammeBlock(
programmeBlockDTO);
if (resultDTO != null) {
final result = ProgrammeBlock.fromJson(
resultDTO.toJson());
if (result != null) {
setState(() {
eventDTO.programme![index] = result;
widget.onChanged(eventDTO);
});
showNotification(
kSuccess,
kWhite,
'Bloc mis à jour avec succès',
context,
null);
}
}
} catch (e) {
showNotification(
kError,
kWhite,
'Erreur lors de la mise à jour du bloc',
context,
null);
}
},
);
},
),
IconButton(
icon: Icon(Icons.delete, color: kError),
onPressed: () async {
final appContext = Provider.of<AppContext>(
context,
listen: false);
try {
if (block.id != null) {
await (appContext.getContext()
as ManagerAppContext)
.clientAPI!
.sectionEventApi!
.sectionEventDeleteProgrammeBlock(
block.id!);
}
setState(() {
eventDTO.programme!.removeAt(index);
widget.onChanged(eventDTO);
});
showNotification(
kSuccess,
kWhite,
'Bloc supprimé avec succès',
context,
null);
} catch (e) {
showNotification(
kError,
kWhite,
'Erreur lors de la suppression du bloc',
context,
null);
}
},
),
],
),
),
);
},
),
),
],
);
}
}