import 'package:flutter/material.dart'; import '../services/odoo_service.dart'; import '../services/config.dart'; import '../theme/app_theme.dart'; import '../widgets/agreement_dialog.dart'; class SignupScreen extends StatefulWidget { const SignupScreen({super.key}); @override State createState() => _SignupScreenState(); } class _SignupScreenState extends State { final _nameController = TextEditingController(); final _phoneController = TextEditingController(); final _passwordController = TextEditingController(); final _confirmPasswordController = TextEditingController(); DateTime? _selectedDate; String? _selectedGender; bool _agreedToTerms = false; bool _isLoading = false; final List _genderOptions = ['Male', 'Female']; void _selectBirthDate() async { final DateTime? picked = await showDatePicker( context: context, initialDate: DateTime(2000, 1, 1), firstDate: DateTime(1920), lastDate: DateTime.now(), builder: (context, child) { return Theme( data: Theme.of(context).copyWith( colorScheme: const ColorScheme.light( primary: AppTheme.secondary, onPrimary: Colors.white, onSurface: AppTheme.onSurface, ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( foregroundColor: AppTheme.secondary, ), ), ), child: child!, ); }, ); if (picked != null && picked != _selectedDate) { setState(() { _selectedDate = picked; }); } } void _signUp() async { final name = _nameController.text.trim(); final phone = _phoneController.text.trim(); final password = _passwordController.text; final confirmPassword = _confirmPasswordController.text; if (name.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Please enter your name.')), ); return; } if (phone.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Please enter your phone number.')), ); return; } if (_selectedDate == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Please select your birth date.')), ); return; } if (_selectedGender == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Please select your gender.')), ); return; } if (password.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Please enter a password.')), ); return; } if (password != confirmPassword) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Passwords do not match.')), ); return; } if (!_agreedToTerms) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('You must agree to the Terms & Conditions and Privacy Policy.')), ); return; } setState(() => _isLoading = true); try { final formattedDate = "${_selectedDate!.year}-${_selectedDate!.month.toString().padLeft(2, '0')}-${_selectedDate!.day.toString().padLeft(2, '0')}"; final service = OdooService(); service.connect(AppConfig.odooUrl); final response = await service.signUpMember( name, phone, formattedDate, _selectedGender!, password, ); if (response != null && response['status'] == 'success') { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(response['message'] ?? 'Registration successful!')), ); Navigator.of(context).pop(); } } else { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(response?['message'] ?? 'Registration failed.')), ); } } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error: $e')), ); } } finally { if (mounted) { setState(() => _isLoading = false); } } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Become a Member'), ), body: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 32.0, vertical: 24.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( 'Join Mie Mapan Loyalty', style: Theme.of(context).textTheme.headlineMedium?.copyWith( color: AppTheme.onSurface, fontSize: 28, ), ), const SizedBox(height: 8), Text( 'Register below to start earning points, unlocking culinary tiers, and tracking your loyalty level.', style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: AppTheme.onSurfaceVariant, ), ), const SizedBox(height: 36), TextField( controller: _nameController, decoration: const InputDecoration( labelText: 'Full Name', ), ), const SizedBox(height: 20), TextField( controller: _phoneController, keyboardType: TextInputType.phone, decoration: const InputDecoration( labelText: 'Phone Number', hintText: 'e.g. 08123456789', ), ), const SizedBox(height: 20), InkWell( onTap: _selectBirthDate, child: Container( color: AppTheme.surfaceContainer, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( _selectedDate == null ? 'Select Birth Date' : 'Birth Date: ${_selectedDate!.day.toString().padLeft(2, '0')}-${_selectedDate!.month.toString().padLeft(2, '0')}-${_selectedDate!.year}', style: TextStyle( color: _selectedDate == null ? AppTheme.onSurfaceVariant : AppTheme.onSurface, fontSize: 16, ), ), const Icon(Icons.calendar_today, color: AppTheme.onSurfaceVariant), ], ), ), ), const SizedBox(height: 20), DropdownButtonFormField( value: _selectedGender, items: _genderOptions.map((String value) { return DropdownMenuItem( value: value, child: Text(value), ); }).toList(), onChanged: (val) { setState(() { _selectedGender = val; }); }, decoration: const InputDecoration( labelText: 'Gender', ), dropdownColor: AppTheme.surfaceContainerLow, style: const TextStyle( color: AppTheme.onSurface, fontSize: 16, ), ), const SizedBox(height: 20), TextField( controller: _passwordController, decoration: const InputDecoration( labelText: 'Password', ), obscureText: true, ), const SizedBox(height: 20), TextField( controller: _confirmPasswordController, decoration: const InputDecoration( labelText: 'Confirm Password', ), obscureText: true, ), const SizedBox(height: 24), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Checkbox( value: _agreedToTerms, activeColor: AppTheme.secondary, onChanged: (val) { setState(() { _agreedToTerms = val ?? false; }); }, ), Expanded( child: Padding( padding: const EdgeInsets.only(top: 8.0), child: Wrap( children: [ const Text('I agree to the ', style: TextStyle(color: AppTheme.onSurfaceVariant, fontSize: 13)), GestureDetector( onTap: () => AgreementDialog.show( context, 'Terms & Conditions', AgreementTexts.termsAndConditions ), child: const Text( 'Terms & Conditions', style: TextStyle( color: AppTheme.secondary, fontWeight: FontWeight.bold, decoration: TextDecoration.underline, fontSize: 13, ), ), ), const Text(' and ', style: TextStyle(color: AppTheme.onSurfaceVariant, fontSize: 13)), GestureDetector( onTap: () => AgreementDialog.show( context, 'Privacy Policy', AgreementTexts.privacyPolicy ), child: const Text( 'Privacy Policy', style: TextStyle( color: AppTheme.secondary, fontWeight: FontWeight.bold, decoration: TextDecoration.underline, fontSize: 13, ), ), ), ], ), ), ), ], ), const SizedBox(height: 36), SizedBox( height: 56, child: _isLoading ? const Center(child: CircularProgressIndicator()) : ElevatedButton( onPressed: _signUp, child: const Text( 'Sign Up & Get Silver Card', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ), ], ), ), ), ); } }