import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../config/app_config.dart'; import '../../core/network/api_exception.dart'; import 'auth_provider.dart'; class LoginScreen extends ConsumerStatefulWidget { const LoginScreen({super.key}); @override ConsumerState createState() => _LoginScreenState(); } class _LoginScreenState extends ConsumerState { final _idController = TextEditingController(); final _passwordController = TextEditingController(); final _formKey = GlobalKey(); bool _isLoading = false; void _handleLogin() async { if (!_formKey.currentState!.validate()) return; final id = _idController.text.trim(); final pwd = _passwordController.text.trim(); setState(() => _isLoading = true); try { await ref.read(authProvider.notifier).login(id, pwd); if (mounted) { context.go('/camera'); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( ApiException.from(e).displayMessage, style: const TextStyle(color: Colors.white), ), backgroundColor: AppConfig.errorColor, ), ); } } finally { if (mounted) { setState(() => _isLoading = false); } } } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Center( child: SingleChildScrollView( padding: const EdgeInsets.symmetric( horizontal: AppConfig.spaceXXL, vertical: AppConfig.spaceXL, ), child: Form( key: _formKey, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Image.asset( 'assets/logo.png', width: 120, height: 120, errorBuilder: (context, error, stackTrace) => const Icon( Icons.storefront, size: 80, color: AppConfig.primaryColor ), ), const SizedBox(height: AppConfig.spaceXL), Text( 'Selamat Datang Kembali', style: AppConfig.h1, textAlign: TextAlign.center, ), const SizedBox(height: AppConfig.spaceSmall), Text( 'Masuk untuk menyinkronkan dokumen Anda ke server pusat', style: AppConfig.bodyMedium, textAlign: TextAlign.center, ), const SizedBox(height: AppConfig.spaceXXL * 1.5), TextFormField( controller: _idController, decoration: const InputDecoration( labelText: 'ID dari Admin', prefixIcon: Icon(Icons.person_outline), ), validator: (value) { if (value == null || value.trim().isEmpty) { return 'Username/ID tidak boleh kosong'; } return null; }, ), const SizedBox(height: AppConfig.spaceLarge), TextFormField( controller: _passwordController, obscureText: true, decoration: const InputDecoration( labelText: 'Kata Sandi', prefixIcon: Icon(Icons.lock_outline), ), validator: (value) { if (value == null || value.trim().isEmpty) { return 'Kata sandi tidak boleh kosong'; } if (value.trim().length < 6) { return 'Kata sandi minimal 6 karakter'; } return null; }, ), const SizedBox(height: AppConfig.spaceXXL), SizedBox( height: 56, child: ElevatedButton( onPressed: _isLoading ? null : _handleLogin, child: _isLoading ? const SizedBox( width: 24, height: 24, child: CircularProgressIndicator(color: Colors.white, strokeWidth: 3) ) : const Text('Masuk'), ), ), const SizedBox(height: AppConfig.spaceXL), Text( 'Hubungi admin pusat untuk mendapatkan kredensial akun.', style: AppConfig.bodySmall, textAlign: TextAlign.center, ), ], ), ), ), ), ), ); } }