import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../core/providers.dart'; import '../../widgets/ui.dart'; import 'shop_picker.dart'; import '../../core/theme.dart'; const _maxW = 640.0; class UserFormScreen extends ConsumerStatefulWidget { const UserFormScreen({super.key}); @override ConsumerState createState() => _UserFormScreenState(); } class _UserFormScreenState extends ConsumerState { final _name = TextEditingController(); final _phone = TextEditingController(); final _pass = TextEditingController(); final _shops = {}; bool _busy = false; String? _error; @override void dispose() { _name.dispose(); _phone.dispose(); _pass.dispose(); super.dispose(); } bool get _ready => _name.text.trim().length >= 3 && _pass.text.length >= 8; Future _create() async { setState(() { _busy = true; _error = null; }); try { await mutate( ref, () => ref .read(apiProvider) .createUser( username: _name.text, phone: _phone.text.trim().isEmpty ? null : _phone.text, password: _pass.text, shopIds: _shops.toList(), ), ); if (!mounted) return; context.pop(); toast(context, 'User created'); } catch (e) { if (mounted) setState(() => _error = errText(e)); } finally { if (mounted) setState(() => _busy = false); } } @override Widget build(BuildContext context) { final shops = ref.watch(activeShopsProvider); return Scaffold( body: SafeArea( child: Column( children: [ const ScreenHeader(title: 'Add user', back: true, maxWidth: _maxW), Expanded( child: PageList( maxWidth: _maxW, top: S.s8, children: [ SrsField( controller: _name, label: 'Username', hint: 'e.g. kzk.staff', helper: 'Letters, numbers, dots, dashes and underscores. Used to sign in.', onChanged: (_) => setState(() => _error = null), ), const SizedBox(height: S.s18), SrsField( controller: _phone, label: 'Phone (optional)', hint: '90000 12345', prefix: '+91 ', keyboard: TextInputType.phone, formatters: [ FilteringTextInputFormatter.allow(RegExp(r'[0-9 ]')), LengthLimitingTextInputFormatter(12), ], onChanged: (_) => setState(() => _error = null), ), const SizedBox(height: S.s18), SrsField( controller: _pass, label: 'Password', hint: 'Enter password', password: true, helper: 'At least 8 characters.', onChanged: (_) => setState(() => _error = null), ), const SectionTitle('Shop access'), asyncView( shops, (list) => ShopPicker( shops: list, selected: _shops, onToggle: (id) => setState( () => _shops.contains(id) ? _shops.remove(id) : _shops.add(id), ), ), ), if (_error != null) ...[ const SizedBox(height: S.s8), ErrorLine(_error!), ], const SizedBox(height: S.s22), BigButton( 'Create user', loading: _busy, onPressed: _ready ? _create : null, ), ], ), ), ], ), ), ); } }