339 lines
12 KiB
Dart
339 lines
12 KiB
Dart
import 'dart:convert';
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:service/constant/box_name.dart';
|
|
import 'package:service/constant/links.dart';
|
|
import 'package:service/controller/functions/crud.dart';
|
|
import 'package:service/main.dart';
|
|
import 'package:service/print.dart';
|
|
import 'package:service/views/widgets/my_dialog.dart';
|
|
|
|
import 'pages/registration_captain_page.dart';
|
|
|
|
class RegisterCaptainController extends GetxController {
|
|
// --- UI State Management ---
|
|
var isLoading = true.obs;
|
|
late PageController pageController;
|
|
var currentPageIndex = 0.obs;
|
|
var driverId = ''.obs;
|
|
var phone = ''.obs;
|
|
var serverData = <String, dynamic>{}.obs;
|
|
// En tu archivo registration_captain_controller.dart
|
|
final phoneController = TextEditingController();
|
|
// --- Dynamic Document Image URLs ---
|
|
final Map<String, RxString> docUrls = {
|
|
'driver_license_front': ''.obs,
|
|
'driver_license_back': ''.obs,
|
|
'car_license_front': ''.obs,
|
|
'car_license_back': ''.obs,
|
|
};
|
|
|
|
// --- Text Field Controllers ---
|
|
late TextEditingController firstNameController;
|
|
late TextEditingController lastNameController;
|
|
late TextEditingController siteController;
|
|
late TextEditingController nationalNumberController;
|
|
late TextEditingController birthdateController;
|
|
late TextEditingController licenseCategoriesController;
|
|
late TextEditingController expiryDateController;
|
|
late TextEditingController ownerController;
|
|
late TextEditingController colorController;
|
|
late TextEditingController carPlateController;
|
|
late TextEditingController vinController;
|
|
late TextEditingController licenseIssueDateController;
|
|
late TextEditingController carLicenseExpiryDateController;
|
|
late TextEditingController makeController;
|
|
late TextEditingController modelController;
|
|
late TextEditingController yearController;
|
|
|
|
// --- Reactive State for Dropdowns ---
|
|
var selectedGender = ''.obs;
|
|
var colorHex = ''.obs;
|
|
var selectedFuel = ''.obs;
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
pageController = PageController();
|
|
|
|
final arguments = Get.arguments;
|
|
driverId.value = arguments?['driverId']; // Fallback for testing
|
|
phone.value = arguments?['phone']; // Fallback for testing
|
|
|
|
_initializeTextControllers();
|
|
_initializeDocUrls();
|
|
fetchDataFromServer();
|
|
}
|
|
|
|
void _initializeDocUrls() {
|
|
const baseUrl =
|
|
"https://syria.intaleq.xyz/intaleq/auth/syria/driversDocs/syria.intaleq.xyz-";
|
|
docUrls['driver_license_front']!.value =
|
|
"$baseUrl${driverId.value}-driver_license_front.jpg";
|
|
docUrls['driver_license_back']!.value =
|
|
"$baseUrl${driverId.value}-driver_license_back.jpg";
|
|
docUrls['car_license_front']!.value =
|
|
"$baseUrl${driverId.value}-car_license_front.jpg";
|
|
docUrls['car_license_back']!.value =
|
|
"$baseUrl${driverId.value}-car_license_back.jpg";
|
|
}
|
|
|
|
void _initializeTextControllers() {
|
|
firstNameController = TextEditingController();
|
|
lastNameController = TextEditingController();
|
|
siteController = TextEditingController();
|
|
nationalNumberController = TextEditingController();
|
|
birthdateController = TextEditingController();
|
|
licenseCategoriesController = TextEditingController();
|
|
expiryDateController = TextEditingController();
|
|
ownerController = TextEditingController();
|
|
colorController = TextEditingController();
|
|
carPlateController = TextEditingController();
|
|
vinController = TextEditingController();
|
|
licenseIssueDateController = TextEditingController();
|
|
carLicenseExpiryDateController = TextEditingController();
|
|
makeController = TextEditingController();
|
|
modelController = TextEditingController();
|
|
yearController = TextEditingController();
|
|
}
|
|
|
|
Future<void> fetchDataFromServer() async {
|
|
isLoading.value = true;
|
|
try {
|
|
var responseString = await CRUD().post(
|
|
link: AppLink.getDriverDetailsForActivate,
|
|
payload: {'driverId': driverId.value});
|
|
|
|
if (responseString != 'failure') {
|
|
var decodedResponse = jsonDecode(responseString);
|
|
if (decodedResponse['status'] == 'success' &&
|
|
(decodedResponse['message'] as List).isNotEmpty) {
|
|
var rawData = decodedResponse['message'][0] as Map<String, dynamic>;
|
|
// Sanitize data: ensure all values are strings to prevent type errors
|
|
serverData.value = rawData
|
|
.map((key, value) => MapEntry(key, value?.toString() ?? ''));
|
|
_populateControllersWithServerData();
|
|
}
|
|
}
|
|
} catch (e) {
|
|
Get.snackbar('Error', 'An unexpected error occurred: $e');
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
}
|
|
|
|
void _populateControllersWithServerData() {
|
|
firstNameController.text = serverData['first_name'] ?? '';
|
|
lastNameController.text = serverData['last_name'] ?? '';
|
|
siteController.text = serverData['site'] ?? '';
|
|
nationalNumberController.text = serverData['national_number'] ?? '';
|
|
birthdateController.text = serverData['birthdate'] ?? '';
|
|
selectedGender.value = serverData['gender'] ?? '';
|
|
licenseCategoriesController.text = serverData['license_categories'] ?? '';
|
|
expiryDateController.text = serverData['expiry_date'] ?? '';
|
|
ownerController.text = serverData['owner'] ?? '';
|
|
|
|
final serverColorName = serverData['color'] ?? '';
|
|
final colorOption = kCarColorOptions.firstWhere(
|
|
(opt) => opt['key'] == serverColorName,
|
|
orElse: () => {'key': serverColorName, 'hex': '#000000'}); // Fallback
|
|
colorController.text = colorOption['key']!;
|
|
colorHex.value = colorOption['hex']!;
|
|
|
|
carPlateController.text = serverData['car_plate'] ?? '';
|
|
vinController.text = serverData['vin'] ?? '';
|
|
licenseIssueDateController.text = serverData['issue_date'] ?? '';
|
|
carLicenseExpiryDateController.text = serverData['expiration_date'] ?? '';
|
|
makeController.text = serverData['make'] ?? '';
|
|
modelController.text = serverData['model'] ?? '';
|
|
selectedFuel.value = serverData['fuel'] ?? '';
|
|
yearController.text = serverData['year'] ?? '';
|
|
}
|
|
|
|
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 (e) {/* Use default if parsing fails */}
|
|
|
|
DateTime? pickedDate = initialDate;
|
|
await showCupertinoModalPopup<void>(
|
|
context: context,
|
|
builder: (BuildContext 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();
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
void nextPage() {
|
|
if (currentPageIndex.value < 3)
|
|
pageController.nextPage(
|
|
duration: const Duration(milliseconds: 400), curve: Curves.easeInOut);
|
|
}
|
|
|
|
void previousPage() {
|
|
if (currentPageIndex.value > 0)
|
|
pageController.previousPage(
|
|
duration: const Duration(milliseconds: 400), curve: Curves.easeInOut);
|
|
}
|
|
|
|
void updateAndActivateSyrianDriver() {
|
|
isLoading.value = true;
|
|
|
|
Map<String, dynamic> dataToSend = {
|
|
// Driver fields from all pages
|
|
'driverId': driverId.value,
|
|
'phone': phone.value,
|
|
'first_name': firstNameController.text,
|
|
'last_name': lastNameController.text,
|
|
'site': siteController.text,
|
|
'national_number': nationalNumberController.text,
|
|
'gender': selectedGender.value,
|
|
'birthdate': '2000-01-01', //birthdateController.text,
|
|
'license_categories': licenseCategoriesController.text,
|
|
'expiry_date': expiryDateController.text,
|
|
'license_issue_date': licenseIssueDateController.text,
|
|
|
|
// Car fields from all pages
|
|
'owner': ownerController.text,
|
|
'color': colorController.text,
|
|
'color_hex': colorHex.value,
|
|
'car_plate': carPlateController.text,
|
|
'maritalStatus': box.read(BoxName.employeename) ?? 'unknown',
|
|
// 'vin': vinController.text,
|
|
'expiration_date': carLicenseExpiryDateController.text,
|
|
'make': makeController.text,
|
|
'model': modelController.text,
|
|
'fuel': selectedFuel.value,
|
|
'year': yearController.text,
|
|
};
|
|
|
|
print("--- Submitting Data to Server ---");
|
|
print(dataToSend);
|
|
|
|
CRUD()
|
|
.post(link: AppLink.updateDriverToActive, payload: dataToSend)
|
|
.then((response) {
|
|
isLoading.value = false;
|
|
var decodedResponse = (response);
|
|
Log.print('decodedResponse: ${decodedResponse}');
|
|
if (decodedResponse != 'failure') {
|
|
MyDialog().getDialog('Success'.tr, '',
|
|
Text('Driver has been activated successfully!'.tr), () {
|
|
Get.back();
|
|
Get.back();
|
|
// fetchDataFromServer();
|
|
Get.back();
|
|
// Get.off(() => RegisterCaptain());
|
|
});
|
|
} else {
|
|
Get.snackbar(
|
|
'Error'.tr,
|
|
'Failed to update driver: ${decodedResponse['message']}'.tr,
|
|
backgroundColor: Colors.red,
|
|
colorText: Colors.white,
|
|
);
|
|
}
|
|
}).catchError((error) {
|
|
isLoading.value = false;
|
|
Get.snackbar(
|
|
'Error'.tr,
|
|
'An error occurred: $error'.tr,
|
|
backgroundColor: Colors.red,
|
|
colorText: Colors.white,
|
|
);
|
|
});
|
|
}
|
|
|
|
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;
|
|
colorController.text =
|
|
kCarColorOptions.firstWhere((o) => o['hex'] == hex)['key']!;
|
|
}
|
|
|
|
@override
|
|
void onClose() {
|
|
pageController.dispose();
|
|
firstNameController.dispose();
|
|
lastNameController.dispose();
|
|
siteController.dispose();
|
|
nationalNumberController.dispose();
|
|
birthdateController.dispose();
|
|
licenseCategoriesController.dispose();
|
|
expiryDateController.dispose();
|
|
ownerController.dispose();
|
|
colorController.dispose();
|
|
carPlateController.dispose();
|
|
vinController.dispose();
|
|
licenseIssueDateController.dispose();
|
|
carLicenseExpiryDateController.dispose();
|
|
makeController.dispose();
|
|
modelController.dispose();
|
|
yearController.dispose();
|
|
super.onClose();
|
|
}
|
|
}
|