import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:siro_service/constant/colors.dart'; import 'package:siro_service/controller/mainController/review_driver_controller.dart'; import 'package:siro_service/views/widgets/elevated_btn.dart'; import 'package:siro_service/views/widgets/my_scafold.dart'; class ReviewDriverPage extends StatelessWidget { const ReviewDriverPage({super.key}); @override Widget build(BuildContext context) { final controller = Get.put(ReviewDriverController()); return MyScaffold( title: 'Review Driver'.tr, isleading: true, body: [ Obx(() { if (controller.isLoading.value) { return const Center(child: CircularProgressIndicator()); } return Column( children: [ _buildTabBar(controller), Expanded(child: _buildTabBarView(controller)), _buildBottomActions(controller, context), ], ); }), ], ); } Widget _buildTabBar(ReviewDriverController c) { final keys = c.docUrls.keys.toList(); return SizedBox( height: 64, child: ListView.builder( scrollDirection: Axis.horizontal, padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6), itemCount: keys.length, itemBuilder: (context, index) { final key = keys[index]; final isSelected = c.currentTabIndex.value == index; return GestureDetector( onTap: () => c.currentTabIndex.value = index, child: Container( margin: const EdgeInsets.symmetric(horizontal: 3), padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), decoration: BoxDecoration( color: isSelected ? AppColor.primaryColor : AppColor.primaryLight, borderRadius: BorderRadius.circular(20), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( c.tabIcons[key] ?? Icons.image, size: 16, color: isSelected ? Colors.white : AppColor.primaryColor, ), const SizedBox(width: 4), Text( c.tabLabels[key] ?? key, style: TextStyle( fontSize: 11, fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, color: isSelected ? Colors.white : AppColor.primaryColor, ), ), ], ), ), ); }, ), ); } Widget _buildTabBarView(ReviewDriverController c) { return Obx(() { final index = c.currentTabIndex.value; final keys = c.docUrls.keys.toList(); final key = keys[index]; return SingleChildScrollView( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _buildDocumentImage(c.docUrls[key]!.value), const SizedBox(height: 16), _buildFormFieldsForTab(c, key), ], ), ); }); } Widget _buildDocumentImage(String url) { if (url.isEmpty) { return Container( height: 180, decoration: BoxDecoration( color: Colors.grey[100], borderRadius: BorderRadius.circular(12), ), child: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.image_not_supported, size: 48, color: Colors.grey[400]), const SizedBox(height: 8), Text('No image available', style: TextStyle(color: Colors.grey[500])), ], ), ), ); } return GestureDetector( onTap: () => _showImageFullscreen(url), child: ClipRRect( borderRadius: BorderRadius.circular(12), child: Image.network( url, height: 200, fit: BoxFit.contain, width: double.infinity, errorBuilder: (_, __, ___) => Container( height: 180, color: Colors.grey[200], child: Center( child: Text('Failed to load image', style: TextStyle(color: Colors.grey[500])), ), ), ), ), ); } void _showImageFullscreen(String url) { Get.dialog( Scaffold( backgroundColor: Colors.black, appBar: AppBar( backgroundColor: Colors.black, iconTheme: const IconThemeData(color: Colors.white), ), body: Center( child: InteractiveViewer( child: Image.network(url, fit: BoxFit.contain), ), ), ), ); } Widget _buildFormFieldsForTab(ReviewDriverController c, String tabKey) { switch (tabKey) { case 'id_front': return _buildIdFrontFields(c); case 'id_back': return _buildIdBackFields(c); case 'driver_license': return _buildDriverLicenseFields(c); case 'driver_license_back': return _buildLicenseBackFields(c); case 'car_license_front': return _buildCarFrontFields(c); case 'car_license_back': return _buildCarBackFields(c); case 'criminal_record': return _buildCriminalRecordFields(); case 'profile_picture': return _buildProfilePhotoFields(c); default: return const SizedBox(); } } Widget _buildTextField({ required String label, required TextEditingController controller, IconData? icon, TextInputType keyboardType = TextInputType.text, VoidCallback? onTap, String? hint, int maxLines = 1, }) { return Padding( padding: const EdgeInsets.symmetric(vertical: 6), child: TextFormField( controller: controller, keyboardType: keyboardType, maxLines: maxLines, readOnly: onTap != null, onTap: onTap, decoration: InputDecoration( labelText: label.tr, hintText: hint, prefixIcon: icon != null ? Icon(icon, color: AppColor.secondaryColor) : null, border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14), ), ), ); } Widget _buildGenderDropdown(ReviewDriverController c) { return Padding( padding: const EdgeInsets.symmetric(vertical: 6), child: Obx( () => DropdownButtonFormField( value: c.selectedGender.value.isEmpty ? null : c.selectedGender.value, isExpanded: true, decoration: InputDecoration( labelText: 'Gender'.tr, border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14), ), items: ['Male', 'Female'].map((v) { return DropdownMenuItem(value: v, child: Text(v.tr)); }).toList(), onChanged: (v) { if (v != null) c.selectedGender.value = v; }, ), ), ); } Widget _buildColorDropdown(ReviewDriverController c) { return Padding( padding: const EdgeInsets.symmetric(vertical: 6), child: Obx( () => DropdownButtonFormField( value: c.colorHex.value.isEmpty ? null : c.colorHex.value, isExpanded: true, decoration: InputDecoration( labelText: 'Car Color'.tr, border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14), ), items: ReviewDriverController.kCarColorOptions.map((opt) { return DropdownMenuItem( value: opt['hex'], child: Row( children: [ Container( width: 20, height: 20, decoration: BoxDecoration( color: c.hexToColor(opt['hex']!), shape: BoxShape.circle, border: Border.all(color: Colors.black12), ), ), const SizedBox(width: 10), Text(opt['key']!.tr), ], ), ); }).toList(), onChanged: (hex) { if (hex != null) c.updateColorSelection(hex); }, ), ), ); } Widget _buildFuelDropdown(ReviewDriverController c) { return Padding( padding: const EdgeInsets.symmetric(vertical: 6), child: Obx( () => DropdownButtonFormField( value: ReviewDriverController.kFuelOptions .contains(c.selectedFuel.value) ? c.selectedFuel.value : null, isExpanded: true, decoration: InputDecoration( labelText: 'Fuel Type'.tr, border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14), ), items: ReviewDriverController.kFuelOptions.map((v) { return DropdownMenuItem(value: v, child: Text(v)); }).toList(), onChanged: (v) { if (v != null) c.selectedFuel.value = v; }, ), ), ); } Widget _buildIdFrontFields(ReviewDriverController c) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('ID Card Information (Front)', style: Get.textTheme.titleMedium), const Divider(), Row( children: [ Expanded( child: _buildTextField( label: 'First Name', controller: c.firstNameController, icon: Icons.person, ), ), const SizedBox(width: 8), Expanded( child: _buildTextField( label: 'Last Name', controller: c.lastNameController, icon: Icons.person, ), ), ], ), Row( children: [ Expanded( child: _buildTextField( label: 'National Number', controller: c.nationalNumberController, icon: Icons.fingerprint, ), ), const SizedBox(width: 8), Expanded(child: _buildGenderDropdown(c)), ], ), _buildTextField( label: 'Birthdate', controller: c.birthdateController, icon: Icons.cake, onTap: () => c.selectDate(Get.context!, c.birthdateController), ), ], ); } Widget _buildIdBackFields(ReviewDriverController c) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('ID Card Information (Back)', style: Get.textTheme.titleMedium), const Divider(), _buildTextField( label: 'Address', controller: c.addressController, icon: Icons.location_on, maxLines: 2, ), _buildTextField( label: 'Place of Registration', controller: c.siteController, icon: Icons.location_city, ), ], ); } Widget _buildDriverLicenseFields(ReviewDriverController c) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Driver License Information', style: Get.textTheme.titleMedium), const Divider(), _buildTextField( label: 'License Type', controller: c.licenseTypeController, icon: Icons.card_membership, ), _buildTextField( label: 'License Categories', controller: c.licenseCategoriesController, icon: Icons.category, ), _buildTextField( label: 'License Issue Date', controller: c.licenseIssueDateController, icon: Icons.event, onTap: () => c.selectDate(Get.context!, c.licenseIssueDateController), ), ], ); } Widget _buildLicenseBackFields(ReviewDriverController c) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Driver License (Back)', style: Get.textTheme.titleMedium), const Divider(), _buildTextField( label: 'Expiry Date', controller: c.expiryDateController, icon: Icons.event_busy, onTap: () => c.selectDate(Get.context!, c.expiryDateController), ), ], ); } Widget _buildCarFrontFields(ReviewDriverController c) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Car Registration (Front)', style: Get.textTheme.titleMedium), const Divider(), _buildTextField( label: 'Owner Name', controller: c.ownerController, icon: Icons.person_search, ), Row( children: [ Expanded(child: _buildColorDropdown(c)), const SizedBox(width: 8), Expanded( child: _buildTextField( label: 'Car Plate', controller: c.carPlateController, icon: Icons.confirmation_number, ), ), ], ), _buildTextField( label: 'License Issue Date', controller: c.licenseIssueDateController, icon: Icons.event, onTap: () => c.selectDate(Get.context!, c.licenseIssueDateController), ), ], ); } Widget _buildCarBackFields(ReviewDriverController c) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Car Registration (Back)', style: Get.textTheme.titleMedium), const Divider(), Row( children: [ Expanded( child: _buildTextField( label: 'Make', controller: c.makeController, icon: Icons.directions_car, ), ), const SizedBox(width: 8), Expanded( child: _buildTextField( label: 'Model', controller: c.modelController, icon: Icons.model_training, ), ), ], ), Row( children: [ Expanded( child: _buildTextField( label: 'Year', controller: c.yearController, keyboardType: TextInputType.number, ), ), const SizedBox(width: 8), Expanded(child: _buildFuelDropdown(c)), ], ), _buildTextField( label: 'VIN (Chassis Number)', controller: c.vinController, icon: Icons.confirmation_number, ), _buildTextField( label: 'Expiration Date', controller: c.carLicenseExpiryDateController, icon: Icons.event_busy, onTap: () => c.selectDate( Get.context!, c.carLicenseExpiryDateController), ), ], ); } Widget _buildCriminalRecordFields() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Criminal Record', style: Get.textTheme.titleMedium), const Divider(), Card( color: Colors.green[50], child: Padding( padding: const EdgeInsets.all(16), child: Row( children: [ Icon(Icons.check_circle, color: Colors.green[700], size: 32), const SizedBox(width: 12), Expanded( child: Text( 'Review the criminal record document above. ' 'Verify the name matches the driver and the record is valid.', style: TextStyle(color: Colors.green[800]), ), ), ], ), ), ), ], ); } Widget _buildProfilePhotoFields(ReviewDriverController c) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Profile Photo', style: Get.textTheme.titleMedium), const Divider(), Card( color: Colors.blue[50], child: Padding( padding: const EdgeInsets.all(16), child: Row( children: [ Icon(Icons.face, color: Colors.blue[700], size: 32), const SizedBox(width: 12), Expanded( child: Text( 'Verify the profile photo matches the person in the ID ' 'and Driver License photos above.', style: TextStyle(color: Colors.blue[800]), ), ), ], ), ), ), const SizedBox(height: 12), _buildTextField( label: 'Phone Number', controller: c.phoneController, icon: Icons.phone, keyboardType: TextInputType.phone, ), _buildTextField( label: 'Email', controller: c.emailController, icon: Icons.email, keyboardType: TextInputType.emailAddress, ), ], ); } Widget _buildBottomActions(ReviewDriverController c, BuildContext context) { return Obx(() { final saving = c.isSaving.value; return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.05), blurRadius: 10, offset: const Offset(0, -4), ), ], ), child: Row( children: [ Expanded( child: MyElevatedButton( title: 'Save'.tr, onPressed: () { c.saveChanges(); }, kolor: AppColor.blueColor, loading: saving, ), ), const SizedBox(width: 8), Expanded( child: MyElevatedButton( title: 'Activate'.tr, onPressed: () { c.activateDriver(); }, kolor: AppColor.greenColor, loading: saving, ), ), const SizedBox(width: 8), Expanded( child: MyElevatedButton( title: 'Reject'.tr, onPressed: () { c.showRejectDialog(); }, kolor: AppColor.redColor, loading: saving, ), ), ], ), ); }); } }