import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../../shared/services/api_client.dart'; import 'clients_screen.dart'; import 'client_detail_screen.dart'; class ClientFormScreen extends ConsumerStatefulWidget { final String? clientId; const ClientFormScreen({super.key, this.clientId}); @override ConsumerState createState() => _ClientFormScreenState(); } class _ClientFormScreenState extends ConsumerState { final _formKey = GlobalKey(); bool _isLoading = false; bool _isInitialized = false; // Form controllers final _firstNameController = TextEditingController(); final _lastNameController = TextEditingController(); final _emailController = TextEditingController(); final _phoneController = TextEditingController(); final _companyController = TextEditingController(); final _roleController = TextEditingController(); final _industryController = TextEditingController(); final _notesController = TextEditingController(); final _interestsController = TextEditingController(); final _tagsController = TextEditingController(); DateTime? _birthday; DateTime? _anniversary; bool get isEditing => widget.clientId != null; @override void dispose() { _firstNameController.dispose(); _lastNameController.dispose(); _emailController.dispose(); _phoneController.dispose(); _companyController.dispose(); _roleController.dispose(); _industryController.dispose(); _notesController.dispose(); _interestsController.dispose(); _tagsController.dispose(); super.dispose(); } void _initializeFromClient(Map client) { if (_isInitialized) return; _isInitialized = true; _firstNameController.text = client['firstName'] ?? ''; _lastNameController.text = client['lastName'] ?? ''; _emailController.text = client['email'] ?? ''; _phoneController.text = client['phone'] ?? ''; _companyController.text = client['company'] ?? ''; _roleController.text = client['role'] ?? ''; _industryController.text = client['industry'] ?? ''; _notesController.text = client['notes'] ?? ''; _interestsController.text = (client['interests'] as List?)?.join(', ') ?? ''; _tagsController.text = (client['tags'] as List?)?.join(', ') ?? ''; if (client['birthday'] != null) { _birthday = DateTime.tryParse(client['birthday']); } if (client['anniversary'] != null) { _anniversary = DateTime.tryParse(client['anniversary']); } } Future _handleSubmit() async { if (!_formKey.currentState!.validate()) return; setState(() => _isLoading = true); try { final data = { 'firstName': _firstNameController.text.trim(), 'lastName': _lastNameController.text.trim(), if (_emailController.text.isNotEmpty) 'email': _emailController.text.trim(), if (_phoneController.text.isNotEmpty) 'phone': _phoneController.text.trim(), if (_companyController.text.isNotEmpty) 'company': _companyController.text.trim(), if (_roleController.text.isNotEmpty) 'role': _roleController.text.trim(), if (_industryController.text.isNotEmpty) 'industry': _industryController.text.trim(), if (_notesController.text.isNotEmpty) 'notes': _notesController.text.trim(), if (_interestsController.text.isNotEmpty) 'interests': _interestsController.text.split(',').map((e) => e.trim()).where((e) => e.isNotEmpty).toList(), if (_tagsController.text.isNotEmpty) 'tags': _tagsController.text.split(',').map((e) => e.trim()).where((e) => e.isNotEmpty).toList(), if (_birthday != null) 'birthday': _birthday!.toIso8601String(), if (_anniversary != null) 'anniversary': _anniversary!.toIso8601String(), }; final apiClient = ref.read(apiClientProvider); if (isEditing) { await apiClient.updateClient(widget.clientId!, data); ref.invalidate(clientDetailProvider(widget.clientId!)); } else { final client = await apiClient.createClient(data); widget.clientId ?? client['id']; } ref.invalidate(clientsProvider(null)); if (mounted) { context.go(isEditing ? '/clients/${widget.clientId}' : '/'); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Failed to save: $e')), ); } } finally { if (mounted) { setState(() => _isLoading = false); } } } Future _selectDate(BuildContext context, bool isBirthday) async { final initialDate = isBirthday ? _birthday : _anniversary; final picked = await showDatePicker( context: context, initialDate: initialDate ?? DateTime.now(), firstDate: DateTime(1900), lastDate: DateTime.now().add(const Duration(days: 365)), ); if (picked != null) { setState(() { if (isBirthday) { _birthday = picked; } else { _anniversary = picked; } }); } } @override Widget build(BuildContext context) { // Load existing client data if editing if (isEditing) { final clientAsync = ref.watch(clientDetailProvider(widget.clientId!)); return clientAsync.when( data: (client) { _initializeFromClient(client); return _buildForm(context); }, loading: () => Scaffold( appBar: AppBar(title: const Text('Edit Client')), body: const Center(child: CircularProgressIndicator()), ), error: (e, s) => Scaffold( appBar: AppBar(title: const Text('Edit Client')), body: Center(child: Text('Error: $e')), ), ); } return _buildForm(context); } Widget _buildForm(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(isEditing ? 'Edit Client' : 'New Client'), actions: [ TextButton( onPressed: _isLoading ? null : _handleSubmit, child: _isLoading ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2), ) : const Text('Save'), ), ], ), body: Form( key: _formKey, child: ListView( padding: const EdgeInsets.all(16), children: [ // Basic info Text( 'Basic Information', style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), Row( children: [ Expanded( child: TextFormField( controller: _firstNameController, decoration: const InputDecoration(labelText: 'First Name *'), validator: (v) => v?.isEmpty == true ? 'Required' : null, ), ), const SizedBox(width: 16), Expanded( child: TextFormField( controller: _lastNameController, decoration: const InputDecoration(labelText: 'Last Name *'), validator: (v) => v?.isEmpty == true ? 'Required' : null, ), ), ], ), const SizedBox(height: 16), TextFormField( controller: _emailController, decoration: const InputDecoration(labelText: 'Email'), keyboardType: TextInputType.emailAddress, ), const SizedBox(height: 16), TextFormField( controller: _phoneController, decoration: const InputDecoration(labelText: 'Phone'), keyboardType: TextInputType.phone, ), const SizedBox(height: 32), Text( 'Professional', style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), TextFormField( controller: _companyController, decoration: const InputDecoration(labelText: 'Company'), ), const SizedBox(height: 16), TextFormField( controller: _roleController, decoration: const InputDecoration(labelText: 'Role'), ), const SizedBox(height: 16), TextFormField( controller: _industryController, decoration: const InputDecoration(labelText: 'Industry'), ), const SizedBox(height: 32), Text( 'Personal', style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), Row( children: [ Expanded( child: InkWell( onTap: () => _selectDate(context, true), child: InputDecorator( decoration: const InputDecoration(labelText: 'Birthday'), child: Text( _birthday != null ? '${_birthday!.month}/${_birthday!.day}/${_birthday!.year}' : 'Select date', style: TextStyle( color: _birthday != null ? null : Colors.grey, ), ), ), ), ), const SizedBox(width: 16), Expanded( child: InkWell( onTap: () => _selectDate(context, false), child: InputDecorator( decoration: const InputDecoration(labelText: 'Anniversary'), child: Text( _anniversary != null ? '${_anniversary!.month}/${_anniversary!.day}/${_anniversary!.year}' : 'Select date', style: TextStyle( color: _anniversary != null ? null : Colors.grey, ), ), ), ), ), ], ), const SizedBox(height: 16), TextFormField( controller: _interestsController, decoration: const InputDecoration( labelText: 'Interests', hintText: 'Golf, Wine, Travel (comma separated)', ), ), const SizedBox(height: 32), Text( 'Notes & Tags', style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), TextFormField( controller: _notesController, decoration: const InputDecoration(labelText: 'Notes'), maxLines: 4, ), const SizedBox(height: 16), TextFormField( controller: _tagsController, decoration: const InputDecoration( labelText: 'Tags', hintText: 'VIP, Referral Source (comma separated)', ), ), const SizedBox(height: 32), ], ), ), ); } }