Update: 2026-08-02 17:52:28

This commit is contained in:
Hamza-Ayed
2026-08-02 17:52:28 +03:00
parent b78a6797d5
commit 4620e84d34
96 changed files with 6250 additions and 476 deletions
@@ -229,7 +229,7 @@ class InviteScreen extends StatelessWidget {
final appName = 'Siro';
final isDriver = controller.selectedTab == 0;
final shareText = isDriver
? 'Join $appName as a driver! Use my referral code: ${rc.referralCode}\nDownload: ${AppLink.inviteRedirectUrl}?code=${rc.referralCode}&app=driver\n\n💡 Note: If the link is not clickable, save this number or reply to activate links!'
? 'Join $appName as a driver! Use my referral code: ${rc.referralCode}\n${AppLink.driverDownloadLinks}\n\n💡 Note: If the link is not clickable, save this number or reply to activate links!'
: 'Get a ride with $appName! Use my referral code: ${rc.referralCode} for a discount.\nDownload: ${AppLink.inviteRedirectUrl}?code=${rc.referralCode}&app=rider\n\n💡 Note: If the link is not clickable, save this number or reply to activate links!';
Share.share(shareText);
},
@@ -0,0 +1,235 @@
// food_delivery_home_page.dart — تبويب التوصيل: تفعيل وضع التوصيل، عروض واردة، مهام نشطة
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../constant/colors.dart';
import '../../constant/style.dart';
import '../../controller/food_delivery/food_delivery_controller.dart';
import '../../controller/food_delivery/food_delivery_models.dart';
import '../widgets/elevated_btn.dart';
import '../widgets/my_scafold.dart';
class FoodDeliveryHomePage extends StatelessWidget {
const FoodDeliveryHomePage({super.key});
@override
Widget build(BuildContext context) {
Get.put(FoodDeliveryController());
return GetBuilder<FoodDeliveryController>(
builder: (c) => MyScafolld(
title: 'Delivery'.tr,
isleading: true,
body: [
Column(
children: [
_modeToggleBar(c),
if (c.pendingOffers.isNotEmpty) _offersSection(c),
Expanded(
child: RefreshIndicator(
onRefresh: c.fetchActiveTasks,
child: c.isLoadingTasks && c.activeTasks.isEmpty
? const Center(child: CircularProgressIndicator())
: c.activeTasks.isEmpty
? _emptyState(c)
: ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: c.activeTasks.length,
itemBuilder: (_, i) => _taskCard(c, c.activeTasks[i]),
),
),
),
],
),
],
),
);
}
Widget _modeToggleBar(FoodDeliveryController c) {
return Container(
margin: const EdgeInsets.all(16),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration(
color: AppColor.cardColor,
borderRadius: BorderRadius.circular(14),
border: Border.all(color: AppColor.borderColor),
),
child: Row(
children: [
Icon(
c.isDeliveryModeEnabled ? Icons.delivery_dining_rounded : Icons.moped_outlined,
color: c.isDeliveryModeEnabled ? AppColor.greenColor : AppColor.grayColor,
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Delivery Mode'.tr, style: AppStyle.title.copyWith(fontWeight: FontWeight.bold)),
Text(
c.isDeliveryModeEnabled
? 'You will receive delivery offers'.tr
: 'Turn on to receive delivery offers'.tr,
style: AppStyle.subtitle,
),
],
),
),
c.isTogglingMode
? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2))
: Switch(
value: c.isDeliveryModeEnabled,
activeColor: AppColor.greenColor,
onChanged: (v) => c.toggleDeliveryMode(v),
),
],
),
);
}
Widget _offersSection(FoodDeliveryController c) {
return SizedBox(
height: 150,
child: ListView.builder(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(horizontal: 12),
itemCount: c.pendingOffers.length,
itemBuilder: (_, i) => _offerCard(c, c.pendingOffers[i]),
),
);
}
Widget _offerCard(FoodDeliveryController c, FoodDeliveryOffer offer) {
final isResponding = c.isRespondingToOffer(offer.orderId);
return Container(
width: 260,
margin: const EdgeInsets.symmetric(horizontal: 4),
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
color: AppColor.primaryColor,
borderRadius: BorderRadius.circular(16),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.15), blurRadius: 12, offset: const Offset(0, 4))],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const Icon(Icons.notifications_active_rounded, color: Colors.white, size: 18),
const SizedBox(width: 6),
Expanded(
child: Text('New Delivery Offer'.tr,
style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 13)),
),
Text('${offer.secondsRemaining}s', style: const TextStyle(color: Colors.amber, fontWeight: FontWeight.bold)),
],
),
const SizedBox(height: 6),
Text(offer.merchantNameAr,
style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 15),
maxLines: 1, overflow: TextOverflow.ellipsis),
Text(foodFormatPrice(offer.deliveryFee),
style: const TextStyle(color: Colors.white70, fontSize: 13)),
const Spacer(),
Row(
children: [
Expanded(
child: SizedBox(
height: 36,
child: isResponding
? const Center(child: SizedBox(width: 18, height: 18, child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white)))
: OutlinedButton(
style: OutlinedButton.styleFrom(side: const BorderSide(color: Colors.white54)),
onPressed: () => c.respondToOffer(offer.orderId, false),
child: Text('Reject'.tr, style: const TextStyle(color: Colors.white70, fontSize: 12)),
),
),
),
const SizedBox(width: 8),
Expanded(
child: SizedBox(
height: 36,
child: isResponding
? const SizedBox.shrink()
: MyElevatedButton(
title: 'Accept'.tr,
kolor: AppColor.greenColor,
onPressed: () => c.respondToOffer(offer.orderId, true),
),
),
),
],
),
],
),
);
}
Widget _emptyState(FoodDeliveryController c) {
return ListView(
children: [
const SizedBox(height: 100),
Icon(Icons.moped_outlined, size: 72, color: AppColor.grayColor),
const SizedBox(height: 16),
Center(child: Text('No delivery tasks right now'.tr, style: AppStyle.title)),
],
);
}
Widget _taskCard(FoodDeliveryController c, FoodDeliveryTask task) {
final isPickedUp = task.status == 'picked_up';
final isBusy = c.isTaskBusy(task.id);
return Card(
margin: const EdgeInsets.only(bottom: 14),
color: AppColor.cardColor,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
side: BorderSide(color: isPickedUp ? AppColor.greenColor : AppColor.borderColor, width: isPickedUp ? 1.5 : 1),
),
child: Padding(
padding: const EdgeInsets.all(14),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(isPickedUp ? Icons.location_on_rounded : Icons.storefront_rounded,
color: AppColor.accentColor),
const SizedBox(width: 8),
Expanded(
child: Text(
isPickedUp ? (task.deliveryAddress ?? '') : task.merchantNameAr,
style: AppStyle.title.copyWith(fontWeight: FontWeight.bold),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
Text(foodFormatPrice(task.deliveryFee), style: AppStyle.subtitle),
],
),
const SizedBox(height: 4),
Text(
isPickedUp ? 'Deliver to customer'.tr : (task.merchantAddress ?? ''),
style: AppStyle.subtitle,
),
const SizedBox(height: 12),
SizedBox(
width: double.infinity,
height: 44,
child: isBusy
? const Center(child: CircularProgressIndicator())
: MyElevatedButton(
title: isPickedUp ? 'Mark Delivered'.tr : 'Picked Up from Restaurant'.tr,
kolor: isPickedUp ? AppColor.greenColor : AppColor.accentColor,
onPressed: () => isPickedUp ? c.markDelivered(task.id) : c.markPickedUp(task.id),
),
),
],
),
),
);
}
}
@@ -33,6 +33,7 @@ import '../About Us/video_page.dart';
import '../assurance_health_page.dart';
import '../maintain_center_page.dart';
import '../../../transit/transit_driver_home_page.dart';
import '../../../food_delivery/food_delivery_home_page.dart';
// 1. إنشاء Class لتعريف بيانات كل عنصر في القائمة
class DrawerItem {
@@ -61,6 +62,11 @@ class AppDrawer extends StatelessWidget {
// icon: Icons.directions_bus_filled_rounded,
// color: Colors.teal,
// onTap: () => Get.to(() => const TransitDriverHomePage())),
DrawerItem(
title: 'Delivery'.tr,
icon: Icons.delivery_dining_rounded,
color: Colors.deepOrange,
onTap: () => Get.to(() => const FoodDeliveryHomePage())),
DrawerItem(
title: 'Balance'.tr,
icon: Icons.account_balance_wallet,