feat: start of pending screen

This commit is contained in:
alzalia1 2025-08-14 00:27:39 +02:00
parent 019a21f00e
commit ee9c4c3801
12 changed files with 425 additions and 67 deletions

View file

@ -16,6 +16,26 @@ class BalViewModel extends ChangeNotifier {
int? id;
Bal? get bal => _bal;
Future<Result<void>> editBal(
int id,
String name,
DateTime start,
DateTime end,
) async {
final result = await _balRepository.editBal(id, name, start, end);
switch (result) {
case Ok():
debugPrint("\n\n\n\nDID EDIT\n\n\n\n");
_bal = result.value;
notifyListeners();
break;
case Error():
debugPrint("\n\n\n\nERROR: ${result.error}");
break;
}
return result;
}
/*
* =================================
* =====[ COMMAND AND LOADING ]=====

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:seshat/domain/models/bal.dart';
import 'package:seshat/ui/bal_page/view_model/bal_view_model.dart';
import 'package:seshat/ui/bal_page/widget/pending/bal_pending_screen.dart';
import 'package:seshat/ui/core/ui/navigation_bar.dart';
import 'package:seshat/ui/core/ui/await_loading.dart';
@ -16,26 +17,29 @@ class BalPage extends StatefulWidget {
class _BalPageState extends State<BalPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: AppNavigationBar(startIndex: 0),
body: ListenableBuilder(
listenable: widget.viewModel,
builder: (context, child) {
return switch (widget.viewModel.isLoaded) {
false => AwaitLoading(),
true => switch (widget.viewModel.bal == null) {
true => Center(
return ListenableBuilder(
listenable: widget.viewModel,
builder: (context, child) {
return switch (widget.viewModel.isLoaded) {
false => Scaffold(
bottomNavigationBar: AppNavigationBar(startIndex: 0),
body: AwaitLoading(),
),
true => switch (widget.viewModel.bal == null) {
true => Scaffold(
bottomNavigationBar: AppNavigationBar(startIndex: 0),
body: Center(
child: Text("La BAL référencée n'est pas accessible"),
),
false => switch (widget.viewModel.bal!.state) {
BalState.pending => Center(child: Text("Pending")),
BalState.ongoing => Center(child: Text("Ongoing")),
BalState.ended => Center(child: Text("Ending")),
},
),
false => switch (widget.viewModel.bal!.state) {
BalState.pending => BalPendingScreen(viewModel: widget.viewModel),
BalState.ongoing => Center(child: Text("Ongoing")),
BalState.ended => Center(child: Text("Ending")),
},
};
},
),
},
};
},
);
}
}

View file

@ -1,11 +1,191 @@
import 'package:flutter/material.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart';
import 'package:seshat/domain/models/bal.dart';
import 'package:seshat/ui/bal_page/view_model/bal_view_model.dart';
import 'package:seshat/ui/core/ui/navigation_bar.dart';
class BalPendingScreen extends StatelessWidget {
const BalPendingScreen({super.key});
const BalPendingScreen({super.key, required this.viewModel});
final BalViewModel viewModel;
@override
Widget build(BuildContext context) {
// TODO: implement build
throw UnimplementedError();
return Scaffold(
bottomNavigationBar: AppNavigationBar(startIndex: 0),
appBar: AppBar(
title: Text(viewModel.bal!.name),
actions: [
IconButton(
onPressed: () {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => EditPopup(viewModel: viewModel),
);
},
icon: Icon(Icons.edit),
),
],
),
body: Center(
child: ElevatedButton(
onPressed: () {},
child: Text("Démarrer cette BAL"),
),
),
);
}
}
class EditPopup extends StatefulWidget {
const EditPopup({super.key, required this.viewModel});
final BalViewModel viewModel;
@override
State<EditPopup> createState() => _EditPopup();
}
class _EditPopup extends State<EditPopup> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String? name;
DateTime? start;
Future<void> _selectStart() async {
final DateTime? pickedDate = await showDatePicker(
context: context,
initialDate: start ?? widget.viewModel.bal!.startTime,
firstDate: DateTime.now(),
lastDate: DateTime(DateTime.now().year + 2),
locale: Locale("fr", "FR"),
);
setState(() {
start = pickedDate;
});
}
DateTime? end;
Future<void> _selectEnd() async {
final DateTime? pickedDate = await showDatePicker(
context: context,
initialDate: end ?? widget.viewModel.bal!.endTime,
firstDate: DateTime.now(),
lastDate: DateTime(DateTime.now().year + 2),
locale: Locale("fr", "FR"),
);
setState(() {
end = pickedDate;
});
}
@override
Widget build(BuildContext context) {
initializeDateFormatting();
var format = DateFormat("dd MMM yyyy", "fr");
return AlertDialog(
title: Text("Créer une BAL"),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
decoration: InputDecoration(
labelText: "Nom de la BAL",
border: OutlineInputBorder(),
),
initialValue: widget.viewModel.bal!.name,
validator: (value) {
if (value == null || value.isEmpty) {
return "Veuillez entrer un nom";
}
return null;
},
onSaved: (newValue) {
name = newValue;
},
),
Row(
children: [
Text("Date de début : "),
TextButton(
onPressed: () {
_selectStart();
},
child: Text(
format.format(start ?? widget.viewModel.bal!.startTime),
locale: Locale("fr"),
),
),
],
),
Row(
children: [
Text("Date de fin : "),
TextButton(
onPressed: () {
_selectEnd();
},
child: Text(
format.format(end ?? widget.viewModel.bal!.endTime),
),
),
],
),
Text("Note: Les dates sont à titre purement indicatif."),
],
),
),
],
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text("Annuler"),
),
TextButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
final Bal bal = widget.viewModel.bal!;
final result = await widget.viewModel.editBal(
bal.id,
name ?? bal.name,
start ?? bal.startTime,
end ?? bal.endTime,
);
if (result is Error && context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Une erreur est survenue")),
);
}
if (context.mounted) {
Navigator.of(context).pop();
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
"Veuillez indiquer une date de début et de fin.",
),
),
);
}
},
child: Text("Valider"),
),
],
);
}
}