feat: add device authentication, place gates support, and PiP navigation features
This commit is contained in:
@@ -0,0 +1,503 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../../core/constants/app_colors.dart';
|
||||
|
||||
class AboutAwardsSheet extends StatelessWidget {
|
||||
const AboutAwardsSheet({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DraggableScrollableSheet(
|
||||
initialChildSize: 0.88,
|
||||
minChildSize: 0.5,
|
||||
maxChildSize: 0.96,
|
||||
builder: (context, scrollController) {
|
||||
return Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColors.canvasLight,
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(28)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x33000000),
|
||||
blurRadius: 30,
|
||||
offset: Offset(0, -6),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
// Top drag bar
|
||||
Center(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(top: 12, bottom: 8),
|
||||
width: 44,
|
||||
height: 4.5,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.borderGlass,
|
||||
borderRadius: BorderRadius.circular(3),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Scrollable content
|
||||
Expanded(
|
||||
child: ListView(
|
||||
controller: scrollController,
|
||||
padding: const EdgeInsets.fromLTRB(20, 8, 20, 36),
|
||||
children: [
|
||||
// ── 1. HEADER EMBLEM & TITLE ──
|
||||
Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: 110,
|
||||
height: 110,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: AppColors.pureWhite,
|
||||
border: Border.all(
|
||||
color: AppColors.urukGold.withValues(alpha: 0.45),
|
||||
width: 2,
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.urukGold.withValues(alpha: 0.2),
|
||||
blurRadius: 28,
|
||||
offset: const Offset(0, 8),
|
||||
),
|
||||
],
|
||||
),
|
||||
padding: const EdgeInsets.all(6),
|
||||
child: ClipOval(
|
||||
child: Image.asset(
|
||||
'assets/images/uruk_prize_logo.png',
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
Text(
|
||||
'جائزة أوروك الدولية',
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: AppColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
'URUK INTERNATIONAL PRIZE',
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.urukGoldDark,
|
||||
letterSpacing: 1.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 6),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.urukGoldLight,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(color: AppColors.urukGoldBorder),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.workspace_premium_rounded,
|
||||
size: 16,
|
||||
color: AppColors.urukGoldDark,
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
'تكريم التميز والسيادة التكنولوجية',
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 11.5,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.urukGoldDark,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// ── 2. ORIGIN & GENESIS STORY ──
|
||||
_buildSectionCard(
|
||||
icon: Icons.history_edu_rounded,
|
||||
iconColor: AppColors.urukGoldDark,
|
||||
title: 'قصة المنظومة: من أوروك إلى سيادة البيانات',
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'تستلهم جائزة أوروك الدولية إرثها من حضارة أوروك العظيمة — مهد أول تدوين للرموز والتخطيط العمراني في فجر الحضارة البشرية — لتكريم المشروعات التي تصنع فارقاً استراتيجياً في العالم العربي.',
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 12.5,
|
||||
height: 1.65,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: AppColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
'من رحم هذا البرنامج وتتويجاً لتكريم جائزة أوروك، وُلدت منظومة «خرائط أوروك - Uruk Map» كبنية تحتية سيادية بديلة ومستقلة تماماً، مصممة لحماية السيادة المكانية وتوفير خرائط وملاحة ذكية مخصصة لمنطقة الشرق الأوسط وشمال أفريقيا دون الارتهان للشركات العالمية.',
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 12.5,
|
||||
height: 1.65,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: AppColors.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// ── 3. TECH ARCHITECT & FOUNDER ──
|
||||
_buildSectionCard(
|
||||
icon: Icons.person_pin_circle_rounded,
|
||||
iconColor: AppColors.appleBlue,
|
||||
title: 'القيادة التقنية والمعمارية للمنظومة',
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 44,
|
||||
height: 44,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: AppColors.appleBlue.withValues(alpha: 0.1),
|
||||
border: Border.all(color: AppColors.appleBlue.withValues(alpha: 0.3)),
|
||||
),
|
||||
child: const Icon(Icons.architecture_rounded, color: AppColors.appleBlue, size: 24),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'م. حمزة عايد | Hamza Ayed',
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.textPrimary,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Founding Tech Architect & Mobility Strategist',
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.appleBlue,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
'خبير استراتيجي في حركية النقل الذكي وتأسيس منظومات البيانات الحساسة بخبرة قيادية تتجاوز 20 عاماً في إدارة العمليات والأنظمة الحرجة، والمؤسس التقني المشارك لمنصات انطلق (Intaleq)، تريبز (Tripz)، ومنظومة سيرو (Siro Platform).',
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 12,
|
||||
height: 1.6,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: AppColors.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// ── 4. ECONOMIC MOAT & UNIT ECONOMICS ──
|
||||
_buildSectionCard(
|
||||
icon: Icons.account_balance_wallet_rounded,
|
||||
iconColor: AppColors.tacticalEmerald,
|
||||
title: 'الأثر الاقتصادي والتوسع الإقليمي',
|
||||
child: Column(
|
||||
children: [
|
||||
_buildStatRow(
|
||||
metric: '0.30\$+',
|
||||
metricLabel: 'وفر مباشر في كل رحلة وطلب',
|
||||
desc: 'استبدال فواتير Google Maps الباهظة بنظام ذاتي الاستضافة والتحكم الكامل.',
|
||||
color: AppColors.tacticalEmerald,
|
||||
),
|
||||
const Divider(height: 20, color: AppColors.borderSubtle),
|
||||
_buildStatRow(
|
||||
metric: 'MENA',
|
||||
metricLabel: 'استهداف الأسواق المحرومة من خرائط موثوقة',
|
||||
desc: 'توفير ملاحة ذكية وبنية خرائط مستقلة في العراق، السودان، اليمن، سوريا، وإيران.',
|
||||
color: AppColors.urukGoldDark,
|
||||
),
|
||||
const Divider(height: 20, color: AppColors.borderSubtle),
|
||||
_buildStatRow(
|
||||
metric: '100%',
|
||||
metricLabel: 'سيادة رقمية وعزل جغرافي',
|
||||
desc: 'خوادم متجهات وتوجيه محلي (Self-Hosted OSRM + Vector Tiles) مستقلة عن أي قيود أو واجهات أجنبية.',
|
||||
color: AppColors.appleBlue,
|
||||
),
|
||||
const Divider(height: 20, color: AppColors.borderSubtle),
|
||||
_buildStatRow(
|
||||
metric: 'OFFLINE',
|
||||
metricLabel: 'ملاحة ذكية كاملة دون اتصال',
|
||||
desc: 'مواصلة التوجيه والانعطاف حتى في مناطق انعدام التغطية الخلوية والصحراوية.',
|
||||
color: AppColors.sovereignGold,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// ── 5. URUK EDITION APP ICON SHOWCASE ──
|
||||
Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF131722),
|
||||
borderRadius: BorderRadius.circular(22),
|
||||
border: Border.all(color: AppColors.urukGoldBorder),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.18),
|
||||
blurRadius: 18,
|
||||
offset: const Offset(0, 6),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 60,
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: AppColors.urukGold.withValues(alpha: 0.4)),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
child: Image.asset(
|
||||
'assets/images/siro_uruk_logo.png',
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 14),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'شعار إصدار أوروك الخاص',
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.pureWhite,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'دمج جناح تمثال أوروك الذهبي مع سهم الملاحة الفضائي وخطوط الارتفاع الطبوغرافية.',
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 10.5,
|
||||
color: const Color(0xFFB0B5C0),
|
||||
height: 1.4,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// ── 6. ACTIONS & SHARE ──
|
||||
ElevatedButton.icon(
|
||||
onPressed: () {
|
||||
Clipboard.setData(const ClipboardData(text: 'https://intaleqapp.com/hamza.html'));
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
'تم نسخ رابط الملف التنفيذي ودراسة المنظومة بنجاح',
|
||||
style: TextStyle(fontSize: 12),
|
||||
),
|
||||
backgroundColor: AppColors.tacticalEmerald,
|
||||
duration: Duration(seconds: 2),
|
||||
),
|
||||
);
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColors.textPrimary,
|
||||
foregroundColor: AppColors.pureWhite,
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
elevation: 0,
|
||||
),
|
||||
icon: const Icon(Icons.link_rounded, size: 18, color: AppColors.urukGold),
|
||||
label: Text(
|
||||
'نسخ رابط ملف المشروع ودراسة الحالة التنفيذية',
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 10),
|
||||
|
||||
OutlinedButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
style: OutlinedButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(vertical: 13),
|
||||
side: const BorderSide(color: AppColors.borderSubtle),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'إغلاق والعودة للخريطة',
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.textSecondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSectionCard({
|
||||
required IconData icon,
|
||||
required Color iconColor,
|
||||
required String title,
|
||||
required Widget child,
|
||||
}) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(18),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.pureWhite,
|
||||
borderRadius: BorderRadius.circular(22),
|
||||
border: Border.all(color: AppColors.borderSubtle),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Color(0x0A000000),
|
||||
blurRadius: 16,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 32,
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
color: iconColor.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Icon(icon, size: 18, color: iconColor),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
title,
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 13.5,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
child,
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatRow({
|
||||
required String metric,
|
||||
required String metricLabel,
|
||||
required String desc,
|
||||
required Color color,
|
||||
}) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
constraints: const BoxConstraints(minWidth: 70),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: color.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
metric,
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: color,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
metricLabel,
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
desc,
|
||||
style: GoogleFonts.alexandria(
|
||||
fontSize: 11,
|
||||
color: AppColors.textSecondary,
|
||||
height: 1.4,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../core/constants/app_colors.dart';
|
||||
import '../../../../core/services/pip_service.dart';
|
||||
import '../../../../logic/cubits/navigation/navigation_state.dart';
|
||||
|
||||
class ActiveNavHudWidget extends StatelessWidget {
|
||||
@@ -235,32 +236,39 @@ class ActiveNavHudWidget extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
state.formattedRemainingDuration,
|
||||
style: const TextStyle(
|
||||
fontFamily: '.SF Pro Text',
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: AppColors.tacticalEmerald,
|
||||
FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: Alignment.centerRight,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
state.formattedRemainingDuration,
|
||||
style: const TextStyle(
|
||||
fontFamily: '.SF Pro Text',
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: AppColors.tacticalEmerald,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'• ${state.formattedRemainingDistance}',
|
||||
style: const TextStyle(
|
||||
fontFamily: '.SF Pro Text',
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.textSecondary,
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
'• ${state.formattedRemainingDistance}',
|
||||
style: const TextStyle(
|
||||
fontFamily: '.SF Pro Text',
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.textSecondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
'وصول متوقع: ${state.arrivalTime}',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontFamily: '.SF Pro Text',
|
||||
fontSize: 11,
|
||||
@@ -273,30 +281,58 @@ class ActiveNavHudWidget extends StatelessWidget {
|
||||
),
|
||||
// Mute Button
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
padding: const EdgeInsets.all(4),
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed: onToggleMute,
|
||||
icon: Icon(
|
||||
state.isMuted ? Icons.volume_off_rounded : Icons.volume_up_rounded,
|
||||
color: state.isMuted ? AppColors.textMuted : AppColors.appleBlue,
|
||||
size: 24,
|
||||
size: 22,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
// Vehicle Customizer
|
||||
if (onOpenVehicleCustomizer != null)
|
||||
if (onOpenVehicleCustomizer != null) ...[
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
padding: const EdgeInsets.all(4),
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed: onOpenVehicleCustomizer,
|
||||
icon: const Icon(
|
||||
Icons.directions_car_filled_rounded,
|
||||
color: AppColors.appleBlue,
|
||||
size: 22,
|
||||
size: 21,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
],
|
||||
// Picture-in-Picture Mode
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
padding: const EdgeInsets.all(4),
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed: () {
|
||||
PipService.instance.enterPictureInPicture();
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.picture_in_picture_alt_rounded,
|
||||
color: AppColors.appleBlue,
|
||||
size: 21,
|
||||
),
|
||||
tooltip: 'تصغير النافذة (Picture-in-Picture)',
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
// Recenter Map
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
padding: const EdgeInsets.all(4),
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed: onRecenter,
|
||||
icon: const Icon(
|
||||
Icons.my_location_rounded,
|
||||
color: AppColors.textSecondary,
|
||||
size: 22,
|
||||
size: 21,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
|
||||
@@ -55,7 +55,7 @@ class _AddPlaceSheetState extends State<AddPlaceSheet> {
|
||||
),
|
||||
const SizedBox(height: 18),
|
||||
const Text(
|
||||
'إضافة مكان جديد إلى خرائط سيرو',
|
||||
'إضافة مكان جديد إلى خرائط أوروك',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w700),
|
||||
),
|
||||
|
||||
@@ -7,6 +7,8 @@ class ExplorePanelWidget extends StatelessWidget {
|
||||
const ExplorePanelWidget({super.key, required this.onCategorySelected});
|
||||
|
||||
static const List<Map<String, dynamic>> _categories = [
|
||||
{'title': 'مولات', 'query': 'مول', 'icon': Icons.local_mall_rounded},
|
||||
{'title': 'مستشفيات', 'query': 'مستشفى', 'icon': Icons.local_hospital_rounded},
|
||||
{'title': 'مطاعم', 'query': 'مطعم', 'icon': Icons.restaurant_rounded},
|
||||
{'title': 'كافيهات', 'query': 'مقهى', 'icon': Icons.local_cafe_rounded},
|
||||
{'title': 'وقود', 'query': 'محطة وقود', 'icon': Icons.local_gas_station_rounded},
|
||||
|
||||
@@ -6,12 +6,14 @@ class LayerSelectorSheet extends StatelessWidget {
|
||||
final MapThemeType currentTheme;
|
||||
final ValueChanged<MapThemeType> onThemeChanged;
|
||||
final VoidCallback? onOpenVehicleCustomizer;
|
||||
final VoidCallback? onOpenAboutAwards;
|
||||
|
||||
const LayerSelectorSheet({
|
||||
super.key,
|
||||
required this.currentTheme,
|
||||
required this.onThemeChanged,
|
||||
this.onOpenVehicleCustomizer,
|
||||
this.onOpenAboutAwards,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -67,9 +69,9 @@ class LayerSelectorSheet extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
if (onOpenVehicleCustomizer != null) ...[
|
||||
const SizedBox(height: 20),
|
||||
const SizedBox(height: 18),
|
||||
const Divider(height: 1, color: AppColors.borderSubtle),
|
||||
const SizedBox(height: 16),
|
||||
const SizedBox(height: 14),
|
||||
ListTile(
|
||||
onTap: onOpenVehicleCustomizer,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
@@ -98,6 +100,45 @@ class LayerSelectorSheet extends StatelessWidget {
|
||||
trailing: const Icon(Icons.arrow_forward_ios_rounded, size: 14, color: AppColors.textMuted),
|
||||
),
|
||||
],
|
||||
if (onOpenAboutAwards != null) ...[
|
||||
const SizedBox(height: 10),
|
||||
ListTile(
|
||||
onTap: onOpenAboutAwards,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
side: const BorderSide(color: AppColors.urukGoldBorder),
|
||||
),
|
||||
tileColor: AppColors.urukGoldLight,
|
||||
leading: Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.pureWhite,
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(color: AppColors.urukGold.withValues(alpha: 0.4)),
|
||||
),
|
||||
child: ClipOval(
|
||||
child: Image.asset(
|
||||
'assets/images/uruk_prize_logo.png',
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
title: const Text(
|
||||
'جائزة أوروك الدولية واعتماد المنظومة',
|
||||
style: TextStyle(
|
||||
fontSize: 13.5,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.urukGoldDark,
|
||||
),
|
||||
),
|
||||
subtitle: const Text(
|
||||
'قصة نشأة المشروع، السيادة الرقمية، والمعمار التقني',
|
||||
style: TextStyle(fontSize: 11, color: AppColors.textSecondary),
|
||||
),
|
||||
trailing: const Icon(Icons.workspace_premium_rounded, size: 20, color: AppColors.urukGoldDark),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../core/constants/app_colors.dart';
|
||||
import '../../../../logic/cubits/navigation/navigation_state.dart';
|
||||
|
||||
/// Ultra-compact, luxury floating Navigation HUD tailored for Picture-in-Picture (PiP)
|
||||
/// and In-App floating mini-navigation mode on iOS & Android.
|
||||
class PipNavHudWidget extends StatelessWidget {
|
||||
final NavigationState state;
|
||||
final VoidCallback? onExpand;
|
||||
final VoidCallback? onStopNavigation;
|
||||
|
||||
const PipNavHudWidget({
|
||||
super.key,
|
||||
required this.state,
|
||||
this.onExpand,
|
||||
this.onStopNavigation,
|
||||
});
|
||||
|
||||
IconData _getManeuverIcon(int sign) {
|
||||
switch (sign) {
|
||||
case -3:
|
||||
return Icons.turn_sharp_left_rounded;
|
||||
case -2:
|
||||
return Icons.turn_left_rounded;
|
||||
case -1:
|
||||
return Icons.turn_slight_left_rounded;
|
||||
case 1:
|
||||
return Icons.turn_slight_right_rounded;
|
||||
case 2:
|
||||
return Icons.turn_right_rounded;
|
||||
case 3:
|
||||
return Icons.turn_sharp_right_rounded;
|
||||
case 4:
|
||||
return Icons.flag_rounded;
|
||||
case 6:
|
||||
return Icons.roundabout_right_rounded;
|
||||
case -7:
|
||||
case 7:
|
||||
return Icons.u_turn_left_rounded;
|
||||
case 8:
|
||||
return Icons.u_turn_right_rounded;
|
||||
case 0:
|
||||
default:
|
||||
return Icons.straight_rounded;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final int sign = state.currentManeuverModifier;
|
||||
final String instruction = state.currentInstruction.isNotEmpty
|
||||
? state.currentInstruction
|
||||
: 'تابع السير على المسار';
|
||||
final int speed = state.speed.clamp(0, 260).round();
|
||||
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xF518181A), // Deep luxury iOS & Android dark glass
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: Colors.white.withValues(alpha: 0.15), width: 1),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.45),
|
||||
blurRadius: 14,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: onExpand,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// ── 1. TOP TIER: MANEUVER BADGE + DISTANCE + INSTRUCTION + ACTIONS ──
|
||||
Row(
|
||||
children: [
|
||||
// Turn Maneuver Icon Badge
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
gradient: const LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: [
|
||||
AppColors.tacticalEmerald,
|
||||
Color(0xFF009624),
|
||||
],
|
||||
),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.tacticalEmerald.withValues(alpha: 0.4),
|
||||
blurRadius: 6,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Icon(
|
||||
_getManeuverIcon(sign),
|
||||
color: Colors.white,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
|
||||
// Distance & Instruction
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
state.formattedDistanceToStep,
|
||||
style: const TextStyle(
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.w900,
|
||||
color: Colors.white,
|
||||
height: 1.1,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
instruction,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white.withValues(alpha: 0.9),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
|
||||
// Expand Button
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
padding: const EdgeInsets.all(4),
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed: onExpand,
|
||||
icon: const Icon(
|
||||
Icons.open_in_full_rounded,
|
||||
color: AppColors.appleBlue,
|
||||
size: 19,
|
||||
),
|
||||
tooltip: 'تكبير للشاشة الكاملة',
|
||||
),
|
||||
|
||||
// Stop Navigation Button
|
||||
if (onStopNavigation != null) ...[
|
||||
const SizedBox(width: 4),
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
padding: const EdgeInsets.all(4),
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed: onStopNavigation,
|
||||
icon: const Icon(
|
||||
Icons.close_rounded,
|
||||
color: AppColors.coralDanger,
|
||||
size: 19,
|
||||
),
|
||||
tooltip: 'إنهاء الملاحة',
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 6),
|
||||
|
||||
// ── 2. BOTTOM TIER: TRIP ETA & SPEED BAR (OVERFLOW-PROOF) ──
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3.5),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withValues(alpha: 0.08),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Text(
|
||||
'${state.formattedRemainingDuration} • ${state.formattedRemainingDistance}',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 10.5,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.textSecondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 1.5),
|
||||
decoration: BoxDecoration(
|
||||
color: (speed > 100 ? AppColors.coralDanger : AppColors.tacticalEmerald)
|
||||
.withValues(alpha: 0.2),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(
|
||||
'$speed كم/س',
|
||||
style: TextStyle(
|
||||
fontSize: 9.5,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: speed > 100 ? AppColors.coralDanger : AppColors.tacticalEmerald,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intaleq_maps/intaleq_maps.dart';
|
||||
import '../../../../core/constants/app_colors.dart';
|
||||
import '../../../../core/services/location_service.dart';
|
||||
import '../../../../data/models/place_gate.dart';
|
||||
import '../../../../data/models/place_model.dart';
|
||||
|
||||
class PlaceGatesSheet extends StatelessWidget {
|
||||
final PlaceModel place;
|
||||
final LatLng? userLocation;
|
||||
final Function(PlaceGate gate) onSelectGate;
|
||||
final VoidCallback onSelectMainPlace;
|
||||
|
||||
const PlaceGatesSheet({
|
||||
super.key,
|
||||
required this.place,
|
||||
this.userLocation,
|
||||
required this.onSelectGate,
|
||||
required this.onSelectMainPlace,
|
||||
});
|
||||
|
||||
IconData _getGateIcon(PlaceGate gate) {
|
||||
final name = gate.nameAr.toLowerCase();
|
||||
if (name.contains('طوارئ') || name.contains('طوارئ')) {
|
||||
return Icons.emergency_rounded;
|
||||
}
|
||||
if (name.contains('كارفور') || name.contains('سوق') || name.contains('تسوق')) {
|
||||
return Icons.shopping_bag_rounded;
|
||||
}
|
||||
if (name.contains('زوار') || name.contains('مراجعين')) {
|
||||
return Icons.people_alt_rounded;
|
||||
}
|
||||
if (name.contains('مواقف') || name.contains('كراج') || name.contains('سفلي')) {
|
||||
return Icons.local_parking_rounded;
|
||||
}
|
||||
return Icons.door_sliding_rounded;
|
||||
}
|
||||
|
||||
String? _getFormattedDistance(PlaceGate gate) {
|
||||
if (userLocation == null) return null;
|
||||
final distM = LocationService.instance.calculateDistance(
|
||||
userLocation!,
|
||||
LatLng(gate.latitude, gate.longitude),
|
||||
);
|
||||
if (distM >= 1000) {
|
||||
return '${(distM / 1000).toStringAsFixed(1)} كم';
|
||||
}
|
||||
return '${distM.round()} م';
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final sortedGates = List<PlaceGate>.from(place.gates)
|
||||
..sort((a, b) {
|
||||
if (a.isMainGate && !b.isMainGate) return -1;
|
||||
if (!a.isMainGate && b.isMainGate) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
return Container(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: MediaQuery.of(context).size.height * 0.65,
|
||||
),
|
||||
decoration: const BoxDecoration(
|
||||
color: AppColors.pureWhite,
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(28)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x24000000),
|
||||
blurRadius: 32,
|
||||
offset: Offset(0, -8),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: SafeArea(
|
||||
top: false,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// Top Drag Handle
|
||||
Center(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(top: 12, bottom: 8),
|
||||
width: 44,
|
||||
height: 5,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black12,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Header Section
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 6, 20, 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 48,
|
||||
height: 48,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.appleBlue.withValues(alpha: 0.12),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.meeting_room_rounded,
|
||||
color: AppColors.appleBlue,
|
||||
size: 26,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 14),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: Text(
|
||||
place.name,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: AppColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.appleBlue.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Text(
|
||||
'${place.gates.length} بوابات',
|
||||
style: const TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.appleBlue,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
const Text(
|
||||
'اختر البوابة أو المدخل الأقرب لوجهتك المحددة',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: AppColors.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
const Divider(height: 1, color: AppColors.borderSubtle),
|
||||
|
||||
// Gates List
|
||||
Flexible(
|
||||
child: ListView.separated(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
shrinkWrap: true,
|
||||
itemCount: sortedGates.length,
|
||||
separatorBuilder: (_, __) => const SizedBox(height: 8),
|
||||
itemBuilder: (context, index) {
|
||||
final gate = sortedGates[index];
|
||||
final distStr = _getFormattedDistance(gate);
|
||||
final isEmergency = gate.nameAr.contains('طوارئ');
|
||||
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
onSelectGate(gate);
|
||||
},
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||
decoration: BoxDecoration(
|
||||
color: gate.isMainGate
|
||||
? AppColors.appleBlue.withValues(alpha: 0.05)
|
||||
: AppColors.canvasLight,
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
border: Border.all(
|
||||
color: gate.isMainGate
|
||||
? AppColors.appleBlue.withValues(alpha: 0.3)
|
||||
: AppColors.borderSubtle,
|
||||
width: gate.isMainGate ? 1.5 : 1.0,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
// Gate Icon
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: isEmergency
|
||||
? AppColors.coralDanger.withValues(alpha: 0.12)
|
||||
: (gate.isMainGate
|
||||
? AppColors.tacticalEmerald.withValues(alpha: 0.12)
|
||||
: Colors.white),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Icon(
|
||||
_getGateIcon(gate),
|
||||
color: isEmergency
|
||||
? AppColors.coralDanger
|
||||
: (gate.isMainGate ? AppColors.tacticalEmerald : AppColors.textSecondary),
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 14),
|
||||
// Gate Name
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: Text(
|
||||
gate.nameAr,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: gate.isMainGate ? FontWeight.w800 : FontWeight.w700,
|
||||
color: isEmergency ? AppColors.coralDanger : AppColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (gate.isMainGate) ...[
|
||||
const SizedBox(width: 8),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.tacticalEmerald.withValues(alpha: 0.15),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: const Text(
|
||||
'رئيسية',
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.tacticalEmerald,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (gate.nameEn != null && gate.nameEn!.isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 2),
|
||||
child: Text(
|
||||
gate.nameEn!,
|
||||
style: const TextStyle(
|
||||
fontSize: 11,
|
||||
color: AppColors.textMuted,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// Distance badge
|
||||
if (distStr != null) ...[
|
||||
Text(
|
||||
distStr,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.textSecondary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
],
|
||||
|
||||
const Icon(
|
||||
Icons.arrow_forward_ios_rounded,
|
||||
size: 14,
|
||||
color: AppColors.textMuted,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
// General Destination Option
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 6, 16, 12),
|
||||
child: TextButton.icon(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
onSelectMainPlace();
|
||||
},
|
||||
icon: const Icon(Icons.place_outlined, size: 18, color: AppColors.textSecondary),
|
||||
label: const Text(
|
||||
'التوجه إلى الموقع العام للمجمع',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.textSecondary,
|
||||
),
|
||||
),
|
||||
style: TextButton.styleFrom(
|
||||
minimumSize: const Size(double.infinity, 44),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user