2025-08-26 23:53:12 -07:00
|
|
|
// ignore_for_file: deprecated_member_use
|
|
|
|
|
|
2025-08-06 20:28:19 -07:00
|
|
|
import 'package:flutter/material.dart';
|
2025-08-26 23:53:12 -07:00
|
|
|
import 'package:monarch/main_pages/HomePage/animated.dart';
|
|
|
|
|
import 'package:monarch/main_pages/HomePage/greeting.dart';
|
2025-08-22 07:12:09 -07:00
|
|
|
import 'package:monarch/main_pages/HomePage/navbar.dart';
|
2025-08-26 23:53:12 -07:00
|
|
|
import 'package:monarch/main_pages/HomePage/t_dialog.dart';
|
|
|
|
|
import 'package:monarch/main_pages/HomePage/voice_dialog.dart';
|
2025-08-06 20:28:19 -07:00
|
|
|
import 'package:monarch/other_pages/colors.dart';
|
|
|
|
|
import 'package:monarch/support/fetch_service.dart';
|
|
|
|
|
import 'package:monarch/main_pages/HomePage/hero_card.dart';
|
|
|
|
|
import 'package:monarch/main_pages/HomePage/quick_actions.dart';
|
|
|
|
|
import 'package:monarch/support/transcations_recent.dart';
|
|
|
|
|
|
|
|
|
|
class FinTrackHomePage extends StatefulWidget {
|
2025-08-26 23:53:12 -07:00
|
|
|
const FinTrackHomePage({super.key});
|
2025-08-06 20:28:19 -07:00
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
State<FinTrackHomePage> createState() => _FinTrackHomePageState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _FinTrackHomePageState extends State<FinTrackHomePage>
|
|
|
|
|
with TickerProviderStateMixin {
|
|
|
|
|
late AnimationController _fadeController;
|
|
|
|
|
late AnimationController _slideController;
|
2025-08-22 07:12:09 -07:00
|
|
|
late AnimationController _scaleController;
|
|
|
|
|
|
2025-08-06 20:28:19 -07:00
|
|
|
late Animation<double> _fadeAnimation;
|
|
|
|
|
late Animation<Offset> _slideAnimation;
|
2025-08-22 07:12:09 -07:00
|
|
|
late Animation<double> _scaleAnimation;
|
2025-08-06 20:28:19 -07:00
|
|
|
|
2025-08-12 21:52:42 -07:00
|
|
|
int _selectedIndex = 0;
|
2025-08-22 07:12:09 -07:00
|
|
|
String _greetingText = '';
|
|
|
|
|
|
2025-08-06 20:28:19 -07:00
|
|
|
@override
|
|
|
|
|
void initState() {
|
|
|
|
|
super.initState();
|
2025-08-12 21:52:42 -07:00
|
|
|
_initializeData();
|
|
|
|
|
_setupAnimations();
|
2025-08-22 07:12:09 -07:00
|
|
|
_updateGreeting();
|
2025-08-12 21:52:42 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void dispose() {
|
|
|
|
|
_fadeController.dispose();
|
|
|
|
|
_slideController.dispose();
|
2025-08-22 07:12:09 -07:00
|
|
|
_scaleController.dispose();
|
2025-08-12 21:52:42 -07:00
|
|
|
super.dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _initializeData() {
|
2025-08-06 20:28:19 -07:00
|
|
|
fetchRecentTransactions().then((transactions) {
|
2025-08-12 21:52:42 -07:00
|
|
|
// Handle transactions data
|
2025-08-06 20:28:19 -07:00
|
|
|
});
|
2025-08-12 21:52:42 -07:00
|
|
|
}
|
2025-08-06 20:28:19 -07:00
|
|
|
|
2025-08-22 07:12:09 -07:00
|
|
|
void _updateGreeting() {
|
|
|
|
|
final now = DateTime.now();
|
|
|
|
|
final hour = now.hour;
|
|
|
|
|
|
|
|
|
|
if (hour >= 5 && hour < 12) {
|
|
|
|
|
_greetingText = 'Good Morning';
|
|
|
|
|
} else if (hour >= 12 && hour < 17) {
|
|
|
|
|
_greetingText = 'Good Afternoon';
|
|
|
|
|
} else if (hour >= 17 && hour < 21) {
|
|
|
|
|
_greetingText = 'Good Evening';
|
|
|
|
|
} else {
|
|
|
|
|
_greetingText = 'Good Night';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-12 21:52:42 -07:00
|
|
|
void _setupAnimations() {
|
2025-08-06 20:28:19 -07:00
|
|
|
_fadeController = AnimationController(
|
2025-08-22 07:12:09 -07:00
|
|
|
duration: const Duration(milliseconds: 1500),
|
2025-08-06 20:28:19 -07:00
|
|
|
vsync: this,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
_slideController = AnimationController(
|
2025-08-22 07:12:09 -07:00
|
|
|
duration: const Duration(milliseconds: 1200),
|
|
|
|
|
vsync: this,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
_scaleController = AnimationController(
|
2025-08-06 20:28:19 -07:00
|
|
|
duration: const Duration(milliseconds: 800),
|
|
|
|
|
vsync: this,
|
|
|
|
|
);
|
|
|
|
|
|
2025-08-22 07:12:09 -07:00
|
|
|
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
|
|
|
|
CurvedAnimation(parent: _fadeController, curve: Curves.easeOutQuart),
|
|
|
|
|
);
|
2025-08-06 20:28:19 -07:00
|
|
|
|
|
|
|
|
_slideAnimation = Tween<Offset>(
|
2025-08-22 07:12:09 -07:00
|
|
|
begin: const Offset(0, 0.2),
|
2025-08-06 20:28:19 -07:00
|
|
|
end: Offset.zero,
|
2025-08-22 07:12:09 -07:00
|
|
|
).animate(
|
|
|
|
|
CurvedAnimation(parent: _slideController, curve: Curves.easeOutCubic),
|
|
|
|
|
);
|
2025-08-06 20:28:19 -07:00
|
|
|
|
2025-08-22 07:12:09 -07:00
|
|
|
_scaleAnimation = Tween<double>(begin: 0.8, end: 1.0).animate(
|
|
|
|
|
CurvedAnimation(parent: _scaleController, curve: Curves.elasticOut),
|
|
|
|
|
);
|
|
|
|
|
|
2025-08-06 20:28:19 -07:00
|
|
|
_fadeController.forward();
|
2025-08-22 07:12:09 -07:00
|
|
|
Future.delayed(const Duration(milliseconds: 200), () {
|
|
|
|
|
_slideController.forward();
|
|
|
|
|
});
|
|
|
|
|
Future.delayed(const Duration(milliseconds: 400), () {
|
|
|
|
|
_scaleController.forward();
|
|
|
|
|
});
|
2025-08-06 20:28:19 -07:00
|
|
|
}
|
|
|
|
|
|
2025-08-22 07:12:09 -07:00
|
|
|
void _showTransactionEntryDialog(String type) {
|
2025-08-26 20:03:28 -07:00
|
|
|
if (type == 'voice') {
|
|
|
|
|
showModalBottomSheet(
|
|
|
|
|
context: context,
|
|
|
|
|
backgroundColor: Colors.transparent,
|
|
|
|
|
isScrollControlled: true,
|
|
|
|
|
builder: (context) => VoiceTransactionDialog(),
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
showModalBottomSheet(
|
|
|
|
|
context: context,
|
|
|
|
|
backgroundColor: Colors.transparent,
|
|
|
|
|
isScrollControlled: true,
|
2025-08-26 23:53:12 -07:00
|
|
|
builder: (context) => EmailTransactionDialog(),
|
2025-08-26 20:03:28 -07:00
|
|
|
);
|
|
|
|
|
}
|
2025-08-06 20:28:19 -07:00
|
|
|
}
|
|
|
|
|
|
2025-08-12 21:52:42 -07:00
|
|
|
Widget _buildMainContent() {
|
|
|
|
|
return Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
2025-08-26 23:53:12 -07:00
|
|
|
AnimatedSection(
|
2025-08-22 07:12:09 -07:00
|
|
|
delay: 600,
|
|
|
|
|
child: Container(
|
|
|
|
|
margin: const EdgeInsets.only(bottom: 32),
|
|
|
|
|
child: const BalanceCardPage(),
|
|
|
|
|
),
|
2025-08-12 21:52:42 -07:00
|
|
|
),
|
2025-08-26 23:53:12 -07:00
|
|
|
AnimatedSection(
|
2025-08-22 07:12:09 -07:00
|
|
|
delay: 800,
|
|
|
|
|
child: Container(
|
|
|
|
|
margin: const EdgeInsets.only(bottom: 32),
|
|
|
|
|
child: QuickActionsPage(),
|
|
|
|
|
),
|
2025-08-12 21:52:42 -07:00
|
|
|
),
|
2025-08-26 23:53:12 -07:00
|
|
|
AnimatedSection(
|
2025-08-22 07:12:09 -07:00
|
|
|
delay: 1000,
|
|
|
|
|
child: Container(
|
|
|
|
|
margin: const EdgeInsets.only(bottom: 32),
|
|
|
|
|
child: RecentTransactionsWidget(
|
|
|
|
|
recentTransactions: fetchRecentTransactions(),
|
|
|
|
|
),
|
2025-08-12 21:52:42 -07:00
|
|
|
),
|
|
|
|
|
),
|
2025-08-22 07:12:09 -07:00
|
|
|
const SizedBox(height: 120),
|
2025-08-12 21:52:42 -07:00
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
}
|
2025-08-06 20:28:19 -07:00
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
return Scaffold(
|
|
|
|
|
backgroundColor: backgroundColor,
|
|
|
|
|
body: SafeArea(
|
|
|
|
|
child: FadeTransition(
|
|
|
|
|
opacity: _fadeAnimation,
|
|
|
|
|
child: SlideTransition(
|
|
|
|
|
position: _slideAnimation,
|
2025-08-22 07:12:09 -07:00
|
|
|
child: RefreshIndicator(
|
|
|
|
|
onRefresh: () async {
|
|
|
|
|
_initializeData();
|
|
|
|
|
_updateGreeting();
|
|
|
|
|
setState(() {});
|
|
|
|
|
},
|
|
|
|
|
color: accentColor,
|
|
|
|
|
backgroundColor: cardColor,
|
|
|
|
|
strokeWidth: 2.5,
|
|
|
|
|
displacement: 60,
|
|
|
|
|
child: CustomScrollView(
|
|
|
|
|
physics: const BouncingScrollPhysics(
|
|
|
|
|
parent: AlwaysScrollableScrollPhysics(),
|
|
|
|
|
),
|
|
|
|
|
slivers: [
|
|
|
|
|
SliverToBoxAdapter(
|
|
|
|
|
child: Container(
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
gradient: LinearGradient(
|
|
|
|
|
begin: Alignment.topCenter,
|
|
|
|
|
end: Alignment.bottomCenter,
|
|
|
|
|
colors: [
|
|
|
|
|
backgroundColor,
|
|
|
|
|
backgroundColor.withOpacity(0.95),
|
|
|
|
|
],
|
|
|
|
|
stops: const [0.0, 1.0],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
child: Padding(
|
2025-08-26 23:53:12 -07:00
|
|
|
padding: const EdgeInsets.fromLTRB(
|
|
|
|
|
24,
|
|
|
|
|
20,
|
|
|
|
|
24,
|
|
|
|
|
80,
|
|
|
|
|
), // Added bottom padding for navbar
|
2025-08-22 07:12:09 -07:00
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
2025-08-26 23:53:12 -07:00
|
|
|
GreetingHeader(
|
|
|
|
|
greetingText: _greetingText,
|
|
|
|
|
scaleAnimation: _scaleAnimation,
|
|
|
|
|
onEmailPressed:
|
|
|
|
|
() => _showTransactionEntryDialog('email'),
|
|
|
|
|
onVoicePressed:
|
|
|
|
|
() => _showTransactionEntryDialog('voice'),
|
|
|
|
|
),
|
2025-08-22 07:12:09 -07:00
|
|
|
_buildMainContent(),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
2025-08-12 21:52:42 -07:00
|
|
|
),
|
2025-08-06 20:28:19 -07:00
|
|
|
),
|
2025-08-22 07:12:09 -07:00
|
|
|
],
|
|
|
|
|
),
|
2025-08-06 20:28:19 -07:00
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
2025-08-26 23:53:12 -07:00
|
|
|
// Use bottomNavigationBar instead of floatingActionButton
|
|
|
|
|
bottomNavigationBar: CustomNavBar(
|
2025-08-06 20:28:19 -07:00
|
|
|
currentIndex: _selectedIndex,
|
|
|
|
|
onTap: (index) {
|
|
|
|
|
setState(() => _selectedIndex = index);
|
|
|
|
|
},
|
|
|
|
|
backgroundColor: backgroundColor,
|
|
|
|
|
accentColor: accentColor,
|
|
|
|
|
primaryColor: primaryColor,
|
|
|
|
|
cardColor: cardColor,
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|