Update: 2026-07-10 16:09:37
This commit is contained in:
@@ -7,7 +7,6 @@ import 'package:get/get.dart';
|
||||
import 'package:intaleq_maps/intaleq_maps.dart';
|
||||
import 'package:siro_rider/constant/box_name.dart';
|
||||
import 'package:siro_rider/constant/table_names.dart';
|
||||
import 'package:siro_rider/views/widgets/elevated_btn.dart';
|
||||
|
||||
import '../../../constant/colors.dart';
|
||||
import '../../../constant/style.dart';
|
||||
@@ -15,7 +14,6 @@ import '../../../controller/functions/toast.dart';
|
||||
import '../../../controller/home/map/location_search_controller.dart';
|
||||
import '../../../controller/home/map/map_engine_controller.dart';
|
||||
import '../../../controller/home/map/ride_lifecycle_controller.dart';
|
||||
import '../../../controller/home/map/ride_state.dart';
|
||||
import '../../../main.dart';
|
||||
|
||||
// ---------------------------------------------------
|
||||
@@ -119,55 +117,94 @@ class _SearchFieldState extends State<_SearchField> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const Color accent = Color(0xFFEF4444); // matches the red destination dot
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
controller: widget.controller.placeDestinationController,
|
||||
onChanged: _onSearchChanged,
|
||||
decoration: InputDecoration(
|
||||
hintText: widget.controller.hintTextDestinationPoint,
|
||||
hintStyle: AppStyle.subtitle.copyWith(color: Colors.grey[600]),
|
||||
prefixIcon: Icon(Icons.search, color: AppColor.primaryColor),
|
||||
suffixIcon: widget
|
||||
.controller.placeDestinationController.text.isNotEmpty
|
||||
? IconButton(
|
||||
icon: Icon(Icons.clear, color: Colors.grey[400]),
|
||||
onPressed: () {
|
||||
widget.controller.placeDestinationController.clear();
|
||||
},
|
||||
)
|
||||
: null,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0, vertical: 10.0),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
borderSide: BorderSide.none,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 6.0),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(6),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(colors: [
|
||||
accent.withOpacity(0.08),
|
||||
accent.withOpacity(0.03),
|
||||
]),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: accent.withOpacity(0.35), width: 1.4),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 34,
|
||||
height: 34,
|
||||
decoration: BoxDecoration(
|
||||
color: accent,
|
||||
shape: BoxShape.circle,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: accent.withOpacity(0.4),
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 3)),
|
||||
],
|
||||
),
|
||||
child:
|
||||
const Icon(Icons.flag_rounded, color: Colors.white, size: 17),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
controller: widget.controller.placeDestinationController,
|
||||
onChanged: _onSearchChanged,
|
||||
style: const TextStyle(
|
||||
fontSize: 14.5, fontWeight: FontWeight.w700),
|
||||
decoration: InputDecoration(
|
||||
hintText: widget.controller.hintTextDestinationPoint,
|
||||
hintStyle: AppStyle.subtitle.copyWith(
|
||||
color: accent.withOpacity(0.85),
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 14.5,
|
||||
),
|
||||
isDense: true,
|
||||
suffixIcon: widget
|
||||
.controller.placeDestinationController.text.isNotEmpty
|
||||
? IconButton(
|
||||
icon: Icon(Icons.clear, color: Colors.grey[400]),
|
||||
onPressed: () {
|
||||
widget.controller.placeDestinationController
|
||||
.clear();
|
||||
},
|
||||
)
|
||||
: null,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
border: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
filled: false,
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
borderSide: BorderSide(color: AppColor.primaryColor),
|
||||
),
|
||||
filled: true,
|
||||
fillColor: Colors.grey[50],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8.0),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
widget.mapEngine.changeMainBottomMenuMap();
|
||||
widget.mapEngine.changePickerShown();
|
||||
},
|
||||
icon: Icon(Icons.location_on_outlined,
|
||||
color: AppColor.accentColor, size: 30),
|
||||
tooltip: widget.rideLifecycle.isAnotherOreder
|
||||
? 'Pick destination on map'.tr
|
||||
: 'Pick on map'.tr,
|
||||
),
|
||||
],
|
||||
const SizedBox(width: 6.0),
|
||||
InkWell(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
onTap: () {
|
||||
widget.mapEngine.changeMainBottomMenuMap();
|
||||
widget.mapEngine.changePickerShown();
|
||||
},
|
||||
child: Tooltip(
|
||||
message: widget.rideLifecycle.isAnotherOreder
|
||||
? 'Pick destination on map'.tr
|
||||
: 'Pick on map'.tr,
|
||||
child: Container(
|
||||
width: 36,
|
||||
height: 36,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: accent.withOpacity(0.3)),
|
||||
),
|
||||
child: Icon(Icons.map_rounded, color: accent, size: 18),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intaleq_maps/intaleq_maps.dart';
|
||||
|
||||
import '../../../constant/colors.dart';
|
||||
import '../../../constant/style.dart';
|
||||
import '../../../controller/home/map/location_search_controller.dart';
|
||||
import '../../../controller/home/map/map_engine_controller.dart';
|
||||
@@ -16,64 +15,104 @@ GetBuilder<LocationSearchController> formSearchPlacesStart() {
|
||||
id: 'start_point_form',
|
||||
builder: (controller) {
|
||||
final mapEngine = Get.find<MapEngineController>();
|
||||
const Color accent = Color(0xFF16A34A); // green: "their" pickup point
|
||||
return Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
controller: controller.placeStartController,
|
||||
onChanged: (value) {
|
||||
if (controller.placeStartController.text.length > 2) {
|
||||
controller.getPlacesStart();
|
||||
} else if (controller.placeStartController.text.isEmpty) {
|
||||
controller.clearPlacesStart();
|
||||
}
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Search for a starting point'.tr,
|
||||
hintStyle:
|
||||
AppStyle.subtitle.copyWith(color: Colors.grey[600]),
|
||||
prefixIcon:
|
||||
Icon(Icons.search, color: AppColor.primaryColor),
|
||||
suffixIcon: controller.placeStartController.text.isNotEmpty
|
||||
? IconButton(
|
||||
icon: Icon(Icons.clear, color: Colors.grey[400]),
|
||||
onPressed: () {
|
||||
controller.placeStartController.clear();
|
||||
controller.clearPlacesStart();
|
||||
},
|
||||
)
|
||||
: null,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0, vertical: 10.0),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
borderSide: BorderSide.none,
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 6.0),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(6),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(colors: [
|
||||
accent.withOpacity(0.08),
|
||||
accent.withOpacity(0.03),
|
||||
]),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(color: accent.withOpacity(0.35), width: 1.4),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 34,
|
||||
height: 34,
|
||||
decoration: BoxDecoration(
|
||||
color: accent,
|
||||
shape: BoxShape.circle,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: accent.withOpacity(0.4),
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 3)),
|
||||
],
|
||||
),
|
||||
child: const Icon(Icons.person_pin_circle_rounded,
|
||||
color: Colors.white, size: 18),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
controller: controller.placeStartController,
|
||||
style: const TextStyle(
|
||||
fontSize: 14.5, fontWeight: FontWeight.w700),
|
||||
onChanged: (value) {
|
||||
if (controller.placeStartController.text.length > 2) {
|
||||
controller.getPlacesStart();
|
||||
} else if (controller
|
||||
.placeStartController.text.isEmpty) {
|
||||
controller.clearPlacesStart();
|
||||
}
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Search for a starting point'.tr,
|
||||
hintStyle: AppStyle.subtitle.copyWith(
|
||||
color: accent.withOpacity(0.85),
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 14.5,
|
||||
),
|
||||
isDense: true,
|
||||
suffixIcon: controller
|
||||
.placeStartController.text.isNotEmpty
|
||||
? IconButton(
|
||||
icon:
|
||||
Icon(Icons.clear, color: Colors.grey[400]),
|
||||
onPressed: () {
|
||||
controller.placeStartController.clear();
|
||||
controller.clearPlacesStart();
|
||||
},
|
||||
)
|
||||
: null,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
border: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
filled: false,
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
borderSide: BorderSide(color: AppColor.primaryColor),
|
||||
),
|
||||
filled: true,
|
||||
fillColor: Colors.grey[50],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8.0),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
controller.passengerStartLocationFromMap = true;
|
||||
mapEngine.changeMainBottomMenuMap();
|
||||
mapEngine.changePickerShown();
|
||||
},
|
||||
icon: Icon(Icons.location_on_outlined,
|
||||
color: AppColor.accentColor, size: 30),
|
||||
tooltip: 'Pick start point on map'.tr,
|
||||
),
|
||||
],
|
||||
const SizedBox(width: 6.0),
|
||||
InkWell(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
onTap: () {
|
||||
controller.passengerStartLocationFromMap = true;
|
||||
mapEngine.changeMainBottomMenuMap();
|
||||
mapEngine.changePickerShown();
|
||||
},
|
||||
child: Tooltip(
|
||||
message: 'Pick start point on map'.tr,
|
||||
child: Container(
|
||||
width: 36,
|
||||
height: 36,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: accent.withOpacity(0.3)),
|
||||
),
|
||||
child: Icon(Icons.map_rounded, color: accent, size: 18),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
AnimatedContainer(
|
||||
@@ -96,7 +135,8 @@ GetBuilder<LocationSearchController> formSearchPlacesStart() {
|
||||
var address = res['address'] ?? 'Details not available';
|
||||
|
||||
return ListTile(
|
||||
leading: const Icon(Icons.place, size: 30, color: Colors.grey),
|
||||
leading:
|
||||
const Icon(Icons.place, size: 30, color: Colors.grey),
|
||||
title: Text(title,
|
||||
style: AppStyle.subtitle
|
||||
.copyWith(fontWeight: FontWeight.w500)),
|
||||
@@ -106,8 +146,8 @@ GetBuilder<LocationSearchController> formSearchPlacesStart() {
|
||||
var latitude = res['latitude'];
|
||||
var longitude = res['longitude'];
|
||||
if (latitude != null && longitude != null) {
|
||||
controller.passengerLocation =
|
||||
LatLng(double.parse(latitude), double.parse(longitude));
|
||||
controller.passengerLocation = LatLng(
|
||||
double.parse(latitude), double.parse(longitude));
|
||||
controller.placeStartController.text = title;
|
||||
controller.clearPlacesStart();
|
||||
mapEngine.changeMainBottomMenuMap();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'dart:ui' show ImageFilter;
|
||||
import 'package:siro_rider/print.dart';
|
||||
import 'package:siro_rider/views/widgets/my_textField.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:siro_rider/constant/box_name.dart';
|
||||
@@ -74,7 +73,6 @@ class _D {
|
||||
],
|
||||
stops: const [0.0, 0.5, 1.0],
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
@@ -1050,65 +1048,91 @@ class _OrderTypeButton extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final rideLifecycle = Get.find<RideLifecycleController>();
|
||||
final bool isOther = mapEngine.isAnotherOreder;
|
||||
final Color accent =
|
||||
isOther ? Colors.indigo.shade500 : AppColor.primaryColor;
|
||||
const MaterialColor accent = Colors.indigo;
|
||||
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
showCupertinoModalPopup(
|
||||
context: context,
|
||||
builder: (ctx) => CupertinoActionSheet(
|
||||
title: Text('Select Order Type'.tr),
|
||||
actions: [
|
||||
CupertinoActionSheetAction(
|
||||
child: Text('I want to order for myself'.tr),
|
||||
onPressed: () {
|
||||
mapEngine.changeisAnotherOreder(false);
|
||||
rideLifecycle.isAnotherOreder = false;
|
||||
Navigator.pop(ctx);
|
||||
},
|
||||
),
|
||||
CupertinoActionSheetAction(
|
||||
child: Text('I want to order for someone else'.tr),
|
||||
onPressed: () {
|
||||
mapEngine.changeisAnotherOreder(true);
|
||||
rideLifecycle.isAnotherOreder = true;
|
||||
Navigator.pop(ctx);
|
||||
},
|
||||
),
|
||||
],
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
isDefaultAction: true,
|
||||
onPressed: () => Navigator.pop(ctx),
|
||||
child: Text('Cancel'.tr)),
|
||||
),
|
||||
);
|
||||
},
|
||||
borderRadius: BorderRadius.circular(_D.radiusInner),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||
decoration: BoxDecoration(
|
||||
color: accent.withValues(alpha: 0.08),
|
||||
borderRadius: BorderRadius.circular(_D.radiusInner)),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(isOther ? Icons.person_rounded : Icons.group_rounded,
|
||||
color: accent, size: 17),
|
||||
const SizedBox(width: 14),
|
||||
Expanded(
|
||||
child: Text(
|
||||
isOther
|
||||
? 'Order for myself'.tr
|
||||
: 'Order for someone else'.tr,
|
||||
void select(bool other) {
|
||||
if (mapEngine.isAnotherOreder == other) return;
|
||||
mapEngine.changeisAnotherOreder(other);
|
||||
rideLifecycle.isAnotherOreder = other;
|
||||
}
|
||||
|
||||
Widget segment(
|
||||
{required bool selected,
|
||||
required IconData icon,
|
||||
required String label,
|
||||
required VoidCallback onTap}) {
|
||||
return Expanded(
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: BorderRadius.circular(_D.radiusInner - 2),
|
||||
child: AnimatedContainer(
|
||||
duration: _D.fast,
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: selected ? accent.shade500 : Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(_D.radiusInner - 2),
|
||||
boxShadow: selected
|
||||
? [
|
||||
BoxShadow(
|
||||
color: accent.withValues(alpha: 0.35),
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 3)),
|
||||
]
|
||||
: null,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(icon,
|
||||
color: selected ? Colors.white : Colors.grey.shade500,
|
||||
size: 16),
|
||||
const SizedBox(width: 8),
|
||||
Flexible(
|
||||
child: Text(
|
||||
label,
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: accent,
|
||||
fontSize: 13.5,
|
||||
fontWeight: FontWeight.w600))),
|
||||
],
|
||||
color: selected ? Colors.white : Colors.grey.shade600,
|
||||
fontSize: 13,
|
||||
fontWeight:
|
||||
selected ? FontWeight.w700 : FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(4),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade100,
|
||||
borderRadius: BorderRadius.circular(_D.radiusInner),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
segment(
|
||||
selected: !isOther,
|
||||
icon: Icons.person_rounded,
|
||||
label: 'Order for myself'.tr,
|
||||
onTap: () => select(false),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
segment(
|
||||
selected: isOther,
|
||||
icon: Icons.group_rounded,
|
||||
label: 'Order for someone else'.tr,
|
||||
onTap: () => select(true),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user