Initial commit for Intaleq Driver

This commit is contained in:
Hamza-Ayed
2025-09-01 19:04:50 +03:00
parent 889c67a691
commit 8c7f3e3a75
46 changed files with 4300 additions and 6192 deletions

View File

@@ -95,7 +95,7 @@ class CardSeferWalletDriver extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'محفظة انطلق',
'رصيد انطلق',
style: AppStyle.headTitle.copyWith(
fontFamily: 'Amiri', // خط يوحي بالفخامة
color: Colors.white,

View File

@@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:sefer_driver/constant/colors.dart';
import 'package:sefer_driver/constant/style.dart';
import 'package:sefer_driver/views/widgets/my_scafold.dart';
import 'package:sefer_driver/views/widgets/mycircular.dart';
import 'package:sefer_driver/constant/style.dart'; // Assuming this has your text styles
import 'package:sefer_driver/views/widgets/mycircular.dart'; // Assuming this is your loading widget
import '../../../controller/payment/driver_payment_controller.dart';
@@ -12,43 +12,133 @@ class PaymentHistoryDriverPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Initialize your controller
Get.put(DriverWalletHistoryController());
return MyScafolld(
title: 'Payment History'.tr,
body: [
GetBuilder<DriverWalletHistoryController>(
builder: (controller) => controller.isLoading
? const MyCircularProgressIndicator()
: ListView.builder(
itemCount: controller.archive.length,
itemBuilder: (BuildContext context, int index) {
var list = controller.archive[index];
return Padding(
padding: const EdgeInsets.all(4),
child: Container(
decoration: BoxDecoration(
color: double.parse(list['amount']) < 0
? AppColor.redColor.withOpacity(.4)
: AppColor.greenColor.withOpacity(.4)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
list['amount'],
style: AppStyle.title,
),
Text(
list['created_at'],
style: AppStyle.title,
),
],
),
),
);
},
return Scaffold(
appBar: AppBar(
title: Text('Payment History'.tr),
backgroundColor: Colors.white,
elevation: 1,
),
backgroundColor: Colors.grey[100],
body: GetBuilder<DriverWalletHistoryController>(
builder: (controller) {
if (controller.isLoading) {
// Using your custom loading indicator
return const Center(child: MyCircularProgressIndicator());
}
if (controller.archive.isEmpty) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.account_balance_wallet_outlined,
size: 80, color: Colors.grey[400]),
const SizedBox(height: 16),
Text(
'No transactions yet'.tr,
style: Theme.of(context)
.textTheme
.headlineSmall
?.copyWith(color: Colors.grey[600]),
),
)
],
isleading: true);
],
),
);
}
return AnimationLimiter(
child: ListView.builder(
padding: const EdgeInsets.all(16.0),
itemCount: controller.archive.length,
itemBuilder: (BuildContext context, int index) {
var transaction = controller.archive[index];
return AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 375),
child: SlideAnimation(
verticalOffset: 50.0,
child: FadeInAnimation(
child: _TransactionCard(transaction: transaction),
),
),
);
},
),
);
},
),
);
}
}
// A dedicated widget for displaying a single transaction with a modern UI.
class _TransactionCard extends StatelessWidget {
final Map<String, dynamic> transaction;
const _TransactionCard({required this.transaction});
@override
Widget build(BuildContext context) {
// Safely parse the amount to avoid errors
final double amount =
double.tryParse(transaction['amount']?.toString() ?? '0') ?? 0;
final bool isCredit = amount >= 0;
final Color indicatorColor =
isCredit ? AppColor.greenColor : AppColor.redColor;
final IconData iconData =
isCredit ? Icons.arrow_upward_rounded : Icons.arrow_downward_rounded;
final String transactionType = (isCredit ? 'Credit'.tr : 'Debit'.tr).tr;
return Card(
elevation: 2,
shadowColor: Colors.black.withOpacity(0.05),
margin: const EdgeInsets.only(bottom: 12.0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
clipBehavior: Clip.antiAlias, // Ensures the color bar is clipped neatly
child: IntrinsicHeight(
// Ensures the color bar and content have the same height
child: Row(
children: [
// Left-side color indicator bar
Container(width: 6, color: indicatorColor),
Expanded(
child: ListTile(
leading: Icon(iconData, color: indicatorColor, size: 30),
title: Text(
// Use .abs() to remove the negative sign from the display
'${amount.abs().toStringAsFixed(2)} ${'SYP'.tr}',
style: AppStyle.title.copyWith(
fontWeight: FontWeight.bold,
color: Colors.black87,
),
),
subtitle: Text(
transaction['created_at'] ?? 'No date',
style: AppStyle.title.copyWith(
fontSize: 12,
color: Colors.grey[600],
),
),
trailing: Text(
transactionType,
style: AppStyle.title.copyWith(
fontSize: 14,
color: indicatorColor,
fontWeight: FontWeight.w600,
),
),
),
),
],
),
),
);
}
}

View File

@@ -47,7 +47,7 @@ class WalletCaptainRefactored extends StatelessWidget {
Widget build(BuildContext context) {
captainWalletController.refreshCaptainWallet();
return MyScafolld(
title: 'Driver Wallet'.tr,
title: 'Driver Balance'.tr,
isleading: true,
action: IconButton(
icon: const Icon(Icons.refresh),
@@ -173,7 +173,7 @@ class WalletCaptainRefactored extends StatelessWidget {
'This amount for all trip I get from Passengers'
.tr),
child: const Icon(Icons.headphones)),
'${'Total Amount:'.tr} ${controller.totalAmount} ${'S.P'.tr}',
'${'Total Amount:'.tr} ${controller.totalAmount} ${'SYP'.tr}',
'This amount for all trip I get from Passengers'.tr,
duration: const Duration(seconds: 6),
backgroundColor: AppColor.yellowColor,
@@ -195,7 +195,7 @@ class WalletCaptainRefactored extends StatelessWidget {
' Intaleq Wallet'.tr),
child: const Icon(Icons.headphones),
),
'${'Total Amount:'.tr} ${controller.totalAmountVisa} ${'S.P'.tr}',
'${'Total Amount:'.tr} ${controller.totalAmountVisa} ${'SYP'.tr}',
'This amount for all trip I get from Passengers and Collected For me in'
.tr +
' ${AppInformation.appName} Wallet'.tr,

View File

@@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:sefer_driver/constant/colors.dart';
import 'package:sefer_driver/constant/style.dart';
import 'package:sefer_driver/views/widgets/my_scafold.dart';
import 'package:sefer_driver/views/widgets/mycircular.dart';
import 'package:intl/intl.dart';
import '../../../controller/payment/driver_payment_controller.dart';
class WeeklyPaymentPage extends StatelessWidget {
@@ -14,128 +14,210 @@ class WeeklyPaymentPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
Get.put(DriverWalletHistoryController());
return MyScafolld(
title: 'Payment History'.tr,
body: [
GetBuilder<DriverWalletHistoryController>(
builder: (controller) => controller.isLoading
? const MyCircularProgressIndicator()
: Column(
children: [
Container(
width: Get.width * .8,
decoration: AppStyle.boxDecoration1,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
controller.weeklyList.isEmpty
? '0'
: controller.weeklyList[0]
['totalAmount']
.toString(),
style: AppStyle.number,
),
return Scaffold(
appBar: AppBar(
title: Text('Weekly Summary'.tr),
backgroundColor: Colors.white,
elevation: 1,
),
backgroundColor: Colors.grey[100],
body: GetBuilder<DriverWalletHistoryController>(
builder: (controller) {
if (controller.isLoading) {
return const Center(child: MyCircularProgressIndicator());
}
return Column(
children: [
// 1. Prominent Summary Card at the top
_buildSummaryCard(controller),
// 2. A title for the transactions list
Padding(
padding: const EdgeInsets.fromLTRB(20, 20, 20, 10),
child: Row(
children: [
Icon(Icons.list_alt, color: Colors.grey[600]),
const SizedBox(width: 8),
Text(
'Transactions this week'.tr,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
color: Colors.grey[700],
),
),
],
),
),
// 3. The animated list of transactions
Expanded(
child: controller.weeklyList.isEmpty
? _buildEmptyState(context)
: AnimationLimiter(
child: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
itemCount: controller.weeklyList.length,
itemBuilder: (BuildContext context, int index) {
var transaction = controller.weeklyList[index];
return AnimationConfiguration.staggeredList(
position: index,
duration: const Duration(milliseconds: 375),
child: SlideAnimation(
verticalOffset: 50.0,
child: FadeInAnimation(
child: _TransactionListItem(
transaction: transaction),
),
),
),
Text(
' Total weekly is '.tr,
style: AppStyle.title,
),
],
);
},
),
),
const SizedBox(
height: 10,
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 5),
child: SizedBox(
height: Get.height * .75,
child: controller.weeklyList.isNotEmpty
? ListView.builder(
itemCount: controller.weeklyList.length,
itemBuilder:
(BuildContext context, int index) {
var list = controller.weeklyList[index];
return Padding(
padding: const EdgeInsets.all(2.0),
child: Container(
decoration: AppStyle.boxDecoration1,
child: Padding(
padding: const EdgeInsets.all(4),
child: Column(
children: [
Card(
elevation: 2,
color: list['paymentMethod'] ==
'visa'
? AppColor.blueColor
: AppColor.secondaryColor,
child: Padding(
padding:
const EdgeInsets.all(8.0),
child: Text(
list['paymentMethod'] ==
'Remainder'
? 'Remainder'.tr
: list['paymentMethod'] ==
'fromBudget'
? 'fromBudget'.tr
: list[
'paymentMethod'],
style: AppStyle.title,
),
),
),
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Card(
child: Padding(
padding:
const EdgeInsets.all(
8.0),
child: Text(
list['amount'],
style: AppStyle.number,
),
),
),
Text(
DateFormat(
'yyyy-MM-dd hh:mm a')
.format(DateTime.parse(
list[
'dateUpdated'])),
style: AppStyle.number,
),
],
),
],
),
),
),
);
},
)
: const SizedBox(),
),
),
],
),
],
);
},
),
);
}
// A widget for the top summary card.
Widget _buildSummaryCard(DriverWalletHistoryController controller) {
final String totalAmount = controller.weeklyList.isEmpty
? '0.00'
: controller.weeklyList[0]['totalAmount']?.toString() ?? '0.00';
return Card(
margin: const EdgeInsets.all(16.0),
elevation: 4,
shadowColor: AppColor.primaryColor.withOpacity(0.2),
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
child: Container(
padding: const EdgeInsets.all(20.0),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [AppColor.primaryColor, AppColor.greenColor],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: Row(
children: [
const Icon(Icons.account_balance_wallet,
color: Colors.white, size: 40),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Total Weekly Earnings'.tr,
style: AppStyle.title
.copyWith(color: Colors.white70, fontSize: 16),
),
)
const SizedBox(height: 4),
Text(
'$totalAmount ${'SYP'.tr}',
style: AppStyle.number
.copyWith(color: Colors.white, fontSize: 32),
),
],
),
),
],
),
),
);
}
// A dedicated widget for the list item.
Widget _TransactionListItem({required Map<String, dynamic> transaction}) {
final String paymentMethod = transaction['paymentMethod'] ?? 'Unknown';
final String amount = transaction['amount']?.toString() ?? '0';
final DateTime? date = DateTime.tryParse(transaction['dateUpdated'] ?? '');
return Card(
elevation: 2,
shadowColor: Colors.black.withOpacity(0.05),
margin: const EdgeInsets.only(bottom: 12.0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
child: ListTile(
leading: CircleAvatar(
backgroundColor: AppColor.primaryColor.withOpacity(0.1),
child: Icon(_getPaymentIcon(paymentMethod),
color: AppColor.primaryColor, size: 22),
),
title: Text(
'$amount ${'SYP'.tr}',
style: AppStyle.title.copyWith(fontWeight: FontWeight.bold),
),
subtitle: Text(
date != null
? DateFormat('EEEE, hh:mm a', Get.locale?.toString())
.format(date) // e.g., Tuesday, 10:11 AM
: 'Invalid Date',
style: AppStyle.title.copyWith(fontSize: 12, color: Colors.grey[600]),
),
trailing: Chip(
label: Text(
_getTranslatedPaymentMethod(paymentMethod),
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w600),
),
backgroundColor: Colors.grey.shade200,
padding: const EdgeInsets.symmetric(horizontal: 6),
side: BorderSide.none,
),
),
);
}
Widget _buildEmptyState(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.receipt_long_outlined, size: 80, color: Colors.grey[400]),
const SizedBox(height: 16),
Text(
'No transactions this week'.tr,
style: Theme.of(context)
.textTheme
.headlineSmall
?.copyWith(color: Colors.grey[600]),
),
],
isleading: true);
),
);
}
// Helper to get a specific icon for each payment method.
IconData _getPaymentIcon(String paymentMethod) {
switch (paymentMethod.toLowerCase()) {
case 'visa':
return Icons.credit_card;
case 'frombudget':
return Icons.account_balance_wallet_outlined;
case 'remainder':
return Icons.receipt_long;
case 'cash':
return Icons.money;
default:
return Icons.payment;
}
}
// Helper to get translated or formatted payment method names.
String _getTranslatedPaymentMethod(String paymentMethod) {
switch (paymentMethod) {
case 'Remainder':
return 'Remainder'.tr;
case 'fromBudget':
return 'From Budget'.tr;
default:
return paymentMethod;
}
}
}