import 'dart:io'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../../../controller/auth/syria/registration_controller.dart'; class RegistrationView extends StatelessWidget { const RegistrationView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final RegistrationController controller = Get.put(RegistrationController()); return Scaffold( appBar: AppBar( title: Text('Driver Registration'.tr), centerTitle: true, ), body: Column( children: [ SizedBox( height: 90, child: Obx( () => Stepper( currentStep: controller.currentPage.value, type: StepperType.horizontal, controlsBuilder: (_, __) => const SizedBox.shrink(), steps: [ Step( title: Text('Driver'.tr), content: const SizedBox.shrink()), Step( title: Text('Vehicle'.tr), content: const SizedBox.shrink()), Step( title: Text('Docs'.tr), content: const SizedBox.shrink()), ], ), ), ), Expanded( child: PageView( controller: controller.pageController, physics: const NeverScrollableScrollPhysics(), onPageChanged: (i) => controller.currentPage.value = i, children: [ _buildDriverInfoStep(context, controller), _buildCarInfoStep(context, controller), _buildDocumentUploadStep(context, controller), ], ), ), ], ), bottomNavigationBar: _buildBottomNavBar(controller), ); } // STEP 1 Widget _buildDriverInfoStep(BuildContext ctx, RegistrationController c) { return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Form( key: c.driverInfoFormKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Driver's Personal Information".tr, style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold)), const SizedBox(height: 20), TextFormField( controller: c.firstNameController, decoration: InputDecoration( labelText: 'First Name'.tr, border: const OutlineInputBorder(), ), validator: (v) { if (v == null || v.isEmpty) { return 'Required field'.tr; } if (v.length < 2) { return 'Name must be at least 2 characters'.tr; } return null; }, ), const SizedBox(height: 16), TextFormField( controller: c.lastNameController, decoration: InputDecoration( labelText: 'Last Name'.tr, border: const OutlineInputBorder(), ), validator: (v) { if (v == null || v.isEmpty) { return 'Required field'.tr; } if (v.length < 2) { return 'Name must be at least 2 characters'.tr; } return null; }, ), const SizedBox(height: 16), TextFormField( controller: c.nationalIdController, decoration: InputDecoration( labelText: 'National ID Number'.tr, border: const OutlineInputBorder(), ), keyboardType: TextInputType.number, validator: (v) { if (v == null || v.isEmpty) { return 'Required field'.tr; } if (v.length != 11) { return 'National ID must be 11 digits'.tr; } return null; }, ), const SizedBox(height: 16), TextFormField( controller: c.driverLicenseExpiryController, decoration: InputDecoration( labelText: 'License Expiry Date'.tr, hintText: 'YYYY-MM-DD'.tr, border: const OutlineInputBorder()), readOnly: true, onTap: () async { DateTime? d = await showDatePicker( context: ctx, initialDate: DateTime.now(), firstDate: DateTime(2000), lastDate: DateTime(2101), ); if (d != null) { c.driverLicenseExpiryDate = d; c.driverLicenseExpiryController.text = d.toLocal().toString().split(' ')[0]; } }, validator: (v) => (v?.isEmpty ?? true) ? 'Please select a date'.tr : null, ), ], ), ), ); } // STEP 2 Widget _buildCarInfoStep(BuildContext ctx, RegistrationController c) { return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Form( key: c.carInfoFormKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Vehicle Information'.tr, style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold)), const SizedBox(height: 20), TextFormField( controller: c.carPlateController, decoration: InputDecoration( labelText: 'Car Plate Number'.tr, border: const OutlineInputBorder()), validator: (v) => (v?.isEmpty ?? true) ? 'Required field'.tr : null, ), const SizedBox(height: 16), TextFormField( controller: c.carMakeController, decoration: InputDecoration( labelText: 'Car Make (e.g., Toyota)'.tr, border: const OutlineInputBorder()), validator: (v) => (v?.isEmpty ?? true) ? 'Required field'.tr : null, ), const SizedBox(height: 16), TextFormField( controller: c.carModelController, decoration: InputDecoration( labelText: 'Car Model (e.g., Corolla)'.tr, border: const OutlineInputBorder()), validator: (v) => (v?.isEmpty ?? true) ? 'Required field'.tr : null, ), const SizedBox(height: 16), TextFormField( controller: c.carYearController, keyboardType: TextInputType.number, decoration: InputDecoration( labelText: 'Year of Manufacture'.tr, border: const OutlineInputBorder()), validator: (v) => (v?.isEmpty ?? true) ? 'Required field'.tr : null, ), const SizedBox(height: 16), // حقل اسم اللون (يبقى اختياري أو نملؤه تلقائيًا عند اختيار الهكس) // TextFormField( // controller: c.carColorController, // decoration: InputDecoration( // labelText: 'Car Color (Name)'.tr, // border: const OutlineInputBorder(), // ), // validator: (v) => // (v?.isEmpty ?? true) ? 'Required field'.tr : null, // ), // const SizedBox(height: 16), // الدروب داون للهكس + دائرة اللون GetBuilder( id: 'carColor', // اختياري لتحديث انتقائي builder: (c) { return DropdownButtonFormField( value: (c.colorHex != null && c.colorHex!.isNotEmpty) ? c.colorHex : null, isExpanded: true, decoration: InputDecoration( labelText: 'Car Color (Hex)'.tr, border: const OutlineInputBorder(), // prefixIcon: Padding( // padding: // const EdgeInsetsDirectional.only(start: 12, end: 8), // child: Container( // width: 18, // height: 18, // decoration: BoxDecoration( // color: (c.colorHex?.isNotEmpty ?? false) // ? c.hexToColor(c.colorHex!) // : Colors.transparent, // shape: BoxShape.circle, // border: Border.all(color: Colors.black26), // ), // ), // ), ), items: RegistrationController.kCarColorOptions.map((opt) { final hex = opt['hex']!; final key = opt['key']!; return DropdownMenuItem( value: hex, child: Row( children: [ Container( width: 18, height: 18, decoration: BoxDecoration( color: c.hexToColor(hex), shape: BoxShape.circle, border: Border.all(color: Colors.black12), ), ), const SizedBox(width: 8), Expanded(child: Text(key.tr)), ], ), ); }).toList(), onChanged: (hex) { c.colorHex = hex; // خزّن الهكس final key = RegistrationController.kCarColorOptions .firstWhere((o) => o['hex'] == hex)['key']!; c.carColorController.text = key.tr; c.update([ 'carColor' ]); // <-- مهم: يعيد بناء الودجت ويحدّث الدائرة }, validator: (v) => (v == null || v.isEmpty) ? 'Required field'.tr : null, ); }, ) ], ), ), ); } // STEP 3 Widget _buildDocumentUploadStep(BuildContext ctx, RegistrationController c) { final String linkUpload = 'https://syria.intaleq.xyz/intaleq/auth/syria/uploadImage.php'; return GetBuilder( builder: (ctrl) => SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Upload Documents'.tr, style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold)), const SizedBox(height: 20), _buildImagePickerBox( 'Driver License (Front)'.tr, ctrl.docUrls['driver_license_front'], // () => ctrl.pickImage(ImageType.driverLicenseFront), () async => await ctrl.choosImage(linkUpload, 'driver_license_front'), ), _buildImagePickerBox( 'Driver License (Back)'.tr, ctrl.docUrls['driver_license_back'], () async => await ctrl.choosImage(linkUpload, 'driver_license_back'), // () => ctrl.pickImage(ImageType.driverLicenseBack), ), _buildImagePickerBox( 'Car Registration (Front)'.tr, ctrl.docUrls['car_license_front'], () async => await ctrl.choosImage(linkUpload, 'car_license_front'), // () => ctrl.pickImage(ImageType.carLicenseFront), ), _buildImagePickerBox( 'Car Registration (Back)'.tr, ctrl.docUrls['car_license_back'], () async => await ctrl.choosImage(linkUpload, 'car_license_back'), // () => ctrl.pickImage(ImageType.carLicenseBack), ), ], ), ), ); } Widget signedImageWithAuth(String fileUrl, String bearerToken) { return Image.network( fileUrl, headers: {'Authorization': 'Bearer $bearerToken'}, fit: BoxFit.cover, errorBuilder: (_, __, ___) => const Text('Image expired or unauthorized'), ); } Widget _buildImagePickerBox(String title, String? img, VoidCallback onTap) { return Card( margin: const EdgeInsets.only(bottom: 16), child: InkWell( onTap: onTap, child: SizedBox( height: 150, width: double.infinity, child: (img != null && img.isNotEmpty) ? Image.network( img, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.broken_image, size: 40, color: Colors.red), const SizedBox(height: 8), Text('Image not available', style: TextStyle(color: Colors.red[700])), ], ), ); }, ) : Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.camera_alt_outlined, size: 40, color: Colors.grey[600]), const SizedBox(height: 8), Text(title, style: TextStyle(color: Colors.grey[700])), Text('Tap to upload'.tr, style: const TextStyle(color: Colors.grey, fontSize: 12)), ], ), ), ), ); } Widget _buildBottomNavBar(RegistrationController c) { return Obx(() => Padding( padding: const EdgeInsets.all(16), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ if (c.currentPage.value > 0) TextButton( onPressed: c.goToPreviousStep, child: Text('<< BACK'.tr), ), const Spacer(), ElevatedButton( style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 12), backgroundColor: c.currentPage.value == 2 ? Colors.green : Theme.of(Get.context!).primaryColor, ), onPressed: c.isLoading.value ? null : () { if (c.currentPage.value == 2) { c.submitRegistration(); } else { c.goToNextStep(); } }, child: c.isLoading.value ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator( color: Colors.white, strokeWidth: 2)) : Text( c.currentPage.value == 2 ? 'SUBMIT'.tr : 'NEXT >>'.tr, style: const TextStyle(fontSize: 16, color: Colors.white), ), ), ], ), )); } }