Update: 2026-07-06 03:51:32

This commit is contained in:
Hamza-Ayed
2026-07-06 03:51:32 +03:00
parent ff49586d6d
commit cadc26518b
@@ -93,8 +93,8 @@ class CarDetailsTypeToChoose extends StatelessWidget {
right: 0, right: 0,
child: ClipRRect( child: ClipRRect(
borderRadius: const BorderRadius.only( borderRadius: const BorderRadius.only(
topLeft: Radius.circular(28), topLeft: Radius.circular(24),
topRight: Radius.circular(28), topRight: Radius.circular(24),
), ),
child: BackdropFilter( child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 12, sigmaY: 12), filter: ImageFilter.blur(sigmaX: 12, sigmaY: 12),
@@ -102,8 +102,8 @@ class CarDetailsTypeToChoose extends StatelessWidget {
decoration: BoxDecoration( decoration: BoxDecoration(
color: AppColor.secondaryColor.withAlpha(240), color: AppColor.secondaryColor.withAlpha(240),
borderRadius: const BorderRadius.only( borderRadius: const BorderRadius.only(
topLeft: Radius.circular(28), topLeft: Radius.circular(24),
topRight: Radius.circular(28), topRight: Radius.circular(24),
), ),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
@@ -120,9 +120,9 @@ class CarDetailsTypeToChoose extends StatelessWidget {
// ── Drag Handle ────────────────────────────────────── // ── Drag Handle ──────────────────────────────────────
Center( Center(
child: Container( child: Container(
width: 40, width: 32,
height: 4, height: 3,
margin: const EdgeInsets.only(top: 8, bottom: 4), margin: const EdgeInsets.only(top: 6, bottom: 2),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.grey.shade300, color: Colors.grey.shade300,
borderRadius: BorderRadius.circular(2), borderRadius: BorderRadius.circular(2),
@@ -138,18 +138,18 @@ class CarDetailsTypeToChoose extends StatelessWidget {
// ── Car Selection List ─────────────────────────────── // ── Car Selection List ───────────────────────────────
SizedBox( SizedBox(
height: 115, height: 90,
child: ListView.builder( child: ListView.builder(
physics: const BouncingScrollPhysics(), physics: const BouncingScrollPhysics(),
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
padding: const EdgeInsets.fromLTRB(20, 4, 20, 6), padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
itemCount: carTypes.length, itemCount: carTypes.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final carType = carTypes[index]; final carType = carTypes[index];
final isSelected = controller.selectedIndex == index; final isSelected = controller.selectedIndex == index;
return Padding( return Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(
right: index < carTypes.length - 1 ? 10 : 0), right: index < carTypes.length - 1 ? 8 : 0),
child: _buildCarCard( child: _buildCarCard(
context, controller, carType, isSelected, index), context, controller, carType, isSelected, index),
); );
@@ -162,7 +162,7 @@ class CarDetailsTypeToChoose extends StatelessWidget {
controller.savingsLabel!.isNotEmpty) controller.savingsLabel!.isNotEmpty)
Padding( Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 4), horizontal: 16, vertical: 2),
child: CompetitorPriceBadge( child: CompetitorPriceBadge(
savingsLabel: controller.savingsLabel, savingsLabel: controller.savingsLabel,
savingsPercent: controller.savingsPercent ?? 0.0, savingsPercent: controller.savingsPercent ?? 0.0,
@@ -172,7 +172,7 @@ class CarDetailsTypeToChoose extends StatelessWidget {
// ── Promo Code & Actions ───────────────────────────── // ── Promo Code & Actions ─────────────────────────────
_buildPromoButton(context, controller), _buildPromoButton(context, controller),
SizedBox(height: MediaQuery.of(context).padding.bottom + 4), SizedBox(height: MediaQuery.of(context).padding.bottom),
], ],
), ),
), ),
@@ -187,88 +187,79 @@ class CarDetailsTypeToChoose extends StatelessWidget {
// ═══════════════════════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════════════════════
Widget _buildHeader(RideLifecycleController controller) { Widget _buildHeader(RideLifecycleController controller) {
return Padding( return Padding(
padding: const EdgeInsets.fromLTRB(22, 2, 22, 4), padding: const EdgeInsets.fromLTRB(16, 0, 16, 2),
child: Column( child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Expanded(
children: [ child: Row(
// Title children: [
Expanded( Text(
child: Text(
'Choose your ride'.tr, 'Choose your ride'.tr,
style: AppStyle.headTitle.copyWith( style: AppStyle.headTitle.copyWith(
fontSize: 20, fontSize: 17,
fontWeight: FontWeight.w800, fontWeight: FontWeight.w800,
letterSpacing: 0.3, letterSpacing: 0.3,
), ),
), ),
), const SizedBox(width: 8),
// Close button // Distance chip
GestureDetector( _buildStatChip(
onTap: () { icon: Icons.route_rounded,
controller.isBottomSheetShown = false; value: '${controller.distance.toStringAsFixed(1)} ${'KM'.tr}',
controller.update(); color: AppColor.primaryColor,
},
child: Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: Get.isDarkMode
? Colors.white.withOpacity(0.08)
: Colors.grey.shade100,
shape: BoxShape.circle,
),
child: Icon(Icons.close_rounded,
size: 18, color: AppColor.grayColor),
), ),
), const SizedBox(width: 6),
], // Duration chip
_buildStatChip(
icon: Icons.schedule_rounded,
value: controller.hours > 0
? '${controller.hours}h ${controller.minutes}m'
: '${controller.minutes} ${'min'.tr}',
color: const Color(0xFF6366F1),
),
],
),
), ),
const SizedBox(height: 6), if (controller.selectedIndex >= 0 &&
// Trip Stats Row controller.selectedIndex < carTypes.length)
Row( Container(
children: [ padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
// Distance chip margin: const EdgeInsets.only(right: 6),
_buildStatChip( decoration: BoxDecoration(
icon: Icons.route_rounded, gradient: LinearGradient(
value: '${controller.distance.toStringAsFixed(1)} ${'KM'.tr}', colors: [
color: AppColor.primaryColor, AppColor.primaryColor,
), AppColor.primaryColor.withAlpha(200),
const SizedBox(width: 8), ],
// Duration chip
_buildStatChip(
icon: Icons.schedule_rounded,
value: controller.hours > 0
? '${controller.hours}h ${controller.minutes}m'
: '${controller.minutes} ${'min'.tr}',
color: const Color(0xFF6366F1), // Indigo
),
const Spacer(),
// Price preview for selected car
if (controller.selectedIndex >= 0 &&
controller.selectedIndex < carTypes.length)
Container(
padding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
AppColor.primaryColor,
AppColor.primaryColor.withAlpha(200),
],
),
borderRadius: BorderRadius.circular(20),
),
child: Text(
'${_getPassengerPriceText(carTypes[controller.selectedIndex], controller)} ${CurrencyHelper.currency}',
style: const TextStyle(
color: Colors.white,
fontSize: 13,
fontWeight: FontWeight.w700,
),
),
), ),
], borderRadius: BorderRadius.circular(16),
),
child: Text(
'${_getPassengerPriceText(carTypes[controller.selectedIndex], controller)} ${CurrencyHelper.currency}',
style: const TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w700,
),
),
),
// Close button
GestureDetector(
onTap: () {
controller.isBottomSheetShown = false;
controller.update();
},
child: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Get.isDarkMode
? Colors.white.withOpacity(0.08)
: Colors.grey.shade100,
shape: BoxShape.circle,
),
child: Icon(Icons.close_rounded,
size: 16, color: AppColor.grayColor),
),
), ),
], ],
), ),
@@ -278,21 +269,21 @@ class CarDetailsTypeToChoose extends StatelessWidget {
Widget _buildStatChip( Widget _buildStatChip(
{required IconData icon, required String value, required Color color}) { {required IconData icon, required String value, required Color color}) {
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 3),
decoration: BoxDecoration( decoration: BoxDecoration(
color: color.withAlpha(20), color: color.withAlpha(20),
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(14),
border: Border.all(color: color.withAlpha(50)), border: Border.all(color: color.withAlpha(50)),
), ),
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Icon(icon, size: 14, color: color), Icon(icon, size: 11, color: color),
const SizedBox(width: 5), const SizedBox(width: 4),
Text( Text(
value, value,
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 11,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
color: color, color: color,
), ),
@@ -316,7 +307,7 @@ class CarDetailsTypeToChoose extends StatelessWidget {
child: AnimatedContainer( child: AnimatedContainer(
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
curve: Curves.easeOutCubic, curve: Curves.easeOutCubic,
width: 105, width: 88,
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: isSelected gradient: isSelected
? LinearGradient( ? LinearGradient(
@@ -329,20 +320,20 @@ class CarDetailsTypeToChoose extends StatelessWidget {
) )
: null, : null,
color: isSelected ? null : AppColor.secondaryColor, color: isSelected ? null : AppColor.secondaryColor,
borderRadius: BorderRadius.circular(18), borderRadius: BorderRadius.circular(14),
border: Border.all( border: Border.all(
color: isSelected color: isSelected
? AppColor.primaryColor ? AppColor.primaryColor
: AppColor.grayColor.withOpacity(0.25), : AppColor.grayColor.withOpacity(0.25),
width: isSelected ? 2.5 : 1.5, width: isSelected ? 2 : 1.2,
), ),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
color: isSelected color: isSelected
? AppColor.primaryColor.withAlpha(50) ? AppColor.primaryColor.withAlpha(50)
: Colors.black.withAlpha(16), : Colors.black.withAlpha(12),
blurRadius: isSelected ? 14 : 6, blurRadius: isSelected ? 10 : 4,
offset: const Offset(0, 3), offset: const Offset(0, 2),
), ),
], ],
), ),
@@ -351,11 +342,11 @@ class CarDetailsTypeToChoose extends StatelessWidget {
// Selected indicator // Selected indicator
if (isSelected) if (isSelected)
Positioned( Positioned(
top: 5, top: 3,
right: 5, right: 3,
child: Container( child: Container(
width: 22, width: 18,
height: 22, height: 18,
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient: LinearGradient(
colors: [ colors: [
@@ -367,31 +358,31 @@ class CarDetailsTypeToChoose extends StatelessWidget {
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
color: AppColor.primaryColor.withAlpha(60), color: AppColor.primaryColor.withAlpha(60),
blurRadius: 6, blurRadius: 4,
), ),
], ],
), ),
child: const Icon(Icons.check, size: 13, color: Colors.white), child: const Icon(Icons.check, size: 11, color: Colors.white),
), ),
), ),
// Card content // Card content
Padding( Padding(
padding: const EdgeInsets.fromLTRB(8, 8, 8, 8), padding: const EdgeInsets.fromLTRB(6, 6, 6, 6),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
// Car image // Car image
AnimatedScale( AnimatedScale(
scale: isSelected ? 1.12 : 1.0, scale: isSelected ? 1.1 : 1.0,
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
child: Image.asset( child: Image.asset(
carType.image, carType.image,
height: 44, height: 34,
fit: BoxFit.contain, fit: BoxFit.contain,
), ),
), ),
const SizedBox(height: 2), const SizedBox(height: 1),
// Car name // Car name
FittedBox( FittedBox(
@@ -401,7 +392,7 @@ class CarDetailsTypeToChoose extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontWeight: fontWeight:
isSelected ? FontWeight.w800 : FontWeight.w600, isSelected ? FontWeight.w800 : FontWeight.w600,
fontSize: 13, fontSize: 11,
color: isSelected color: isSelected
? AppColor.primaryColor ? AppColor.primaryColor
: AppColor.writeColor, : AppColor.writeColor,
@@ -410,17 +401,17 @@ class CarDetailsTypeToChoose extends StatelessWidget {
), ),
), ),
const SizedBox(height: 2), const SizedBox(height: 1),
// Price tag // Price tag
Container( Container(
padding: padding:
const EdgeInsets.symmetric(horizontal: 8, vertical: 2), const EdgeInsets.symmetric(horizontal: 6, vertical: 1),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isSelected color: isSelected
? AppColor.primaryColor ? AppColor.primaryColor
: AppColor.writeColor.withOpacity(0.05), : AppColor.writeColor.withOpacity(0.05),
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(8),
border: isSelected border: isSelected
? null ? null
: Border.all( : Border.all(
@@ -430,7 +421,7 @@ class CarDetailsTypeToChoose extends StatelessWidget {
child: Text( child: Text(
'${_getPassengerPriceText(carType, controller)} ${CurrencyHelper.currency}', '${_getPassengerPriceText(carType, controller)} ${CurrencyHelper.currency}',
style: TextStyle( style: TextStyle(
fontSize: 14.5, fontSize: 12,
fontWeight: FontWeight.w800, fontWeight: FontWeight.w800,
color: isSelected color: isSelected
? Colors.white ? Colors.white
@@ -456,14 +447,14 @@ class CarDetailsTypeToChoose extends StatelessWidget {
if (controller.promoTaken) return const SizedBox.shrink(); if (controller.promoTaken) return const SizedBox.shrink();
return Padding( return Padding(
padding: const EdgeInsets.fromLTRB(20, 4, 20, 2), padding: const EdgeInsets.fromLTRB(16, 2, 16, 0),
child: Material( child: Material(
color: Colors.transparent, color: Colors.transparent,
child: InkWell( child: InkWell(
onTap: () => _showPromoCodeDialog(context, controller), onTap: () => _showPromoCodeDialog(context, controller),
borderRadius: BorderRadius.circular(14), borderRadius: BorderRadius.circular(12),
child: Container( child: Container(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 10),
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient: LinearGradient(
colors: [ colors: [
@@ -471,49 +462,39 @@ class CarDetailsTypeToChoose extends StatelessWidget {
Colors.orange.shade50, Colors.orange.shade50,
], ],
), ),
borderRadius: BorderRadius.circular(14), borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.amber.shade200), border: Border.all(color: Colors.amber.shade200),
), ),
child: Row( child: Row(
children: [ children: [
Container( Container(
padding: const EdgeInsets.all(7), padding: const EdgeInsets.all(5),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.amber.shade100, color: Colors.amber.shade100,
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: Icon(Icons.percent_rounded, child: Icon(Icons.percent_rounded,
color: Colors.amber.shade800, size: 16), color: Colors.amber.shade800, size: 14),
), ),
const SizedBox(width: 12), const SizedBox(width: 8),
Expanded( Expanded(
child: Column( child: Text(
crossAxisAlignment: CrossAxisAlignment.start, 'Have a Promo Code?'.tr,
children: [ style: TextStyle(
Text( fontSize: 12,
'Have a Promo Code?'.tr, fontWeight: FontWeight.w700,
style: TextStyle( color: Colors.amber.shade900,
fontSize: 13, ),
fontWeight: FontWeight.w700,
color: Colors.amber.shade900,
),
),
Text(
'Tap to apply your discount'.tr,
style: TextStyle(
fontSize: 11, color: Colors.amber.shade700),
),
],
), ),
), ),
Container( Container(
padding: const EdgeInsets.all(4), padding: const EdgeInsets.all(3),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.amber.shade100, color: Colors.amber.shade100,
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(6),
), ),
child: Icon(Icons.arrow_forward_ios_rounded, child: Icon(Icons.arrow_forward_ios_rounded,
size: 12, color: Colors.amber.shade800), size: 10, color: Colors.amber.shade800),
), ),
], ],
), ),
@@ -531,32 +512,32 @@ class CarDetailsTypeToChoose extends StatelessWidget {
double.tryParse(box.read(BoxName.passengerWalletTotal) ?? '0.0') ?? 0.0; double.tryParse(box.read(BoxName.passengerWalletTotal) ?? '0.0') ?? 0.0;
if (passengerWallet < 0.0) { if (passengerWallet < 0.0) {
return Container( return Container(
margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 6), margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 3),
padding: const EdgeInsets.all(12), padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.red.shade50, color: Colors.red.shade50,
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.red.shade200), border: Border.all(color: Colors.red.shade200),
), ),
child: Row( child: Row(
children: [ children: [
Container( Container(
padding: const EdgeInsets.all(6), padding: const EdgeInsets.all(4),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.red.shade100, color: Colors.red.shade100,
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: Icon(Icons.warning_amber_rounded, child: Icon(Icons.warning_amber_rounded,
color: Colors.red.shade700, size: 18), color: Colors.red.shade700, size: 14),
), ),
const SizedBox(width: 10), const SizedBox(width: 8),
Expanded( Expanded(
child: Text( child: Text(
'${'You have a negative balance of'.tr} ${passengerWallet.toStringAsFixed(2)} ${CurrencyHelper.currency}.', '${'You have a negative balance of'.tr} ${passengerWallet.toStringAsFixed(2)} ${CurrencyHelper.currency}.',
style: TextStyle( style: TextStyle(
color: Colors.red.shade800, color: Colors.red.shade800,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontSize: 12, fontSize: 11,
), ),
), ),
), ),