import 'package:flutter/material.dart'; import 'package:barber_app/core/theme/app_theme.dart'; import 'package:barber_app/core/constants/app_strings.dart'; import 'package:barber_app/features/finances/data/models/transaction_model.dart'; import 'package:barber_app/features/finances/data/repositories/transaction_repository.dart'; import 'package:barber_app/shared/widgets/custom_text_field.dart'; import 'package:barber_app/shared/widgets/loading_button.dart'; class AddTransactionPage extends StatefulWidget { const AddTransactionPage({super.key}); @override State createState() => _AddTransactionPageState(); } class _AddTransactionPageState extends State { final _formKey = GlobalKey(); final _descriptionController = TextEditingController(); final _amountController = TextEditingController(); TransactionType _type = TransactionType.expense; DateTime _dueDate = DateTime.now(); bool _isPaid = false; bool _isLoading = false; @override void dispose() { _descriptionController.dispose(); _amountController.dispose(); super.dispose(); } Future _selectDate() async { final date = await showDatePicker( context: context, initialDate: _dueDate, firstDate: DateTime(2020), lastDate: DateTime(2030), builder: (context, child) { return Theme( data: Theme.of(context).copyWith( colorScheme: ColorScheme.dark( primary: AppColors.primaryColor, surface: AppColors.surface, ), ), child: child!, ); }, ); if (date != null) { setState(() => _dueDate = date); } } Future _saveTransaction() async { if (!(_formKey.currentState?.validate() ?? false)) return; setState(() => _isLoading = true); try { final repo = TransactionRepository(); if (_type == TransactionType.expense) { await repo.createExpense( amount: double.parse(_amountController.text.replaceAll(',', '.')), description: _descriptionController.text, dueDate: _dueDate, isPaid: _isPaid, ); } else { await repo.createRevenue( amount: double.parse(_amountController.text.replaceAll(',', '.')), description: _descriptionController.text, dueDate: _dueDate, isPaid: _isPaid, ); } if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text(AppStrings.savedSuccessfully), backgroundColor: AppColors.success, ), ); Navigator.pop(context); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Erro: $e'), backgroundColor: AppColors.error), ); } } finally { if (mounted) setState(() => _isLoading = false); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Nova Transação'), leading: IconButton( icon: const Icon(Icons.arrow_back_ios), onPressed: () => Navigator.pop(context), ), ), body: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.all(24), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Tipo const Text( 'Tipo', style: TextStyle( color: AppColors.textSecondary, fontSize: 14, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 8), Row( children: [ Expanded( child: _buildTypeButton( 'Despesa', TransactionType.expense, Icons.arrow_upward, AppColors.error, ), ), const SizedBox(width: 12), Expanded( child: _buildTypeButton( 'Receita', TransactionType.revenue, Icons.arrow_downward, AppColors.success, ), ), ], ), const SizedBox(height: 24), CustomTextField( controller: _descriptionController, label: AppStrings.description, hint: 'Ex: Aluguel, Luz, Produto...', prefixIcon: Icons.description_outlined, validator: (v) => v?.isEmpty ?? true ? 'Informe a descrição' : null, ), const SizedBox(height: 20), CustomTextField( controller: _amountController, label: 'Valor', hint: '0,00', prefixIcon: Icons.attach_money, keyboardType: TextInputType.number, validator: (v) => v?.isEmpty ?? true ? 'Informe o valor' : null, ), const SizedBox(height: 20), // Data const Text( AppStrings.dueDate, style: TextStyle( color: AppColors.textSecondary, fontSize: 14, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 8), GestureDetector( onTap: _selectDate, child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColors.surfaceLight, borderRadius: BorderRadius.circular(12), ), child: Row( children: [ Icon( Icons.calendar_today, color: AppColors.textSecondary, ), const SizedBox(width: 12), Text( '${_dueDate.day.toString().padLeft(2, '0')}/${_dueDate.month.toString().padLeft(2, '0')}/${_dueDate.year}', style: const TextStyle( color: AppColors.textPrimary, fontSize: 16, ), ), ], ), ), ), const SizedBox(height: 20), // Já pago? SwitchListTile( title: const Text( 'Já foi pago?', style: TextStyle(color: AppColors.textPrimary), ), value: _isPaid, onChanged: (v) => setState(() => _isPaid = v), activeThumbColor: AppColors.primaryColor, contentPadding: EdgeInsets.zero, ), const SizedBox(height: 32), LoadingButton( text: AppStrings.save, isLoading: _isLoading, onPressed: _saveTransaction, ), ], ), ), ), ), ); } Widget _buildTypeButton( String label, TransactionType type, IconData icon, Color color, ) { final isSelected = _type == type; return GestureDetector( onTap: () => setState(() => _type = type), child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: isSelected ? color.withValues(alpha: 0.2) : AppColors.surface, borderRadius: BorderRadius.circular(12), border: Border.all( color: isSelected ? color : AppColors.surfaceLight, width: isSelected ? 2 : 1, ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, color: isSelected ? color : AppColors.textSecondary), const SizedBox(width: 8), Text( label, style: TextStyle( color: isSelected ? color : AppColors.textSecondary, fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, ), ), ], ), ), ); } }