Files
intaleq_driver/lib/views/home/statistics/widgets/daily_goal_widget.dart

308 lines
11 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../../constant/finance_design_system.dart';
import '../../../../controller/gamification/gamification_controller.dart';
class DailyGoalWidget extends StatelessWidget {
final GamificationController controller;
const DailyGoalWidget({super.key, required this.controller});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(FinanceDesignSystem.cardRadius),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.03),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: controller.isDailyGoalMet
? FinanceDesignSystem.successGreen.withOpacity(0.1)
: FinanceDesignSystem.accentBlue.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: Icon(
controller.isDailyGoalMet
? Icons.check_circle_rounded
: Icons.track_changes_rounded,
color: controller.isDailyGoalMet
? FinanceDesignSystem.successGreen
: FinanceDesignSystem.accentBlue,
size: 20,
),
),
const SizedBox(width: 12),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Daily Goal'.tr,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: FinanceDesignSystem.primaryDark,
),
),
Text(
'الهدف اليومي'.tr,
style: TextStyle(
fontSize: 11,
color: Colors.grey.shade500,
),
),
],
),
],
),
// زر تعديل الهدف
InkWell(
onTap: () => _showSetGoalDialog(context),
borderRadius: BorderRadius.circular(8),
child: Container(
padding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(8),
),
child: Text(
controller.dailyGoal > 0
? 'Edit'.tr
: 'Set Goal'.tr,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: FinanceDesignSystem.accentBlue,
),
),
),
),
],
),
const SizedBox(height: 20),
// مبلغ الأرباح والهدف
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Text(
controller.dailyEarnings.toStringAsFixed(0),
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.w900,
color: controller.isDailyGoalMet
? FinanceDesignSystem.successGreen
: FinanceDesignSystem.primaryDark,
fontFamily: 'digit',
),
),
const SizedBox(width: 6),
Text(
'/ ${controller.dailyGoal.toStringAsFixed(0)} ${'SYP'.tr}',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.grey.shade400,
),
),
],
),
const SizedBox(height: 14),
// شريط التقدم
Stack(
children: [
Container(
height: 12,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(6),
),
),
LayoutBuilder(
builder: (context, constraints) {
return AnimatedContainer(
duration: const Duration(milliseconds: 800),
curve: Curves.easeOutCubic,
height: 12,
width: constraints.maxWidth * controller.dailyGoalProgress,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: controller.isDailyGoalMet
? [
FinanceDesignSystem.successGreen,
const Color(0xFF69F0AE)
]
: [
FinanceDesignSystem.accentBlue,
const Color(0xFF82B1FF)
],
),
borderRadius: BorderRadius.circular(6),
boxShadow: [
BoxShadow(
color: (controller.isDailyGoalMet
? FinanceDesignSystem.successGreen
: FinanceDesignSystem.accentBlue)
.withOpacity(0.3),
blurRadius: 6,
offset: const Offset(0, 2),
),
],
),
);
},
),
],
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${(controller.dailyGoalProgress * 100).toStringAsFixed(0)}%',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: controller.isDailyGoalMet
? FinanceDesignSystem.successGreen
: FinanceDesignSystem.accentBlue,
),
),
if (controller.isDailyGoalMet)
Row(
children: [
const Icon(Icons.celebration_rounded,
color: Color(0xFFFFD700), size: 14),
const SizedBox(width: 4),
Text(
'Goal Achieved!'.tr,
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: FinanceDesignSystem.successGreen,
),
),
],
)
else
Text(
'${'Remaining:'.tr} ${(controller.dailyGoal - controller.dailyEarnings).clamp(0, double.infinity).toStringAsFixed(0)} ${'SYP'.tr}',
style: TextStyle(
fontSize: 11,
color: Colors.grey.shade500,
),
),
],
),
],
),
);
}
void _showSetGoalDialog(BuildContext context) {
final textController = TextEditingController(
text: controller.dailyGoal > 0
? controller.dailyGoal.toStringAsFixed(0)
: '',
);
Get.defaultDialog(
title: 'Set Daily Goal'.tr,
titleStyle: FinanceDesignSystem.headingStyle,
content: Column(
children: [
Text(
'How much do you want to earn today?'.tr,
style: FinanceDesignSystem.subHeadingStyle,
textAlign: TextAlign.center,
),
const SizedBox(height: 16),
TextField(
controller: textController,
keyboardType: TextInputType.number,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
fontFamily: 'digit',
),
decoration: InputDecoration(
hintText: '5000',
suffixText: 'SYP'.tr,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide:
BorderSide(color: Colors.grey.shade300),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide:
const BorderSide(color: FinanceDesignSystem.accentBlue),
),
),
),
const SizedBox(height: 12),
// الأهداف السريعة
Wrap(
spacing: 8,
children: [1000, 3000, 5000, 10000].map((goal) {
return ActionChip(
label: Text('$goal'),
labelStyle: const TextStyle(fontSize: 12),
backgroundColor: FinanceDesignSystem.accentBlue.withOpacity(0.1),
side: BorderSide.none,
onPressed: () {
textController.text = goal.toString();
},
);
}).toList(),
),
],
),
confirm: ElevatedButton(
onPressed: () {
double? goal = double.tryParse(textController.text);
if (goal != null && goal > 0) {
controller.setDailyGoal(goal);
Get.back();
}
},
style: ElevatedButton.styleFrom(
backgroundColor: FinanceDesignSystem.accentBlue,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12)),
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 12),
),
child: Text('Save'.tr),
),
cancel: TextButton(
onPressed: () => Get.back(),
child: Text('Cancel'.tr,
style: const TextStyle(color: Colors.grey)),
),
);
}
}