This repository has been archived on 2025-08-25. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
Seshat/lib/ui/sell_page/widgets/sell_page.dart
2025-08-20 13:21:05 +02:00

219 lines
9.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:seshat/domain/models/book_stack.dart';
import 'package:seshat/routing/routes.dart';
import 'package:seshat/ui/core/ui/navigation_bar.dart';
import 'package:seshat/ui/sell_page/view_model/sell_view_model.dart';
import 'package:seshat/ui/sell_page/widgets/scan_screen.dart';
import 'package:seshat/ui/core/ui/await_loading.dart';
class SellPage extends StatefulWidget {
const SellPage({super.key, required this.viewModel});
final SellViewModel viewModel;
@override
State<SellPage> createState() => _SellPageState();
}
class _SellPageState extends State<SellPage> {
TextEditingController price = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: AppNavigationBar(startIndex: 2),
body: ListenableBuilder(
listenable: widget.viewModel,
builder: (context, child) {
return switch (widget.viewModel.isLoaded) {
false => AwaitLoading(),
true => switch (widget.viewModel.currentBal) {
null => Center(
child: SizedBox(
width: 300,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"Aucune bal n'est active.",
style: TextStyle(fontSize: 25),
textAlign: TextAlign.center,
),
SizedBox(height: 15),
Text(
"Vous devez créer puis activer une BAL pour pouvoir scanner des livres.",
textAlign: TextAlign.center,
),
SizedBox(height: 30),
ElevatedButton(
onPressed: () {
context.go(Routes.home);
},
child: Text("Gérer les BALs"),
),
],
),
),
),
_ => Stack(
children: [
SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Center(
child: Text(
"Livres dans la vente actuelle",
style: TextStyle(fontSize: 20),
),
),
SizedBox(height: 15),
Expanded(
child: (widget.viewModel.isSendingSell)
? Center(child: CircularProgressIndicator())
: ListView(
children: [
(widget.viewModel.scannedBooks.isEmpty)
? Center(child: Text("Aucun"))
: SizedBox(),
for (BookStack book
in widget.viewModel.soldBooks)
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 15,
),
child: Card(
child: ListTile(
leading: Text(
"${book.instance.price.toString()}",
style: TextStyle(fontSize: 30),
),
title: Text(
"${book.book.title} · ${book.book.author}",
),
subtitle: Text(
"${book.owner.firstName} ${book.owner.lastName} (${book.shortId()})",
),
trailing: IconButton(
onPressed: () {
widget.viewModel.deleteBook(
book.instance.id,
);
},
icon: Icon(Icons.delete),
),
),
),
),
],
),
),
SizedBox(height: 40),
Text(
"Montant minimum à payer : ${widget.viewModel.minimumAmount.toString()}",
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 60.0),
child: SizedBox(
child: TextField(
controller: price,
decoration: InputDecoration(
labelText: "Argent reçu",
helperText:
"L'argent reçu sera réparti automatiquement.",
suffixText: "",
border: OutlineInputBorder(),
),
keyboardType: TextInputType.numberWithOptions(
decimal: true,
),
),
),
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
onPressed: () {
if (double.tryParse(
price.text.replaceFirst(",", "."),
) ==
null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
"Veuillez indiquer un prix de vente valide",
),
behavior: SnackBarBehavior.floating,
),
);
return;
} else if (double.parse(
price.text.replaceFirst(",", "."),
) <
widget.viewModel.minimumAmount) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
"Le prix de vente est inférieur au montant minimum",
),
behavior: SnackBarBehavior.floating,
),
);
return;
}
widget.viewModel.sendSell(
double.parse(
price.text.replaceFirst(",", "."),
),
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
"La vente a bien été enregistrée.",
),
behavior: SnackBarBehavior.floating,
),
);
price.clear();
return;
},
icon: Icon(Icons.check),
style: ButtonStyle(
iconSize: WidgetStatePropertyAll(70),
),
),
SizedBox(width: 70),
IconButton(
onPressed: () {
widget.viewModel.showScan = true;
},
icon: Icon(Icons.add),
style: ButtonStyle(
iconSize: WidgetStatePropertyAll(70),
elevation: WidgetStatePropertyAll(50),
),
),
],
),
SizedBox(height: 5),
],
),
),
(widget.viewModel.showScan)
? ScanScreen(viewModel: widget.viewModel)
: SizedBox(),
],
),
},
};
},
),
);
// return Center(child: Text("Sell page."));
}
}