import 'package:cdb_ui/api.dart'; import 'package:flutter/material.dart'; import 'package:qr_bar_code_scanner_dialog/qr_bar_code_scanner_dialog.dart'; class SupplyPage extends StatefulWidget { final Item item; final Function refresh; const SupplyPage(this.item, this.refresh, {super.key}); @override State createState() => _SupplyPageState(); } class _SupplyPageState extends State { late String variant; final _formKey = GlobalKey(); String _selectedOrigin = ""; String _selectedLocation = ""; late TextEditingController _priceController; late TextEditingController _noteController; @override void initState() { super.initState(); variant = widget.item.variants.keys.first; _priceController = TextEditingController(text: ""); _noteController = TextEditingController(text: ""); } void _supply() { if (_formKey.currentState!.validate()) { _formKey.currentState!.save(); API() .supplyItem(widget.item.id, variant, "${_priceController.text} €", _selectedOrigin, _selectedLocation, _noteController.text) .then((_) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Item added successfully!')), ); Navigator.of(context).pop(); widget.refresh(); }); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Add New Item'), ), body: FutureBuilder( future: _fetchData(), builder: (context, snapshot) { if (!snapshot.hasData) { return const Center(child: CircularProgressIndicator()); } var data = snapshot.data as Map; var locations = data['locations']! as Map; var origins = data['origins']! as List; return Padding( padding: const EdgeInsets.all(16.0), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Variant Selection DropdownButtonFormField( hint: const Text('Select Variant'), value: variant, onChanged: (value) { setState(() { variant = value!; }); }, items: widget.item.variants.entries.map((entry) { return DropdownMenuItem( value: entry.key, child: Text(entry.value.name), ); }).toList(), onSaved: (value) { variant = value!; }, ), const SizedBox(height: 16), // Origin Field with Dropdown and Text Input AutocompletedTextField( options: origins, getValue: () => _selectedOrigin, onChanged: (value) { _selectedOrigin = value; }, onSelection: (String selection) async { var price = _priceController.text.isEmpty ? await API() .getLatestPrice(widget.item.id, variant, origin: selection) .then((x) => x.value.toStringAsFixed(2)) : _priceController.text; setState(() { _priceController.text = price; _selectedOrigin = selection; }); }, label: "Origin"), const SizedBox(height: 16), // Price Field TextFormField( decoration: const InputDecoration(labelText: 'Price'), keyboardType: TextInputType.number, controller: _priceController, validator: (value) { if (value == null || value.isEmpty) { return 'Please enter a price'; } if (double.tryParse(value) == null) { return 'Please enter a valid number'; } return null; }, ), const SizedBox(height: 16), // Location Dropdown Row( children: [ Expanded( child: DropdownButtonFormField( hint: const Text('Select Location'), value: _selectedLocation, onChanged: (value) { setState(() { _selectedLocation = value!; }); }, items: locations.keys .map>((id) { return DropdownMenuItem( value: id, child: Text(locations[id]!.fullNamePath(locations)), ); }).toList(), onSaved: (value) { _selectedLocation = value!; }, ), ), const SizedBox( width: 12, ), IconButton( onPressed: () { QrBarCodeScannerDialog().getScannedQrBarCode( context: context, onCode: (code) { setState(() { _selectedLocation = code!; }); }, ); }, icon: const Icon(Icons.qr_code), ), ], ), // Note TextFormField( decoration: const InputDecoration(labelText: 'Note'), controller: _noteController, maxLines: 5), const SizedBox(height: 20), // Submit Button ElevatedButton( onPressed: _supply, child: const Text('Add Item'), ), ], ), ), ); }, ), ); } Future> _fetchData() async { var locations = await API().getLocations(); var origins = await API().getUniqueField(widget.item.id, variant, "origin"); origins.insert(0, ""); locations[""] = Location.zero(); return {'locations': locations, 'origins': origins}; } } // ignore: must_be_immutable class AutocompletedTextField extends StatelessWidget { late List options; late Function(String) onChanged; late String Function() getValue; late Function(String) onSelection; late String label; AutocompletedTextField( {super.key, required this.options, required this.getValue, required this.onChanged, required this.onSelection, required this.label}); @override Widget build(BuildContext context) { return Autocomplete( optionsBuilder: (TextEditingValue textEditingValue) { if (textEditingValue.text.isEmpty) { return options; } return options.where((String option) { return option .toLowerCase() .contains(textEditingValue.text.toLowerCase()); }); }, onSelected: onSelection, fieldViewBuilder: (context, textEditingController, focusNode, onFieldSubmitted) { textEditingController.text = getValue(); return TextFormField( onChanged: onChanged, controller: textEditingController, focusNode: focusNode, decoration: InputDecoration( labelText: label, border: const OutlineInputBorder(), ), ); }, ); } }