import 'package:fcs/domain/entities/user.dart'; import 'package:fcs/domain/vo/privilege.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:fcs/localization/app_translations.dart'; import 'package:fcs/pages/main/model/language_model.dart'; import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/staff/model/staff_model.dart'; import 'package:fcs/pages/widgets/display_text.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart'; import 'package:fcs/pages/widgets/progress.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; typedef void FindCallBack(); class StaffEditor extends StatefulWidget { final User? staff; const StaffEditor({this.staff}); @override _StaffEditorState createState() => _StaffEditorState(); } class _StaffEditorState extends State { TextEditingController _phoneInput = new TextEditingController(); bool _isLoading = false; late User user; User? selectedUser; List privileges = []; bool isNew = true; @override void initState() { super.initState(); privileges = Provider.of(context, listen: false).privileges; isNew = widget.staff == null; user = User(); if (!isNew) { user = User( name: widget.staff!.name, phoneNumber: widget.staff!.phoneNumber); user.privileges = widget.staff!.privileges; privileges.forEach((p) => user.privileges.contains(p.id) ? p.isChecked = true : p.isChecked = false); } else { user.name = ""; user.phoneNumber = ""; privileges.forEach((p) => p.isChecked = false); } } List showprivilegeList(BuildContext context) { return privileges.map((p) { return new ListTile( title: InkWell( onTap: () { setState(() { p.isChecked = p.isChecked == null ? true : !p.isChecked!; }); }, child: new Row( children: [ new Checkbox( value: p.isChecked == null ? false : p.isChecked, activeColor: primaryColor, side: BorderSide(color: Colors.black38, width: 2), onChanged: (bool? value) { if (value != null) setState(() { p.isChecked = value; }); }), Padding( padding: const EdgeInsets.only(right: 8.0), child: Icon(p.iconData, size: 50, color: Colors.black38), ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ new Text( p.name ?? "", style: TextStyle(fontSize: 15.0, color: primaryColor), ), Text(p.desc ?? "", style: TextStyle(fontSize: 13, color: Colors.grey[600])) ], ), ), ], ), )); }).toList(); } Widget phoneSearchbox(BuildContext context, FindCallBack findCallBack) { var languageModel = Provider.of(context); return Container( padding: EdgeInsets.only( bottom: 25, left: 8, ), child: Stack( alignment: const Alignment(1, 1.0), children: [ TextFormField( controller: _phoneInput, autofocus: false, cursorColor: primaryColor, keyboardType: TextInputType.phone, style: textStyle, decoration: new InputDecoration( labelText: AppTranslations.of(context)!.text('staff.phone.search'), labelStyle: languageModel.isEng ? labelStyle : labelStyleMM, // icon: Icon( // Icons.search, // color: primaryColor, // ), enabledBorder: UnderlineInputBorder( borderSide: BorderSide(color: primaryColor, width: 1.0)), focusedBorder: UnderlineInputBorder( borderSide: BorderSide(color: primaryColor, width: 1.0)), ), ), new IconButton( onPressed: () { findCallBack(); }, icon: new Icon(Icons.search, size: 25, color: primaryColor)) ], )); } @override Widget build(BuildContext context) { final namebox = DisplayText( text: user.name, labelTextKey: "customer.name", iconData: Icons.person, ); var phoneNumberBox = Row( children: [ Expanded( child: DisplayText( text: user.phoneNumber, labelTextKey: "customer.phone", iconData: Icons.phone, )), isNew ? Container() : IconButton( icon: Icon(Icons.open_in_new, color: primaryColor), onPressed: () => call(context, user.phoneNumber!)), ], ); final updateButton = fcsButton( context, getLocalString(context, 'staff.update'), callack: _save, ); final addButton = fcsButton( context, getLocalString(context, 'staff.add'), callack: _add, ); return LocalProgress( inAsyncCall: _isLoading, child: Scaffold( appBar: LocalAppBar( labelKey: "staff.form.title", backgroundColor: Colors.white, labelColor: primaryColor, arrowColor: primaryColor), body: Padding( padding: const EdgeInsets.only(left: 12.0, right: 12), child: ListView( children: [ isNew ? phoneSearchbox(context, () => _findUser(context)) : Container(), phoneNumberBox, namebox, Padding( padding: const EdgeInsets.only(top: 18.0), child: Text("Privileges", style: TextStyle(fontSize: 15)), ), Column( children: showprivilegeList(context), ), SizedBox( height: 10, ), Container( child: isNew ? addButton : updateButton, ), SizedBox( height: 10, ) ], ), ), )); } _add() async { if (isNew && selectedUser == null) { showMsgDialog(context, "Error", "Invalid user!"); return; } setState(() { _isLoading = true; }); StaffModel staffModel = Provider.of(context, listen: false); try { await staffModel.updatePrivileges( this.selectedUser!.id!, privilegesIDs()); Navigator.pop(context); } catch (e) { showMsgDialog(context, "Error", e.toString()); } finally { setState(() { _isLoading = false; }); } } List privilegesIDs() { return this.privileges.where((p) => p.isChecked!).map((p) => p.id).toList(); } _save() async { setState(() { _isLoading = true; }); if (widget.staff == null) return; StaffModel staffModel = Provider.of(context, listen: false); try { await staffModel.updatePrivileges(widget.staff!.id!, privilegesIDs()); Navigator.pop(context); } catch (e) { showMsgDialog(context, "Error", e.toString()); } finally { setState(() { _isLoading = false; }); } } _findUser(BuildContext context) async { StaffModel staffModel = Provider.of(context, listen: false); if (_phoneInput.text == "") return; setState(() { _isLoading = true; }); try { User? _user = await staffModel.findUser(_phoneInput.text); if (_user == null) { showMsgDialog(context, "Error", _phoneInput.text + " not found!"); return; } this.selectedUser = _user; this.user = _user; setState(() { if (user.privileges.isNotEmpty) { privileges.forEach((p) => user.privileges.contains(p.id) ? p.isChecked = true : p.isChecked = false); } }); } catch (e) { showMsgDialog(context, "Error", e.toString()); } finally { setState(() { _isLoading = false; }); } } }