import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; import '../services/auth_controller.dart'; class AuthFlow extends StatefulWidget { const AuthFlow({super.key}); @override State createState() => _AuthFlowState(); } class _AuthFlowState extends State { final _phone = TextEditingController(); final _password = TextEditingController(); bool _staff = false; bool _waiting = false; Timer? _poll; @override void dispose() { _poll?.cancel(); _phone.dispose(); _password.dispose(); super.dispose(); } Future _staffLogin() async { final auth = context.read(); try { await auth.staffLogin(_phone.text.trim(), _password.text); } catch (_) {} } Future _dealerLogin() async { final auth = context.read(); try { final started = await auth.startDealerLogin(_phone.text.trim()); if (!mounted) return; setState(() => _waiting = true); _poll = Timer.periodic( const Duration(seconds: 2), (_) => _check(started.requestId, started.secret), ); await _check(started.requestId, started.secret); } catch (_) {} } Future _check(String requestId, String secret) async { final auth = context.read(); try { final status = await auth.pollDealerLogin(requestId, secret); if (!mounted) return; if (status == 'pending') return; _poll?.cancel(); if (status != 'approved') setState(() => _waiting = false); } catch (_) { if (!mounted) return; _poll?.cancel(); setState(() => _waiting = false); } } void _cancelWait() { _poll?.cancel(); context.read().error = null; setState(() => _waiting = false); } @override Widget build(BuildContext context) { final auth = context.watch(); final theme = Theme.of(context); return Scaffold( body: SafeArea( child: Align( alignment: Alignment.topCenter, child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 440), child: ListView( padding: const EdgeInsets.fromLTRB(24, 48, 24, 24), children: [ Center( child: ClipRRect( borderRadius: BorderRadius.circular(8), child: Image.asset( 'assets/images/senaro_logo.png', width: 300, semanticLabel: 'Senaro', ), ), ), const SizedBox(height: 20), Text( 'Dealer Network', textAlign: TextAlign.center, style: theme.textTheme.headlineMedium, ), const SizedBox(height: 8), Text( _waiting ? 'Waiting for a sales rep or super admin to approve ${_phone.text.trim()}.' : _staff ? 'Staff sign in with the phone number and password on the account.' : 'Dealers sign in with the phone number already registered for the dealership.', style: theme.textTheme.bodyLarge, ), const SizedBox(height: 28), if (_waiting) const Center(child: CircularProgressIndicator()) else ...[ SegmentedButton( segments: const [ ButtonSegment(value: false, label: Text('Dealer')), ButtonSegment(value: true, label: Text('Staff')), ], selected: {_staff}, onSelectionChanged: auth.busy ? null : (value) => setState(() => _staff = value.first), ), const SizedBox(height: 16), TextField( controller: _phone, keyboardType: TextInputType.phone, inputFormatters: [FilteringTextInputFormatter.digitsOnly], decoration: const InputDecoration( labelText: 'Phone', hintText: '071xxxxxxx', ), onSubmitted: (_) => _staff ? _staffLogin() : _dealerLogin(), ), if (_staff) ...[ const SizedBox(height: 12), TextField( controller: _password, obscureText: true, decoration: const InputDecoration(labelText: 'Password'), onSubmitted: (_) => _staffLogin(), ), ], ], if (auth.error != null) ...[ const SizedBox(height: 12), Text( auth.error!, style: TextStyle(color: theme.colorScheme.error), ), ], const SizedBox(height: 20), if (_waiting) TextButton( onPressed: _cancelWait, child: const Text('Cancel'), ) else FilledButton( onPressed: auth.busy ? null : (_staff ? _staffLogin : _dealerLogin), child: Text( auth.busy ? 'Please wait' : (_staff ? 'Sign in' : 'Request login'), ), ), ], ), ), ), ), ); } }