diff --git a/lib/features/add_transaction/provider.dart b/lib/features/add_transaction/provider.dart index 99272f5..90e5736 100644 --- a/lib/features/add_transaction/provider.dart +++ b/lib/features/add_transaction/provider.dart @@ -13,8 +13,8 @@ class AddTransactionState { const AddTransactionState({ this.amount, - this.category = 'Food', - this.type = TransactionType.expense, + this.category = 'Salary', + this.type = TransactionType.income, required this.date, this.note = '', this.isSubmitting = false, diff --git a/lib/features/add_transaction/screen.dart b/lib/features/add_transaction/screen.dart index 6f5d62e..ddc9cf6 100644 --- a/lib/features/add_transaction/screen.dart +++ b/lib/features/add_transaction/screen.dart @@ -282,18 +282,48 @@ class _AddTransactionScreenState extends ConsumerState { ), const SizedBox(height: 32), - ElevatedButton( - onPressed: state.isSubmitting ? null : _submit, - child: state.isSubmitting - ? const SizedBox( - height: 20, - width: 20, - child: CircularProgressIndicator( - strokeWidth: 2, - color: Colors.white, + AnimatedContainer( + duration: const Duration(milliseconds: 250), + curve: Curves.easeInOut, + child: Builder( + builder: (context) { + final selectedType = state.type; + final typeColor = selectedType == TransactionType.income + ? const Color(0xFF4CAF8C) + : const Color(0xFFE05C6B); + + return SizedBox( + width: double.infinity, + child: OutlinedButton( + onPressed: state.isSubmitting ? null : _submit, + style: OutlinedButton.styleFrom( + backgroundColor: typeColor.withOpacity(0.1), + side: BorderSide(color: typeColor, width: 2), + padding: const EdgeInsets.symmetric(vertical: 16), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), + foregroundColor: typeColor, ), - ) - : Text(state.isEditing ? 'Update Transaction' : 'Save Transaction'), + child: state.isSubmitting + ? SizedBox( + height: 20, + width: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + color: typeColor, + ), + ) + : Text( + state.isEditing ? 'Save Changes' : 'Add Transaction', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: typeColor, + ), + ), + ), + ); + }, + ), ), ], ), @@ -336,13 +366,6 @@ class _TypeToggle extends StatelessWidget { ), child: Row( children: [ - _TypeOption( - label: 'Expense', - icon: Icons.arrow_upward_rounded, - color: AppColors.expense, - isSelected: selected == TransactionType.expense, - onTap: () => onChanged(TransactionType.expense), - ), _TypeOption( label: 'Income', icon: Icons.arrow_downward_rounded, @@ -350,6 +373,13 @@ class _TypeToggle extends StatelessWidget { isSelected: selected == TransactionType.income, onTap: () => onChanged(TransactionType.income), ), + _TypeOption( + label: 'Expense', + icon: Icons.arrow_upward_rounded, + color: AppColors.expense, + isSelected: selected == TransactionType.expense, + onTap: () => onChanged(TransactionType.expense), + ), ], ), ); diff --git a/lib/features/dashboard/screen.dart b/lib/features/dashboard/screen.dart index 1f6834e..c100bb2 100644 --- a/lib/features/dashboard/screen.dart +++ b/lib/features/dashboard/screen.dart @@ -362,7 +362,7 @@ class _BalanceCard extends ConsumerWidget { return Container( width: double.infinity, height: 180, - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 20), decoration: BoxDecoration( gradient: LinearGradient( colors: [ @@ -381,88 +381,81 @@ class _BalanceCard extends ConsumerWidget { ), ], ), - child: LayoutBuilder( - builder: (context, constraints) { - return Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - // LEFT: main balance — takes as much space as needed, right side shrinks first - Flexible( - flex: 3, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'TOTAL BALANCE', - style: TextStyle( - fontSize: 11, - letterSpacing: 1.2, - color: Theme.of(context).colorScheme.onPrimary.withOpacity(0.6), - ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // LEFT: main balance — takes available space, centered + Expanded( + flex: 5, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + 'TOTAL BALANCE', + style: TextStyle( + fontSize: 11, + letterSpacing: 1.5, + color: Theme.of(context).colorScheme.onPrimary.withOpacity(0.6), + ), + ), + const SizedBox(height: 6), + FittedBox( + fit: BoxFit.scaleDown, + alignment: Alignment.center, + child: Text( + _smartBalance(balance, fmt, currencyInfo.symbol), + style: TextStyle( + fontSize: 48, + fontWeight: FontWeight.w700, + color: Theme.of(context).colorScheme.onPrimary, ), - const SizedBox(height: 4), - // FittedBox shrinks text to fit available width - FittedBox( + maxLines: 1, + textAlign: TextAlign.center, + ), + ), + ], + ), + ), + // Only show conversion column if there's a meaningful balance + if (balance != 0) ...[ + const SizedBox(width: 16), + Container( + width: 1, + height: 70, + color: Theme.of(context).colorScheme.onPrimary.withOpacity(0.15), + ), + const SizedBox(width: 16), + // RIGHT: conversions — fixed width, doesn't expand + SizedBox( + width: 110, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: others.map((c) { + final converted = rates.convert(balance, currencyInfo.code, c.$1); + return Padding( + padding: const EdgeInsets.symmetric(vertical: 3), + child: FittedBox( fit: BoxFit.scaleDown, alignment: Alignment.centerLeft, child: Text( - _smartBalance(balance, fmt, currencyInfo.symbol), + _smartBalance(converted, fmt, c.$2), style: TextStyle( - fontSize: 36, // max font size - fontWeight: FontWeight.w700, - color: Theme.of(context).colorScheme.onPrimary, + fontSize: 14, + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.onPrimary.withOpacity(0.65), ), maxLines: 1, ), ), - ], - ), + ); + }).toList(), ), - // RIGHT side: use Flexible (not Expanded) so it can shrink - // When balance is long, this column gets squeezed first - Flexible( - flex: 2, - child: Row( - children: [ - const SizedBox(width: 12), - Container( - width: 1, - height: 60, - color: Theme.of(context).colorScheme.onPrimary.withOpacity(0.15), - ), - const SizedBox(width: 12), - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: others.map((c) { - final converted = rates.convert(balance, currencyInfo.code, c.$1); - return Padding( - padding: const EdgeInsets.symmetric(vertical: 2), - child: FittedBox( - fit: BoxFit.scaleDown, - alignment: Alignment.centerLeft, - child: Text( - _smartBalance(converted, fmt, c.$2), - style: TextStyle( - fontSize: 13, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.onPrimary.withOpacity(0.7), - ), - maxLines: 1, - ), - ), - ); - }).toList(), - ), - ), - ], - ), - ), - ], - ); - }, + ), + ], + ], ), ); }