actions-test/lib/screens/room/items/edit.dart

263 lines
9.3 KiB
Dart
Raw Normal View History

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:outbag_app/backend/request.dart';
import 'package:outbag_app/backend/room.dart';
import 'package:outbag_app/backend/user.dart';
import 'package:outbag_app/components/category_picker.dart';
import 'package:outbag_app/components/product_picker.dart';
import 'package:outbag_app/components/value_unit_input.dart';
import 'package:outbag_app/tools/fetch_wrapper.dart';
import 'package:outbag_app/tools/snackbar.dart';
import 'package:provider/provider.dart';
class EditItemPage extends StatefulWidget {
final String room;
final String server;
final int item;
const EditItemPage(
{super.key,
required this.room,
required this.server,
required this.item});
@override
State<StatefulWidget> createState() => _EditItemPageState();
}
class _EditItemPageState extends State<EditItemPage> {
// input controllers
final _ctrName = TextEditingController();
final _ctrDescription = TextEditingController();
int? _ctrCategory;
int _ctrUnit = 0;
String _ctrValue = '';
int? _ctrLink;
int _ctrState = 0;
// data cache
List<RoomCategory> categories = [];
List<RoomProduct> products = [];
RoomItem? item;
void fetchCategories() {
final user = context.read<User>();
// TODO: load cached categories first
doNetworkRequest(ScaffoldMessenger.of(context),
2023-12-22 20:14:36 +01:00
req: () => postWithCreadentials(
credentials: user,
target: user.server,
path: 'getCategories',
body: {'room': widget.room, 'server': widget.server}),
onOK: (body) async {
final resp = body['data']
.map<RoomCategory>((raw) => RoomCategory.fromJSON(raw))
.toList();
2023-12-22 20:14:36 +01:00
setState(() {
categories = resp;
2023-12-22 20:14:36 +01:00
});
});
}
void fetchProducts() {
final user = context.read<User>();
// TODO: load cached products first
doNetworkRequest(ScaffoldMessenger.of(context),
2023-12-22 20:14:36 +01:00
req: () => postWithCreadentials(
credentials: user,
target: user.server,
path: 'getProducts',
body: {'room': widget.room, 'server': widget.server}),
onOK: (body) async {
final resp = body['data']
.map<RoomProduct>((raw) => RoomProduct.fromJSON(raw))
.toList();
2023-12-22 20:14:36 +01:00
setState(() {
products = resp;
2023-12-22 20:14:36 +01:00
});
});
}
void fetchItem() {
final user = context.read<User>();
// TODO: load cached item first
doNetworkRequest(ScaffoldMessenger.of(context),
2023-12-22 20:14:36 +01:00
req: () => postWithCreadentials(
credentials: user,
target: user.server,
path: 'getItem',
body: {
'room': widget.room,
'server': widget.server,
'listItemID': widget.item
}),
onOK: (body) async {
final resp = RoomItem.fromJSON(body['data']);
setState(() {
item = resp;
_ctrName.text = resp.name;
_ctrDescription.text = resp.description;
_ctrValue = resp.value;
_ctrCategory = resp.category;
_ctrLink = resp.link;
_ctrUnit = resp.unit;
_ctrState = resp.state;
2023-12-22 20:14:36 +01:00
});
});
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
2023-12-22 20:14:36 +01:00
fetchCategories();
fetchProducts();
fetchItem();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context)!.editItem),
),
body: SingleChildScrollView(
2023-12-22 20:14:36 +01:00
child: Center(
child: Padding(
padding: const EdgeInsets.all(14),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 400),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8),
child: TextField(
controller: _ctrName,
keyboardType: TextInputType.name,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.badge),
labelText: AppLocalizations.of(context)!
.inputItemNameLabel,
hintText: AppLocalizations.of(context)!
.inputItemNameHint,
helperText: AppLocalizations.of(context)!
.inputItemNameHelp,
border: const OutlineInputBorder(),
),
),
),
ProductPicker(
label: AppLocalizations.of(context)!
.selectLinkedProductLabel,
hint: AppLocalizations.of(context)!
.selectLinkedProductHint,
products: products,
selected: _ctrLink,
onSelect: (pid) {
setState(() {
_ctrLink = pid;
});
},
),
Padding(
padding: const EdgeInsets.all(8),
child: TextField(
controller: _ctrDescription,
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: AppLocalizations.of(context)!
.inputItemDescriptionLabel,
hintText: AppLocalizations.of(context)!
.inputItemDescriptionHint,
helperText: AppLocalizations.of(context)!
.inputItemDescriptionHelp,
prefixIcon: const Icon(Icons.dns),
border: const OutlineInputBorder(),
),
),
),
DynamicValueUnitInput(
initialUnit: _ctrUnit,
initialValue: _ctrValue,
onUnitChange: (unit) {
setState(() {
_ctrUnit = unit;
});
},
onValueChange: (value) {
setState(() {
_ctrValue = value;
});
},
),
CategoryPicker(
label: AppLocalizations.of(context)!
.selectCategoryLabel,
hint: AppLocalizations.of(context)!
.selectCategoryHint,
categories: categories,
selected: _ctrCategory,
onSelect: (cid) {
setState(() {
_ctrCategory = cid;
});
},
),
],
))))),
floatingActionButton: FloatingActionButton.extended(
2023-12-22 20:14:36 +01:00
onPressed: () async {
final scaffMgr = ScaffoldMessenger.of(context);
final trans = AppLocalizations.of(context);
final nav = Navigator.of(context);
2023-12-22 20:14:36 +01:00
if (_ctrName.text.isEmpty) {
showSimpleSnackbar(scaffMgr,
text: trans!.errorProductNameShouldNotBeEmpty,
action: trans.ok);
return;
}
2023-12-22 20:14:36 +01:00
final user = context.read<User>();
doNetworkRequest(scaffMgr,
req: () => postWithCreadentials(
credentials: user,
target: user.server,
path: 'changeItem',
body: {
'listItemID': widget.item,
'room': widget.room,
'server': widget.server,
'title': _ctrName.text,
'state': _ctrState,
'description': _ctrDescription.text,
'listCatID': _ctrCategory,
'unit': _ctrUnit,
'value': _ctrValue,
'listProdID': _ctrLink
}),
onOK: (_) async {
nav.pop();
});
2023-12-22 20:14:36 +01:00
},
label: Text(AppLocalizations.of(context)!.editItemShort),
icon: const Icon(Icons.edit)),
);
}
}