feat: استيراد كود سيرو إلى تريبز (سيرو @ecfe7568) — بلا تعديل
قرار المالك 2026-07-27: باك إند سيرو PHP هو المعتمد، وتطبيقاته المجرّبة ميدانياً تحل محل إعادة البناء المؤرشفة. سيرو نفسه لم يُمسّ. الخريطة: backend · payment_server · loction_server · ride_server · passenger_server · docker · dashboard · stress_test → الجذر siro_rider → apps/rider siro_driver → apps/driver siro_admin → dashboards/admin siro_service → dashboards/service android_bot → apps/android_bot socialBot → apps/socialBot نُسخ المتعقَّب في git سيرو فقط عبر `git archive` (3,198 ملفاً / ~169 م.ب) لا `cp -r` — فاستُثنيت مخلفات البناء تلقائياً. بلا أي تعديل محتوى عمداً: كل ما يلي يصير فرقاً مقروءاً مقابل المصدر. لم يُستورد وسببه: siromove.com (الموقع التسويقي يبقى marketing/ في تريبز، سيرو فيه 8 ملفات) · docs و planning (تريبز له docs/ الخاص) · deploy.sh (ليس نشراً على سيرفر بل `git add . && git push origin --all` — فخّ في مستودع آخر) · transit_dashboard (بانتظار قرار مصير backend-transit و dashboards/transit-web). ⚠️ لا يبني بعد — ثلاثة نواقص متوقعة ومقصودة: 1. `.env` و `lib/env/env.g.dart` غير متعقَّبين في سيرو (أسرار لكل مستأجر): كل تطبيق فلاتر يحتاج .env خاصاً ثم توليد env.g.dart بـ build_runner. 2. إعدادات Firebase (9 ملفات google-services.json و GoogleService-Info.plist) يستبعدها .gitignore تريبز — ولكل مستأجر مشروع Firebase خاص أصلاً. 3. apps/driver في سيرو يشير إلى `../../Intaleq/packages/get` خارج المستودع → يجب ضمّ الحزم داخله أسوة بـ apps/rider. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9909d9b4c1
commit
4d8414c96b
@@ -0,0 +1,600 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:siro_service/constant/links.dart';
|
||||
import 'package:siro_service/controller/functions/crud.dart';
|
||||
import 'package:siro_service/main.dart';
|
||||
import 'package:siro_service/views/widgets/mycircular.dart';
|
||||
|
||||
class ReviewDriverController extends GetxController {
|
||||
var isLoading = true.obs;
|
||||
var isSaving = false.obs;
|
||||
var driverId = ''.obs;
|
||||
var phone = ''.obs;
|
||||
var serverData = <String, dynamic>{}.obs;
|
||||
var currentTabIndex = 0.obs;
|
||||
|
||||
final Map<String, RxString> docUrls = {
|
||||
'id_front': ''.obs,
|
||||
'id_back': ''.obs,
|
||||
'driver_license_front': ''.obs,
|
||||
'driver_license_back': ''.obs,
|
||||
'car_license_front': ''.obs,
|
||||
'car_license_back': ''.obs,
|
||||
'criminal_record': ''.obs,
|
||||
'profile_picture': ''.obs,
|
||||
};
|
||||
|
||||
final Map<String, String> tabLabels = {
|
||||
'id_front': 'ID Front',
|
||||
'id_back': 'ID Back',
|
||||
'driver_license_front': 'Driver License',
|
||||
'driver_license_back': 'License Back',
|
||||
'car_license_front': 'Car Reg Front',
|
||||
'car_license_back': 'Car Reg Back',
|
||||
'criminal_record': 'Criminal Record',
|
||||
'profile_picture': 'Profile Photo',
|
||||
};
|
||||
|
||||
final Map<String, IconData> tabIcons = {
|
||||
'id_front': Icons.badge,
|
||||
'id_back': Icons.badge_outlined,
|
||||
'driver_license_front': Icons.drive_eta,
|
||||
'driver_license_back': Icons.drive_eta_outlined,
|
||||
'car_license_front': Icons.description,
|
||||
'car_license_back': Icons.description_outlined,
|
||||
'criminal_record': Icons.gavel,
|
||||
'profile_picture': Icons.person,
|
||||
};
|
||||
|
||||
String get country => box.read('countryCode')?.toString() ?? 'Jordan';
|
||||
|
||||
static const Map<String, List<List<dynamic>>> fieldConfig = {
|
||||
'id_front': [
|
||||
['firstNameController', 'First Name', false, false, false, false],
|
||||
['lastNameController', 'Last Name', false, false, false, false],
|
||||
[
|
||||
'nationalNumberController',
|
||||
'National Number',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
['gender', 'Gender', false, true, false, false],
|
||||
['birthdateController', 'Birthdate', true, false, false, false],
|
||||
['siteController', 'Place of Registration', false, false, false, false],
|
||||
],
|
||||
'id_back': [
|
||||
['addressController', 'Address', false, false, false, false],
|
||||
['maritalStatusController', 'Marital Status', false, false, false, false],
|
||||
],
|
||||
'driver_license_front': [
|
||||
['licenseTypeController', 'License Type', false, false, false, false],
|
||||
[
|
||||
'licenseCategoriesController',
|
||||
'License Categories',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
[
|
||||
'licenseIssueDateController',
|
||||
'License Issue Date',
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
[
|
||||
'expiryDateController',
|
||||
'License Expiry Date',
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
],
|
||||
'driver_license_back': [],
|
||||
'car_license_front': [
|
||||
['makeController', 'Make', false, false, false, false],
|
||||
['modelController', 'Model', false, false, false, false],
|
||||
['yearController', 'Year', false, false, false, false],
|
||||
['ownerController', 'Owner Name', false, false, false, false],
|
||||
['carPlateController', 'Car Plate', false, false, false, false],
|
||||
['color', 'Car Color', false, false, true, false],
|
||||
],
|
||||
'car_license_back': [
|
||||
['fuel', 'Fuel Type', false, false, false, true],
|
||||
['vinController', 'VIN / Chassis', false, false, false, false],
|
||||
[
|
||||
'carLicenseExpiryDateController',
|
||||
'License Expiry',
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
],
|
||||
'criminal_record': [],
|
||||
'profile_picture': [],
|
||||
};
|
||||
|
||||
List<List<dynamic>> getFieldsForTab(String tabKey) {
|
||||
final countryCode = country;
|
||||
if (countryCode == 'Syria') {
|
||||
if (tabKey == 'driver_license_front') {
|
||||
return [
|
||||
['licenseTypeController', 'License Type', false, false, false, false],
|
||||
[
|
||||
'licenseIssueDateController',
|
||||
'License Issue Date',
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
[
|
||||
'expiryDateController',
|
||||
'License Expiry Date',
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
];
|
||||
}
|
||||
if (tabKey == 'driver_license_back') {
|
||||
return [
|
||||
[
|
||||
'licenseCategoriesController',
|
||||
'License Categories',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
return fieldConfig[tabKey] ?? [];
|
||||
}
|
||||
|
||||
late TextEditingController firstNameController;
|
||||
late TextEditingController lastNameController;
|
||||
late TextEditingController phoneController;
|
||||
late TextEditingController emailController;
|
||||
late TextEditingController siteController;
|
||||
late TextEditingController nationalNumberController;
|
||||
late TextEditingController birthdateController;
|
||||
late TextEditingController addressController;
|
||||
late TextEditingController licenseCategoriesController;
|
||||
late TextEditingController licenseTypeController;
|
||||
late TextEditingController expiryDateController;
|
||||
late TextEditingController licenseIssueDateController;
|
||||
late TextEditingController maritalStatusController;
|
||||
late TextEditingController ownerController;
|
||||
late TextEditingController carPlateController;
|
||||
late TextEditingController vinController;
|
||||
late TextEditingController carLicenseExpiryDateController;
|
||||
late TextEditingController makeController;
|
||||
late TextEditingController modelController;
|
||||
late TextEditingController yearController;
|
||||
|
||||
var selectedGender = ''.obs;
|
||||
var colorHex = ''.obs;
|
||||
var colorName = ''.obs;
|
||||
var selectedFuel = ''.obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
_initializeTextControllers();
|
||||
final args = Get.arguments;
|
||||
if (args != null) {
|
||||
driverId.value = args['driverId'] ?? '';
|
||||
phone.value = args['phone'] ?? '';
|
||||
}
|
||||
if (country == 'Jordan' || country == 'Egypt') {
|
||||
docUrls.remove('driver_license_back');
|
||||
}
|
||||
_initializeDocUrls();
|
||||
fetchData();
|
||||
}
|
||||
|
||||
void _initializeTextControllers() {
|
||||
firstNameController = TextEditingController();
|
||||
lastNameController = TextEditingController();
|
||||
phoneController = TextEditingController();
|
||||
emailController = TextEditingController();
|
||||
siteController = TextEditingController();
|
||||
nationalNumberController = TextEditingController();
|
||||
birthdateController = TextEditingController();
|
||||
addressController = TextEditingController();
|
||||
licenseCategoriesController = TextEditingController();
|
||||
licenseTypeController = TextEditingController();
|
||||
expiryDateController = TextEditingController();
|
||||
licenseIssueDateController = TextEditingController();
|
||||
maritalStatusController = TextEditingController();
|
||||
ownerController = TextEditingController();
|
||||
carPlateController = TextEditingController();
|
||||
vinController = TextEditingController();
|
||||
carLicenseExpiryDateController = TextEditingController();
|
||||
makeController = TextEditingController();
|
||||
modelController = TextEditingController();
|
||||
yearController = TextEditingController();
|
||||
}
|
||||
|
||||
Future<void> fetchData() async {
|
||||
isLoading.value = true;
|
||||
try {
|
||||
var response = await CRUD().post(
|
||||
link: AppLink.getDriverDetailsForActivate,
|
||||
payload: {'driverId': driverId.value},
|
||||
);
|
||||
if (response != 'failure' &&
|
||||
response['status'] == 'success' &&
|
||||
(response['message'] as List).isNotEmpty) {
|
||||
var raw = response['message'][0] as Map<String, dynamic>;
|
||||
serverData.value =
|
||||
raw.map((key, value) => MapEntry(key, value?.toString() ?? ''));
|
||||
_populateControllers();
|
||||
_populateDocUrls(raw['documents']);
|
||||
}
|
||||
} catch (e) {
|
||||
mySnackbarError('${'Failed to load data'.tr}: $e');
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
String reconstructDocumentUrl(String originalLink, String docType) {
|
||||
if (originalLink.isEmpty) {
|
||||
return "${AppLink.server}/auth/syria/driversDocs/syria.intaleq.xyz-${driverId.value}-$docType.jpg";
|
||||
}
|
||||
|
||||
try {
|
||||
final origUri = Uri.parse(originalLink);
|
||||
final query = origUri.query;
|
||||
final path = origUri.path;
|
||||
|
||||
if (path.contains('secure_image.php')) {
|
||||
return "${AppLink.server}/secure_image.php?$query";
|
||||
}
|
||||
|
||||
if (path.contains('auth/syria/driversDocs/')) {
|
||||
final parts = path.split('auth/syria/driversDocs/');
|
||||
final filename = parts.last;
|
||||
return "${AppLink.server}/auth/syria/driversDocs/$filename";
|
||||
}
|
||||
|
||||
if (originalLink.startsWith('http://') ||
|
||||
originalLink.startsWith('https://')) {
|
||||
final serverUri = Uri.parse(AppLink.server);
|
||||
final host = serverUri.host;
|
||||
|
||||
final newUri = Uri(
|
||||
scheme: 'https',
|
||||
host: host,
|
||||
path: path,
|
||||
query: query.isNotEmpty ? query : null,
|
||||
);
|
||||
return newUri.toString();
|
||||
}
|
||||
|
||||
final cleanPath = path.startsWith('/') ? path : '/$path';
|
||||
return "${AppLink.server}$cleanPath${query.isNotEmpty ? '?$query' : ''}";
|
||||
} catch (e) {
|
||||
if (originalLink.startsWith('http://')) {
|
||||
return originalLink.replaceFirst('http://', 'https://');
|
||||
}
|
||||
return originalLink;
|
||||
}
|
||||
}
|
||||
|
||||
void _initializeDocUrls() {
|
||||
for (var key in docUrls.keys) {
|
||||
docUrls[key]!.value = reconstructDocumentUrl('', key);
|
||||
}
|
||||
}
|
||||
|
||||
void _populateDocUrls(dynamic docs) {
|
||||
if (docs is List) {
|
||||
for (var doc in docs) {
|
||||
if (doc is Map && doc['doc_type'] != null && doc['link'] != null) {
|
||||
String type = doc['doc_type'].toString();
|
||||
if (docUrls.containsKey(type)) {
|
||||
docUrls[type]!.value =
|
||||
reconstructDocumentUrl(doc['link'].toString(), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _populateControllers() {
|
||||
firstNameController.text = serverData['first_name'] ?? '';
|
||||
lastNameController.text = serverData['last_name'] ?? '';
|
||||
phoneController.text = serverData['phone'] ?? '';
|
||||
emailController.text = serverData['email'] ?? '';
|
||||
siteController.text = serverData['site'] ?? '';
|
||||
nationalNumberController.text = serverData['national_number'] ?? '';
|
||||
birthdateController.text = serverData['birthdate'] ?? '';
|
||||
addressController.text = serverData['address'] ?? '';
|
||||
licenseCategoriesController.text = serverData['license_categories'] ?? '';
|
||||
licenseTypeController.text = serverData['license_type'] ?? '';
|
||||
expiryDateController.text = serverData['expiry_date'] ?? '';
|
||||
licenseIssueDateController.text =
|
||||
serverData['licenseIssueDate'] ?? serverData['issue_date'] ?? '';
|
||||
maritalStatusController.text = serverData['maritalStatus'] ?? '';
|
||||
selectedGender.value = serverData['gender'] ?? '';
|
||||
|
||||
ownerController.text = serverData['owner'] ?? '';
|
||||
carPlateController.text = serverData['car_plate'] ?? '';
|
||||
vinController.text = serverData['vin'] ?? '';
|
||||
carLicenseExpiryDateController.text = serverData['expiration_date'] ?? '';
|
||||
makeController.text = serverData['make'] ?? '';
|
||||
modelController.text = serverData['model'] ?? '';
|
||||
yearController.text = serverData['year'] ?? '';
|
||||
selectedFuel.value = serverData['fuel'] ?? '';
|
||||
|
||||
final serverColorName = serverData['color'] ?? '';
|
||||
final colorOption = kCarColorOptions.firstWhere(
|
||||
(opt) => opt['key'] == serverColorName,
|
||||
orElse: () => {'key': serverColorName, 'hex': '#000000'},
|
||||
);
|
||||
colorName.value = colorOption['key']!;
|
||||
colorHex.value = colorOption['hex']!;
|
||||
|
||||
phone.value = serverData['phone'] ?? '';
|
||||
}
|
||||
|
||||
Future<void> selectDate(
|
||||
BuildContext context, TextEditingController controller) async {
|
||||
DateTime initialDate = DateTime.now();
|
||||
try {
|
||||
if (controller.text.isNotEmpty) {
|
||||
initialDate = DateFormat('yyyy-MM-dd').parse(controller.text);
|
||||
}
|
||||
} catch (_) {}
|
||||
DateTime? pickedDate = initialDate;
|
||||
await showCupertinoModalPopup<void>(
|
||||
context: context,
|
||||
builder: (context) => Container(
|
||||
height: 280,
|
||||
color: CupertinoColors.systemBackground.resolveFrom(context),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 200,
|
||||
child: CupertinoDatePicker(
|
||||
initialDateTime: initialDate,
|
||||
minimumDate: DateTime(1950),
|
||||
maximumDate: DateTime(2050),
|
||||
mode: CupertinoDatePickerMode.date,
|
||||
onDateTimeChanged: (DateTime newDate) {
|
||||
pickedDate = newDate;
|
||||
},
|
||||
),
|
||||
),
|
||||
CupertinoButton(
|
||||
child: Text('Done'.tr),
|
||||
onPressed: () {
|
||||
if (pickedDate != null) {
|
||||
controller.text =
|
||||
DateFormat('yyyy-MM-dd').format(pickedDate!);
|
||||
}
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _buildPayload() {
|
||||
return {
|
||||
'driverId': driverId.value,
|
||||
'phone': phoneController.text,
|
||||
'first_name': firstNameController.text,
|
||||
'last_name': lastNameController.text,
|
||||
'site': siteController.text,
|
||||
'national_number': nationalNumberController.text,
|
||||
'gender': selectedGender.value,
|
||||
'birthdate': birthdateController.text,
|
||||
'address': addressController.text,
|
||||
'email': emailController.text,
|
||||
'license_type': licenseTypeController.text,
|
||||
'license_categories': licenseCategoriesController.text,
|
||||
'expiry_date': expiryDateController.text,
|
||||
'license_issue_date': licenseIssueDateController.text,
|
||||
'maritalStatus': maritalStatusController.text,
|
||||
'owner': ownerController.text,
|
||||
'color': colorName.value,
|
||||
'color_hex': colorHex.value,
|
||||
'car_plate': carPlateController.text,
|
||||
'expiration_date': carLicenseExpiryDateController.text,
|
||||
'make': makeController.text,
|
||||
'model': modelController.text,
|
||||
'fuel': selectedFuel.value,
|
||||
'year': yearController.text,
|
||||
'vin': vinController.text,
|
||||
};
|
||||
}
|
||||
|
||||
Future<void> saveChanges() async {
|
||||
isSaving.value = true;
|
||||
try {
|
||||
var payload = _buildPayload();
|
||||
payload['status'] = 'pending_review';
|
||||
var response = await CRUD().post(
|
||||
link: AppLink.updateDriverToActive,
|
||||
payload: payload,
|
||||
);
|
||||
if (response != 'failure' && response['status'] == 'success') {
|
||||
mySnackbarSuccess('Data saved successfully'.tr);
|
||||
} else {
|
||||
mySnackbarError('Failed to save changes'.tr);
|
||||
}
|
||||
} catch (e) {
|
||||
mySnackbarError('${'Error'.tr}: $e');
|
||||
} finally {
|
||||
isSaving.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> activateDriver() async {
|
||||
isSaving.value = true;
|
||||
try {
|
||||
var payload = _buildPayload();
|
||||
var response = await CRUD().post(
|
||||
link: AppLink.updateDriverToActive,
|
||||
payload: payload,
|
||||
);
|
||||
if (response != 'failure' && response['status'] == 'success') {
|
||||
mySnackbarSuccess('Driver activated successfully!'.tr);
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
Get.back();
|
||||
} else {
|
||||
mySnackbarError('Failed to activate driver'.tr);
|
||||
}
|
||||
} catch (e) {
|
||||
mySnackbarError('${'Error'.tr}: $e');
|
||||
} finally {
|
||||
isSaving.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> rejectDriver(String reason) async {
|
||||
if (reason.trim().isEmpty) {
|
||||
mySnackbarError('Please enter a rejection reason'.tr);
|
||||
return;
|
||||
}
|
||||
isSaving.value = true;
|
||||
try {
|
||||
var response = await CRUD().post(
|
||||
link: AppLink.rejectDriver,
|
||||
payload: {
|
||||
'driverId': driverId.value,
|
||||
'reason': reason.trim(),
|
||||
},
|
||||
);
|
||||
if (response != 'failure' && response['status'] == 'success') {
|
||||
mySnackbarSuccess('Driver rejected'.tr);
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
Get.back();
|
||||
} else {
|
||||
mySnackbarError('Failed to reject driver'.tr);
|
||||
}
|
||||
} catch (e) {
|
||||
mySnackbarError('${'Error'.tr}: $e');
|
||||
} finally {
|
||||
isSaving.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
void showRejectDialog() {
|
||||
final reasonController = TextEditingController();
|
||||
Get.defaultDialog(
|
||||
title: 'Reject Driver'.tr,
|
||||
content: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: TextField(
|
||||
controller: reasonController,
|
||||
maxLines: 3,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Enter rejection reason...'.tr,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
confirm: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
|
||||
onPressed: () => rejectDriver(reasonController.text),
|
||||
child: Text('Reject'.tr, style: const TextStyle(color: Colors.white)),
|
||||
),
|
||||
cancel: ElevatedButton(
|
||||
onPressed: () => Get.back(),
|
||||
child: Text('Cancel'.tr),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static const List<Map<String, String>> kCarColorOptions = [
|
||||
{'key': 'white', 'hex': '#FFFFFF'},
|
||||
{'key': 'black', 'hex': '#000000'},
|
||||
{'key': 'silver', 'hex': '#C0C0C0'},
|
||||
{'key': 'gray', 'hex': '#808080'},
|
||||
{'key': 'gunmetal', 'hex': '#2A3439'},
|
||||
{'key': 'red', 'hex': '#C62828'},
|
||||
{'key': 'blue', 'hex': '#1565C0'},
|
||||
{'key': 'navy', 'hex': '#0D47A1'},
|
||||
{'key': 'green', 'hex': '#2E7D32'},
|
||||
{'key': 'darkGreen', 'hex': '#1B5E20'},
|
||||
{'key': 'beige', 'hex': '#D7CCC8'},
|
||||
{'key': 'brown', 'hex': '#5D4037'},
|
||||
{'key': 'maroon', 'hex': '#800000'},
|
||||
{'key': 'burgundy', 'hex': '#800020'},
|
||||
{'key': 'yellow', 'hex': '#F9A825'},
|
||||
{'key': 'orange', 'hex': '#EF6C00'},
|
||||
{'key': 'gold', 'hex': '#D4AF37'},
|
||||
{'key': 'bronze', 'hex': '#CD7F32'},
|
||||
{'key': 'champagne', 'hex': '#EFE1C6'},
|
||||
{'key': 'purple', 'hex': '#6A1B9A'},
|
||||
];
|
||||
|
||||
static const List<String> kFuelOptions = [
|
||||
'بنزين',
|
||||
'ديزل',
|
||||
'هايبرد',
|
||||
'كهربائي',
|
||||
];
|
||||
|
||||
Color hexToColor(String code) =>
|
||||
Color(int.parse(code.substring(1, 7), radix: 16) + 0xFF000000);
|
||||
|
||||
void updateColorSelection(String hex) {
|
||||
colorHex.value = hex;
|
||||
colorName.value =
|
||||
kCarColorOptions.firstWhere((o) => o['hex'] == hex)['key']!;
|
||||
}
|
||||
|
||||
void updateColorSelectionByName(String name) {
|
||||
final opt = kCarColorOptions.firstWhere(
|
||||
(o) => o['key'] == name,
|
||||
orElse: () => {'key': name, 'hex': '#000000'},
|
||||
);
|
||||
colorName.value = opt['key']!;
|
||||
colorHex.value = opt['hex']!;
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
firstNameController.dispose();
|
||||
lastNameController.dispose();
|
||||
phoneController.dispose();
|
||||
emailController.dispose();
|
||||
siteController.dispose();
|
||||
nationalNumberController.dispose();
|
||||
birthdateController.dispose();
|
||||
addressController.dispose();
|
||||
licenseCategoriesController.dispose();
|
||||
licenseTypeController.dispose();
|
||||
expiryDateController.dispose();
|
||||
licenseIssueDateController.dispose();
|
||||
maritalStatusController.dispose();
|
||||
ownerController.dispose();
|
||||
carPlateController.dispose();
|
||||
vinController.dispose();
|
||||
carLicenseExpiryDateController.dispose();
|
||||
makeController.dispose();
|
||||
modelController.dispose();
|
||||
yearController.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user