imprroved

This commit is contained in:
Vaibhav Surve 2025-12-13 14:34:02 +05:30 committed by Manish
parent e2fc81ba0e
commit 2aa6d13a71
2 changed files with 48 additions and 23 deletions

View File

@ -582,7 +582,6 @@ Widget build(BuildContext context) {
children: [ children: [
_quickActions(), _quickActions(),
MySpacing.height(20), MySpacing.height(20),
_sectionTitle('Modules'),
_dashboardModules(), _dashboardModules(),
MySpacing.height(20), MySpacing.height(20),
_sectionTitle('Reports & Analytics'), _sectionTitle('Reports & Analytics'),

View File

@ -56,6 +56,13 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
parent: _animController, parent: _animController,
curve: Curves.easeInOut, curve: Curves.easeInOut,
); );
// Add initial welcome message
_chatHistory.add({
'sender': 'ai',
'message':
'Hello! I am your AI assistant. How can I help you today? You can ask general questions or use the chart button below to analyze your monthly expenses.',
});
} }
// Scroll helper // Scroll helper
@ -152,6 +159,7 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
final placeholderIndex = _chatHistory.length - 1; final placeholderIndex = _chatHistory.length - 1;
try { try {
// NOTE: Assuming GeminiService.generateText handles the API call
final result = await GeminiService.generateText(promptText); final result = await GeminiService.generateText(promptText);
if (placeholderIndex >= 0 && if (placeholderIndex >= 0 &&
_chatHistory.length > placeholderIndex) { _chatHistory.length > placeholderIndex) {
@ -191,11 +199,16 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
try { try {
await widget.dashboardController.fetchMonthlyExpenses(); await widget.dashboardController.fetchMonthlyExpenses();
// NOTE: Assuming monthlyExpenseList contains a list of objects that have a .toJson() method
final rawDataList = widget.dashboardController.monthlyExpenseList; final rawDataList = widget.dashboardController.monthlyExpenseList;
if (rawDataList.isEmpty) { if (rawDataList.isEmpty) {
_error.value = "No monthly expense data found for analysis."; _error.value = "No monthly expense data found for analysis.";
_chatHistory.removeAt(placeholderIndex); if (placeholderIndex >= 0 &&
_chatHistory.length > placeholderIndex) {
_chatHistory.removeAt(placeholderIndex);
}
_isAnalyzingData.value = false;
return; return;
} }
@ -435,7 +448,7 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
), ),
onSubmitted: (_) => onSubmitted: (_) =>
_handlePromptSubmission(), _handlePromptSubmission(),
enabled: !_isAnalyzingData.value, enabled: !_isAnalyzingData.value && !_isLoading.value,
), ),
), ),
Obx( Obx(
@ -449,7 +462,7 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
.isEmpty) .isEmpty)
? null ? null
: _handlePromptSubmission, : _handlePromptSubmission,
icon: _isLoading.value icon: _isLoading.value && _promptController.text.trim().isNotEmpty // Show loading only for text submission
? SizedBox( ? SizedBox(
width: 18, width: 18,
height: 18, height: 18,
@ -493,17 +506,21 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
onPressed: _toggleOpen, onPressed: _toggleOpen,
heroTag: 'gemini_fab', heroTag: 'gemini_fab',
backgroundColor: contentTheme.primary, backgroundColor: contentTheme.primary,
icon: const Icon(LucideIcons.bot), icon: const Icon(LucideIcons.bot, color: Colors.white),
label: const Text( label: const Text(
'Ask Me Anything', 'Ask Me Anything',
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600), style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
color: Colors.white,
),
), ),
), ),
), ),
); );
} }
// Dim background when open // Dim background when open - Full screen scrim
Widget _buildScrim() { Widget _buildScrim() {
return Obx( return Obx(
() => _isOpen.value () => _isOpen.value
@ -511,8 +528,11 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
opacity: _opacityAnimation, opacity: _opacityAnimation,
child: GestureDetector( child: GestureDetector(
onTap: _toggleOpen, onTap: _toggleOpen,
child: Container( // Use Positioned.fill to guarantee it covers the entire Stack
color: Colors.black.withOpacity(0.25), child: const Positioned.fill(
child: ColoredBox(
color: Colors.black38, // Use Colors.black38 for 38% opacity, slightly stronger than 0.25
),
), ),
), ),
) )
@ -522,19 +542,25 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Stack( // Wrap the Stack in SizedBox.expand to force the widget to take the full space
children: [ // of its parent, which is typically the whole screen area in a dashboard.
// Scrim behind panel return SizedBox.expand(
_buildScrim(), child: Stack(
// Panel children: [
_buildFloatingPanel(context), // 1. Scrim (Background layer when open) - Now using Positioned.fill for reliability
// FAB _buildScrim(),
Positioned(
bottom: 16, // 2. Panel (Middle layer when open)
right: 16, _buildFloatingPanel(context),
child: _buildFab(),
), // 3. FAB (Top layer when closed)
], Positioned(
bottom: 16,
right: 16,
child: _buildFab(),
),
],
),
); );
} }
@ -545,4 +571,4 @@ class _GeminiFloatingAssistantState extends State<GeminiFloatingAssistant>
_animController.dispose(); _animController.dispose();
super.dispose(); super.dispose();
} }
} }