mirror of
https://github.com/koloideal/Casha.git
synced 2026-08-08 09:41:13 +03:00
step
This commit is contained in:
@@ -167,6 +167,7 @@ class AppStrings {
|
||||
|
||||
String get colorPrimary => _ru ? 'Основной' : 'Primary';
|
||||
String get colorSecondary => _ru ? 'Второй' : 'Secondary';
|
||||
String get colorSecond => _ru ? 'Второй' : 'Second';
|
||||
String get colorSolid => _ru ? 'Однотон' : 'Solid';
|
||||
String get gradientLinear => _ru ? 'Линейный' : 'Linear';
|
||||
String get gradientReverse => _ru ? 'Обратный' : 'Reverse';
|
||||
|
||||
@@ -85,7 +85,7 @@ class _AccountEditorOverlayState extends State<AccountEditorOverlay> {
|
||||
Widget build(BuildContext context) {
|
||||
final mq = MediaQuery.of(widget.context);
|
||||
final cardTop = mq.padding.top + kToolbarHeight + 16;
|
||||
const cardHeight = 230.0;
|
||||
const cardHeight = 190.0;
|
||||
const editorPanelHeight = 102.0;
|
||||
final editorPanelTop = cardTop + cardHeight + 20;
|
||||
final colorPanelTop = editorPanelTop + editorPanelHeight + 12;
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../../../../core/constants.dart';
|
||||
import '../../../../shared/widgets/byn_sign.dart';
|
||||
|
||||
class AccountEditorPanel extends ConsumerWidget {
|
||||
class AccountEditorPanel extends ConsumerStatefulWidget {
|
||||
final TextEditingController nameController;
|
||||
final String selectedCurrency;
|
||||
final bool showCurrencyDropdown;
|
||||
@@ -26,15 +26,29 @@ class AccountEditorPanel extends ConsumerWidget {
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
ConsumerState<AccountEditorPanel> createState() => _AccountEditorPanelState();
|
||||
}
|
||||
|
||||
class _AccountEditorPanelState extends ConsumerState<AccountEditorPanel> {
|
||||
bool _showNameError = false;
|
||||
|
||||
void _triggerNameError() {
|
||||
setState(() => _showNameError = true);
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
if (mounted) setState(() => _showNameError = false);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: panelHeight,
|
||||
height: widget.panelHeight,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(dashboardContext).colorScheme.surface,
|
||||
color: Theme.of(widget.dashboardContext).colorScheme.surface,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(
|
||||
color: Theme.of(
|
||||
dashboardContext,
|
||||
widget.dashboardContext,
|
||||
).colorScheme.onSurface.withOpacity(0.1),
|
||||
width: 1.5,
|
||||
),
|
||||
@@ -58,7 +72,7 @@ class AccountEditorPanel extends ConsumerWidget {
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(
|
||||
dashboardContext,
|
||||
widget.dashboardContext,
|
||||
).colorScheme.onSurface.withOpacity(0.6),
|
||||
),
|
||||
),
|
||||
@@ -70,7 +84,7 @@ class AccountEditorPanel extends ConsumerWidget {
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: TextField(
|
||||
controller: nameController,
|
||||
controller: widget.nameController,
|
||||
buildCounter:
|
||||
(
|
||||
context, {
|
||||
@@ -84,23 +98,23 @@ class AccountEditorPanel extends ConsumerWidget {
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Theme.of(
|
||||
dashboardContext,
|
||||
widget.dashboardContext,
|
||||
).colorScheme.onSurface.withOpacity(0.4),
|
||||
),
|
||||
filled: true,
|
||||
fillColor: Theme.of(
|
||||
dashboardContext,
|
||||
widget.dashboardContext,
|
||||
).colorScheme.onSurface.withOpacity(0.05),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(showLimitError ||
|
||||
showDuplicateError ||
|
||||
nameController.text.trim().isEmpty)
|
||||
(widget.showLimitError ||
|
||||
widget.showDuplicateError ||
|
||||
_showNameError)
|
||||
? Colors.red
|
||||
: Theme.of(
|
||||
dashboardContext,
|
||||
widget.dashboardContext,
|
||||
).colorScheme.onSurface.withOpacity(0.15),
|
||||
width: 1.5,
|
||||
),
|
||||
@@ -109,12 +123,12 @@ class AccountEditorPanel extends ConsumerWidget {
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(showLimitError ||
|
||||
showDuplicateError ||
|
||||
nameController.text.trim().isEmpty)
|
||||
(widget.showLimitError ||
|
||||
widget.showDuplicateError ||
|
||||
_showNameError)
|
||||
? Colors.red
|
||||
: Theme.of(
|
||||
dashboardContext,
|
||||
widget.dashboardContext,
|
||||
).colorScheme.onSurface.withOpacity(0.15),
|
||||
width: 1.5,
|
||||
),
|
||||
@@ -123,9 +137,9 @@ class AccountEditorPanel extends ConsumerWidget {
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(showLimitError ||
|
||||
showDuplicateError ||
|
||||
nameController.text.trim().isEmpty)
|
||||
(widget.showLimitError ||
|
||||
widget.showDuplicateError ||
|
||||
_showNameError)
|
||||
? Colors.red
|
||||
: const Color(0xFF7C6DED),
|
||||
width: 1.5,
|
||||
@@ -141,19 +155,19 @@ class AccountEditorPanel extends ConsumerWidget {
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: onCurrencyDropdownToggle,
|
||||
onTap: widget.onCurrencyDropdownToggle,
|
||||
child: Container(
|
||||
height: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(
|
||||
dashboardContext,
|
||||
widget.dashboardContext,
|
||||
).colorScheme.onSurface.withOpacity(0.05),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: showCurrencyDropdown
|
||||
color: widget.showCurrencyDropdown
|
||||
? const Color(0xFF7C6DED)
|
||||
: Theme.of(
|
||||
dashboardContext,
|
||||
widget.dashboardContext,
|
||||
).colorScheme.onSurface.withOpacity(0.15),
|
||||
width: 1.5,
|
||||
),
|
||||
@@ -162,17 +176,17 @@ class AccountEditorPanel extends ConsumerWidget {
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
selectedCurrency == 'BYN'
|
||||
widget.selectedCurrency == 'BYN'
|
||||
? BynSign(
|
||||
fontSize: 15,
|
||||
color: Theme.of(
|
||||
dashboardContext,
|
||||
widget.dashboardContext,
|
||||
).colorScheme.onSurface,
|
||||
)
|
||||
: Text(
|
||||
kDisplayCurrencies
|
||||
.firstWhere(
|
||||
(c) => c.$1 == selectedCurrency,
|
||||
(c) => c.$1 == widget.selectedCurrency,
|
||||
)
|
||||
.$2,
|
||||
style: const TextStyle(
|
||||
@@ -182,12 +196,12 @@ class AccountEditorPanel extends ConsumerWidget {
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Icon(
|
||||
showCurrencyDropdown
|
||||
widget.showCurrencyDropdown
|
||||
? Icons.arrow_drop_up
|
||||
: Icons.arrow_drop_down,
|
||||
size: 20,
|
||||
color: Theme.of(
|
||||
dashboardContext,
|
||||
widget.dashboardContext,
|
||||
).colorScheme.onSurface.withOpacity(0.6),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -171,7 +171,7 @@ class BalanceCardState extends ConsumerState<BalanceCard>
|
||||
..rotateY(_tiltY * 0.42),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 220,
|
||||
height: 180,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
gradient: _buildGradient(primary, secondary, gradientType),
|
||||
|
||||
@@ -66,7 +66,7 @@ class _BalanceCardCarouselState extends ConsumerState<BalanceCardCarousel> {
|
||||
return Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 230,
|
||||
height: 190,
|
||||
child: OverflowBox(
|
||||
maxWidth: MediaQuery.of(context).size.width,
|
||||
child: PageView.builder(
|
||||
@@ -154,14 +154,14 @@ class _BalanceCardCarouselState extends ConsumerState<BalanceCardCarousel> {
|
||||
);
|
||||
},
|
||||
loading: () => const SizedBox(
|
||||
height: 220,
|
||||
height: 180,
|
||||
child: Center(child: CircularProgressIndicator()),
|
||||
),
|
||||
error: (error, stack) {
|
||||
return Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 220,
|
||||
height: 180,
|
||||
child: BalanceCard(
|
||||
balance: widget.balance,
|
||||
currencyInfo: widget.currencyInfo,
|
||||
@@ -198,7 +198,7 @@ class AddAccountCard extends StatelessWidget {
|
||||
painter: _DashedBorderPainter(),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 205,
|
||||
height: 165,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surface.withOpacity(0.4),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
|
||||
+181
-1
@@ -2,10 +2,188 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:intl/date_symbol_data_local.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'app/app.dart';
|
||||
import 'core/services/haptic_service.dart';
|
||||
import 'data/database/app_database.dart';
|
||||
import 'data/database/app_database.dart' hide Account, Transaction;
|
||||
import 'data/repositories/account_repository.dart';
|
||||
import 'data/repositories/transaction_repository.dart';
|
||||
import 'features/dashboard/provider.dart';
|
||||
import 'shared/models/account.dart';
|
||||
import 'shared/models/transaction.dart';
|
||||
|
||||
Future<void> seedTestData(AppDatabase database) async {
|
||||
final accountRepo = AccountRepository(database);
|
||||
final transactionRepo = TransactionRepository(database);
|
||||
|
||||
final existingAccounts = await accountRepo.getAll();
|
||||
if (existingAccounts.length > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
final now = DateTime.now();
|
||||
final uuid = const Uuid();
|
||||
|
||||
final cashId = await accountRepo.add(
|
||||
Account(
|
||||
id: 0,
|
||||
name: 'Cash',
|
||||
isMain: false,
|
||||
sortOrder: 1,
|
||||
currency: 'USD',
|
||||
createdAt: now,
|
||||
),
|
||||
);
|
||||
|
||||
final cardId = await accountRepo.add(
|
||||
Account(
|
||||
id: 0,
|
||||
name: 'Card',
|
||||
isMain: false,
|
||||
sortOrder: 2,
|
||||
currency: 'USD',
|
||||
createdAt: now,
|
||||
),
|
||||
);
|
||||
|
||||
final savingsId = await accountRepo.add(
|
||||
Account(
|
||||
id: 0,
|
||||
name: 'Savings',
|
||||
isMain: false,
|
||||
sortOrder: 3,
|
||||
currency: 'USD',
|
||||
createdAt: now,
|
||||
),
|
||||
);
|
||||
|
||||
final transactions = [
|
||||
Transaction(
|
||||
id: uuid.v4(),
|
||||
amount: 3500.0,
|
||||
category: 'Salary',
|
||||
type: TransactionType.income,
|
||||
date: now.subtract(const Duration(days: 28)),
|
||||
note: 'Monthly salary',
|
||||
accountId: cardId,
|
||||
),
|
||||
Transaction(
|
||||
id: uuid.v4(),
|
||||
amount: 85.50,
|
||||
category: 'Groceries',
|
||||
type: TransactionType.expense,
|
||||
date: now.subtract(const Duration(days: 27)),
|
||||
note: 'Weekly shopping',
|
||||
accountId: cardId,
|
||||
),
|
||||
Transaction(
|
||||
id: uuid.v4(),
|
||||
amount: 45.00,
|
||||
category: 'Transportation',
|
||||
type: TransactionType.expense,
|
||||
date: now.subtract(const Duration(days: 25)),
|
||||
accountId: cashId,
|
||||
),
|
||||
Transaction(
|
||||
id: uuid.v4(),
|
||||
amount: 120.00,
|
||||
category: 'Utilities',
|
||||
type: TransactionType.expense,
|
||||
date: now.subtract(const Duration(days: 22)),
|
||||
note: 'Electricity bill',
|
||||
accountId: cardId,
|
||||
),
|
||||
Transaction(
|
||||
id: uuid.v4(),
|
||||
amount: 200.0,
|
||||
category: 'Freelance',
|
||||
type: TransactionType.income,
|
||||
date: now.subtract(const Duration(days: 20)),
|
||||
note: 'Side project',
|
||||
accountId: cashId,
|
||||
),
|
||||
Transaction(
|
||||
id: uuid.v4(),
|
||||
amount: 500.0,
|
||||
category: 'Savings',
|
||||
type: TransactionType.expense,
|
||||
date: now.subtract(const Duration(days: 18)),
|
||||
note: 'Monthly savings',
|
||||
accountId: savingsId,
|
||||
),
|
||||
Transaction(
|
||||
id: uuid.v4(),
|
||||
amount: 65.25,
|
||||
category: 'Dining',
|
||||
type: TransactionType.expense,
|
||||
date: now.subtract(const Duration(days: 15)),
|
||||
accountId: cardId,
|
||||
),
|
||||
Transaction(
|
||||
id: uuid.v4(),
|
||||
amount: 30.00,
|
||||
category: 'Entertainment',
|
||||
type: TransactionType.expense,
|
||||
date: now.subtract(const Duration(days: 12)),
|
||||
note: 'Movie tickets',
|
||||
accountId: cashId,
|
||||
),
|
||||
Transaction(
|
||||
id: uuid.v4(),
|
||||
amount: 95.00,
|
||||
category: 'Groceries',
|
||||
type: TransactionType.expense,
|
||||
date: now.subtract(const Duration(days: 10)),
|
||||
accountId: cardId,
|
||||
),
|
||||
Transaction(
|
||||
id: uuid.v4(),
|
||||
amount: 150.0,
|
||||
category: 'Bonus',
|
||||
type: TransactionType.income,
|
||||
date: now.subtract(const Duration(days: 8)),
|
||||
note: 'Performance bonus',
|
||||
accountId: cardId,
|
||||
),
|
||||
Transaction(
|
||||
id: uuid.v4(),
|
||||
amount: 75.00,
|
||||
category: 'Shopping',
|
||||
type: TransactionType.expense,
|
||||
date: now.subtract(const Duration(days: 6)),
|
||||
accountId: cardId,
|
||||
),
|
||||
Transaction(
|
||||
id: uuid.v4(),
|
||||
amount: 40.00,
|
||||
category: 'Transportation',
|
||||
type: TransactionType.expense,
|
||||
date: now.subtract(const Duration(days: 4)),
|
||||
accountId: cashId,
|
||||
),
|
||||
Transaction(
|
||||
id: uuid.v4(),
|
||||
amount: 55.80,
|
||||
category: 'Dining',
|
||||
type: TransactionType.expense,
|
||||
date: now.subtract(const Duration(days: 2)),
|
||||
note: 'Dinner with friends',
|
||||
accountId: cardId,
|
||||
),
|
||||
Transaction(
|
||||
id: uuid.v4(),
|
||||
amount: 100.0,
|
||||
category: 'Gift',
|
||||
type: TransactionType.income,
|
||||
date: now.subtract(const Duration(days: 1)),
|
||||
accountId: cashId,
|
||||
),
|
||||
];
|
||||
|
||||
for (final transaction in transactions) {
|
||||
await transactionRepo.add(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
@@ -20,6 +198,8 @@ void main() async {
|
||||
|
||||
final database = AppDatabase();
|
||||
|
||||
await seedTestData(database);
|
||||
|
||||
runApp(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
|
||||
Reference in New Issue
Block a user