Update codebase
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import 'package:tripz_driver/constant/currency.dart';
|
||||
import 'package:siro_driver/constant/currency.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intaleq_maps/intaleq_maps.dart'; // لتحديد الأنواع إذا لزم
|
||||
|
||||
import '../widgets/scheduled_ride_badge.dart';
|
||||
import '../widgets/sms_ride_badge.dart';
|
||||
import '../../constant/box_name.dart';
|
||||
import '../../constant/colors.dart';
|
||||
import '../../constant/links.dart';
|
||||
@@ -144,8 +146,7 @@ class RideAvailableCard extends StatelessWidget {
|
||||
? "أرباحك أعلى هنا مقارنة بـ المنافسين"
|
||||
: null,
|
||||
extraAmount: _earningsExtra,
|
||||
currency:
|
||||
rideInfo['driver_earnings_currency']?.toString() ?? 'ل.س',
|
||||
currency: rideInfo['driver_earnings_currency']?.toString() ?? 'ل.س',
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_buildAcceptButton(),
|
||||
@@ -189,6 +190,18 @@ class RideAvailableCard extends StatelessWidget {
|
||||
.copyWith(color: AppColor.greenColor, fontSize: 13),
|
||||
),
|
||||
),
|
||||
// شارة الرحلة المجدولة — معلومة دائمة عن الرحلة، تظهر هنا
|
||||
// وفي نافذة الطلب والأوفرلي معاً.
|
||||
if (ScheduledRideBadge.isScheduled(rideInfo)) ...[
|
||||
const SizedBox(height: 8),
|
||||
ScheduledRideBadge(rideInfo: rideInfo, compact: true),
|
||||
],
|
||||
// راكب طلب برسالة نصية — لا يملك إنترنت، والاتصال هو
|
||||
// الوسيلة الوحيدة للتواصل معه.
|
||||
if (SmsRideBadge.isSmsRide(rideInfo)) ...[
|
||||
const SizedBox(height: 8),
|
||||
SmsRideBadge(rideInfo: rideInfo, compact: true),
|
||||
],
|
||||
if (rideInfo['has_steps']?.toString() == 'true') ...[
|
||||
const SizedBox(height: 8),
|
||||
Container(
|
||||
@@ -200,8 +213,7 @@ class RideAvailableCard extends StatelessWidget {
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.alt_route,
|
||||
color: Colors.orange.shade800, size: 14),
|
||||
Icon(Icons.alt_route, color: Colors.orange.shade800, size: 14),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
'متعددة التوقفات',
|
||||
@@ -262,26 +274,18 @@ class RideAvailableCard extends StatelessWidget {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
Theme.of(Get.context!).colorScheme.surfaceVariant.withOpacity(0.3),
|
||||
color: Theme.of(Get.context!).colorScheme.surfaceVariant.withOpacity(0.3),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: Theme.of(Get.context!).dividerColor.withOpacity(0.5)),
|
||||
border: Border.all(color: Theme.of(Get.context!).dividerColor.withOpacity(0.5)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
_infoItem(Icons.social_distance_rounded, '${rideInfo['distance']} KM',
|
||||
iconColor: AppColor.primaryColor),
|
||||
Container(
|
||||
height: 20, width: 1, color: Theme.of(Get.context!).dividerColor),
|
||||
_infoItem(
|
||||
Icons.access_time_filled_rounded, '${rideInfo['duration']} Min',
|
||||
iconColor: Colors.blueAccent),
|
||||
Container(
|
||||
height: 20, width: 1, color: Theme.of(Get.context!).dividerColor),
|
||||
_infoItem(Icons.star_rounded, '${rideInfo['passengerRate'] ?? 5.0}',
|
||||
iconColor: Colors.amber),
|
||||
_infoItem(Icons.social_distance_rounded, '${rideInfo['distance']} KM', iconColor: AppColor.primaryColor),
|
||||
Container(height: 20, width: 1, color: Theme.of(Get.context!).dividerColor),
|
||||
_infoItem(Icons.access_time_filled_rounded, '${rideInfo['duration']} Min', iconColor: Colors.blueAccent),
|
||||
Container(height: 20, width: 1, color: Theme.of(Get.context!).dividerColor),
|
||||
_infoItem(Icons.star_rounded, '${rideInfo['passengerRate'] ?? 5.0}', iconColor: Colors.amber),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,84 +1,108 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tripz_driver/controller/notification/notification_captain_controller.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:siro_driver/controller/notification/notification_captain_controller.dart';
|
||||
|
||||
import '../widgets/ui/siro_ui.dart';
|
||||
|
||||
class NotificationCaptain extends StatelessWidget {
|
||||
const NotificationCaptain({Key? key}) : super(key: key);
|
||||
const NotificationCaptain({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Get.put(NotificationCaptainController());
|
||||
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
middle: Text('Notifications'.tr),
|
||||
leading: CupertinoNavigationBarBackButton(
|
||||
onPressed: () => Get.back(),
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: GetBuilder<NotificationCaptainController>(
|
||||
builder: (notificationCaptainController) =>
|
||||
notificationCaptainController.isLoading
|
||||
? const Center(child: CupertinoActivityIndicator())
|
||||
: ListView.builder(
|
||||
itemCount: notificationCaptainController
|
||||
.notificationData['message'].length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
if (notificationCaptainController
|
||||
.notificationData['message'] ==
|
||||
"No notification data found") {
|
||||
_showCupertinoDialog(context, 'No Notifications',
|
||||
'There are no notifications at this time.');
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
var res = notificationCaptainController
|
||||
.notificationData['message'][index];
|
||||
return CupertinoListTile(
|
||||
leading: const Icon(CupertinoIcons.bell_fill),
|
||||
title: Text(
|
||||
res['title'],
|
||||
style:
|
||||
CupertinoTheme.of(context).textTheme.textStyle,
|
||||
),
|
||||
subtitle: Text(
|
||||
res['body'],
|
||||
style: CupertinoTheme.of(context)
|
||||
return SiroPage(
|
||||
title: 'Notifications'.tr,
|
||||
body: GetBuilder<NotificationCaptainController>(
|
||||
builder: (controller) {
|
||||
if (controller.isLoading) return const SiroLoading();
|
||||
|
||||
final data = controller.notificationData['message'];
|
||||
|
||||
// الردّ قد يكون نصاً ("No notification data found") لا قائمة.
|
||||
// كان الكود يقرأ `.length` عليه ثم يفتح حواراً من داخل `itemBuilder`
|
||||
// — أي أثناء البناء، وهو ما يرمي استثناءً بدل عرض حالة فراغ.
|
||||
final List items = data is List ? data : const [];
|
||||
|
||||
if (items.isEmpty) {
|
||||
return SiroEmptyState(
|
||||
icon: Icons.notifications_off_rounded,
|
||||
title: 'No Notifications'.tr,
|
||||
message: 'There are no notifications at this time.'.tr,
|
||||
);
|
||||
}
|
||||
|
||||
return ListView.builder(
|
||||
padding: SiroUi.pageInsets,
|
||||
itemCount: items.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final res = items[index];
|
||||
return SiroCard(
|
||||
onTap: () => _showDetails(
|
||||
context,
|
||||
res['title']?.toString() ?? '',
|
||||
res['body']?.toString() ?? '',
|
||||
() {
|
||||
controller.updateNotification(res['id'].toString());
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SiroIconBadge(Icons.notifications_rounded,
|
||||
color: SiroUi.interactive(context)),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
res['title']?.toString() ?? '',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.tabLabelTextStyle,
|
||||
.bodyMedium
|
||||
?.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
onTap: () {
|
||||
_showCupertinoDialog(
|
||||
context,
|
||||
res['title'],
|
||||
res['body'],
|
||||
onConfirm: () {
|
||||
notificationCaptainController
|
||||
.updateNotification(res['id'].toString());
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
res['body']?.toString() ?? '',
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showCupertinoDialog(BuildContext context, String title, String content,
|
||||
{VoidCallback? onConfirm}) {
|
||||
showCupertinoDialog(
|
||||
void _showDetails(BuildContext context, String title, String content,
|
||||
VoidCallback onConfirm) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => CupertinoAlertDialog(
|
||||
title: Text(title),
|
||||
content: Text(content),
|
||||
actions: <CupertinoDialogAction>[
|
||||
CupertinoDialogAction(
|
||||
child: const Text('OK'),
|
||||
onPressed: onConfirm ?? () => Navigator.of(context).pop(),
|
||||
builder: (BuildContext ctx) => AlertDialog(
|
||||
icon: SiroIconBadge(Icons.notifications_active_rounded,
|
||||
color: SiroUi.interactive(ctx), size: 22),
|
||||
title: Text(title, textAlign: TextAlign.center),
|
||||
content: Text(content, textAlign: TextAlign.center),
|
||||
actionsAlignment: MainAxisAlignment.center,
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(ctx).pop(),
|
||||
child: Text('Back'.tr,
|
||||
style: TextStyle(color: SiroUi.subtle(ctx))),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: onConfirm,
|
||||
child: Text('OK'.tr),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tripz_driver/constant/colors.dart';
|
||||
import 'package:tripz_driver/constant/style.dart';
|
||||
import 'package:siro_driver/constant/colors.dart';
|
||||
import 'package:siro_driver/constant/style.dart';
|
||||
|
||||
import '../../controller/notification/passenger_notification_controller.dart';
|
||||
import '../widgets/elevated_btn.dart';
|
||||
|
||||
Reference in New Issue
Block a user