import 'dart:convert'; // import 'dart:io' as html; import 'dart:typed_data'; // Import for Uint8List import 'package:dropdown_search/dropdown_search.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:http/http.dart' as http; import 'package:nhance_partner/core/routing/routes.dart'; import 'package:nhance_partner/presentation/themes/indicators/text_field_theme.dart'; import '../../../../core/config/env.dart'; import '../../../../core/services/api_service.dart'; import '../../../../data/services/auth_service.dart'; import '../../../../data/utils/Pagination.dart'; import '../../../../data/utils/toastNotification.dart'; import '../../../../data/utils/validators.dart'; import '../../../layouts/main_layout.dart'; import '../../../layouts/responsive_layout.dart'; import '../../../providers/manager_provider.dart'; import '../../../providers/userRoleProvider.dart'; import '../../../providers/user_provider.dart'; import '../../../themes/indicators/customizd_file_upload.dart'; import '../../../themes/indicators/export_btn.dart'; import '../../../themes/indicators/input_field_decoration.dart'; import '../../../themes/indicators/search_field_theme.dart'; import '../../../themes/indicators/singleFileUpload.dart'; // import '../../../themes/indicators/upload_doc_theme.dart'; import 'package:universal_html/html.dart' as html; class Agent extends ConsumerStatefulWidget { final String? id; final void Function(String value) onSubmit; const Agent({super.key, this.id, required this.onSubmit}); @override ConsumerState createState() => AgentState(); } class AgentState extends ConsumerState { final _formKey = GlobalKey(); late ApiService apiService; List tabHeader = [ 'name', 'email', 'mobile', 'code', 'address', 'retenRate', ]; late String isActive = "1"; // html.File? docUploadedFile; // PlatformFile? passportFile; String? selectedFileNames; String? passportFileUrlFromApi; String? selectedId; PlatformFile? docUploadedFile; final GlobalKey>> dropDownKey = GlobalKey>>(); Map controllers = {}; String? _token; dynamic userId; dynamic managerId; dynamic role; bool isLoading = false; dynamic selectedSalesExectv; List> filteredSalesExecutiveData = []; List> getSalesExecutiveData = []; Map dataDetails() { final data = { "name": controllers["name"]?.text, "email": controllers["email"]?.text, "mobile": controllers["mobile"]?.text, "address": controllers["address"]?.text, "agent_code": controllers["code"]?.text, "retention_rate": controllers["retenRate"]?.text, 'sales_executive_id': selectedSalesExectv, "is_active": isActive, "manager_id": managerId, }; return data; } @override void initState() { super.initState(); apiService = ApiService(); print('AGID - ${widget.id}'); for (String field in tabHeader) { controllers[field] = TextEditingController(); } updateData(); _initializeToken(); Future.microtask(() { managerId = ref.watch(managerIdProvider); userId = ref.watch(userIdProvider); role = ref.read(userRoleProvider); print("E43 => mId: $managerId"); if (managerId != null && role != null) { getRole(managerId, role); } }); } Future _initializeToken() async { _token = await AuthService.getToken(); print("APISERTOKEN - $_token"); } Future getRole(int id, role) async { print('getSalesExecutiveData called'); setState(() { isLoading = true; }); try { final response = await apiService.fetchSalesExecutiveList(id, role); if (response['status'] == 'success') { print('getRole - ${response['data']}'); setState(() { getSalesExecutiveData = List>.from( response['data'], ); print('API Data - $getSalesExecutiveData'); filteredSalesExecutiveData = getSalesExecutiveData .where((item) => int.tryParse(item['is_active'].toString()) == 1) .toList(); print('filteredSalesExecutiveData - $filteredSalesExecutiveData'); }); } else { getSalesExecutiveData = []; filteredSalesExecutiveData = []; } } catch (e) { print('Exception occurred: $e'); } finally { setState(() { isLoading = false; }); } } void updateData() async { if (widget.id != null && widget.id != 'create') { dynamic response = await apiService.findSingleAgentData(widget.id!); final data = response['data']; print("updateData - ${response['data']}"); if (data == null) return; setState(() { selectedId = widget.id; controllers['name']?.text = data['name'] ?? ''; controllers['email']?.text = data['email'] ?? ''; controllers['mobile']?.text = data['mobile'] ?? ''; controllers['code']?.text = data['agent_code'] ?? ''; controllers['address']?.text = data['address'] ?? ''; controllers['retenRate']?.text = data['retention_rate'] ?? ''; isActive = data["is_active"]; selectedSalesExectv = data['sales_executive_id'] != null ? int.parse(data['sales_executive_id'].toString()) : null; print('selectedSalesExectv - $selectedSalesExectv'); String? apiDocPath = data["certificate_file_name"]; if (apiDocPath != null && apiDocPath.isNotEmpty) { print('apiDocPath - $apiDocPath'); selectedFileNames = apiDocPath.split('/').last; print('selectedFileNames - $selectedFileNames'); passportFileUrlFromApi = apiDocPath; print('passportFileUrlFromApi - $passportFileUrlFromApi'); docUploadedFile = null; } else { selectedFileNames = null; docUploadedFile = null; passportFileUrlFromApi = null; } }); } } Future handleSave() async { if (!_formKey.currentState!.validate()) return; final email = controllers['email']!.text.trim(); final phone = controllers['mobile']!.text.trim(); // Conditional validation: at least one required if (email.isEmpty && phone.isEmpty) { ToastHelper.showSuccessToast( context, 'Please enter either Email or Phone Number', ); return; } print("Debug: current selectedSalesExectv is $selectedSalesExectv"); setState(() { if (_formKey.currentState!.validate()) { final dataSet = dataDetails(); print("dataSetAgent - $dataSet"); print("managerId - $managerId ,userId - $userId "); createUserData(dataSet); } else { // isDisable = false; } }); } Future createUserData(Map userData) async { final String cleanedId = widget.id?.toString().replaceAll(' ', '').toUpperCase() ?? ''; final bool isUpdating = cleanedId.isNotEmpty && cleanedId != 'CREATE' && cleanedId != '0'; final id = widget.id; final uri = Uri.parse( isUpdating ? '${Env.apiUrl}agent/updateAgent' : '${Env.apiUrl}agent/createAgent', ); if (_token == null) { throw Exception('Token not found. Please log in.'); } // Use MultipartRequest (POST only) final request = http.MultipartRequest('POST', uri); request.headers['Authorization'] = 'Bearer $_token'; request.headers['app-signature'] = Env.App_Signature; // If updating, spoof the method Laravel-style if (isUpdating) { // request.fields['_method'] = 'PUT'; request.fields['id'] = id!; request.fields['updated_by'] = userId!.toString(); } else { request.fields['created_by'] = userId!.toString(); } print("USerDAta - $userData"); // userData.forEach((key, value) { // request.fields[key] = value.toString(); // print("✅ Encoded travel_details2: ${request.fields[key]}"); // }); userData.forEach((key, value) { if (key != 'certificate_file_name') { request.fields[key] = value.toString(); print("✅ Encoded $key: ${request.fields[key]}"); } }); // Attach file if selected // if (docUploadedFile != null) { // try { // final reader = html.FileReader(); // reader.readAsArrayBuffer(docUploadedFile!); // await reader.onLoad.first; // // final data = reader.result as Uint8List; // // final multipartFile = http.MultipartFile.fromBytes( // 'certificate_file_name', // data, // filename: docUploadedFile!.name, // ); // // request.files.add(multipartFile); // print("📎 File attached: ${docUploadedFile!.name}"); // } catch (e) { // print("❌ Failed to read file: $e"); // } // } else { // print("⚠️ No passport file selected."); // } // Attach file if selected if (docUploadedFile != null) { try { if (docUploadedFile!.bytes != null) { final multipartFile = http.MultipartFile.fromBytes( 'certificate_file_name', docUploadedFile!.bytes!, filename: docUploadedFile!.name, ); request.files.add(multipartFile); } else if (docUploadedFile!.path != null) { final multipartFile = await http.MultipartFile.fromPath( 'certificate_file_name', docUploadedFile!.path!, filename: docUploadedFile!.name, ); request.files.add(multipartFile); } print("📎 File attached: ${docUploadedFile!.name}"); } catch (e) { print("❌ Failed to attach file: $e"); } } print(" Sending request with fields: ${request.fields}"); try { final streamedResponse = await request.send(); final response = await http.Response.fromStream(streamedResponse); print("Response status: ${response.statusCode}"); print("Response body: ${response.body}"); if (response.statusCode == 200 || response.statusCode == 201) { // dispose(); print("✅ Partner submitted successfully!"); print("Response: ${response.body}"); isUpdating ? ToastHelper.showSuccessToast( context, 'Partner Updated Successfully', ) : ToastHelper.showSuccessToast( context, 'Partner Created Successfully', ); Navigator.of(context).pop(); widget.onSubmit("success"); // context.go(AppRoutes.agentLst); } else if (response.statusCode == 403) { await apiService.clearLocalStorageAndRedirect(); } else { final responseBody = jsonDecode(response.body); dynamic msg = responseBody['data']; print("❌ Submission failed. Status: ${response.statusCode}"); print("Body: ${response.body}"); showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text("Partner User Creation Failed"), content: Text( msg, // "There was a problem in creating user. Please try again.", ), actions: [ TextButton( child: Text("OK"), onPressed: () { Navigator.of(context).pop(); }, ), ], ); }, ); } } catch (e) { print("🔥 Error submitting user: $e"); } } // Future _downloadFile() async { // if (docUploadedFile != null) { // try { // if (kIsWeb) { // // ✅ Web: use bytes // final blob = html.Blob([docUploadedFile!.bytes!]); // final url = html.Url.createObjectUrlFromBlob(blob); // // final anchor = html.AnchorElement(href: url) // ..setAttribute('download', docUploadedFile!.name) // ..click(); // // html.Url.revokeObjectUrl(url); // print("Download triggered successfully (web)!"); // } else { // print("Local file path: ${docUploadedFile!.path}"); // // Use open_filex to open it: // // await OpenFilex.open(docUploadedFile!.path!); // } // } catch (e) { // print("Error during download: $e"); // } // } else if (passportFileUrlFromApi != null) { // print("Download from API: $passportFileUrlFromApi"); // final path = // 'agent/downloadAgentCertificateFile?agent_id=$selectedId'; // // apiService.getPdfDownload(path, selectedId); // } // } @override void dispose() { for (var controller in controllers.values) { controller.dispose(); } super.dispose(); } @override Widget build(BuildContext context) { // managerId = ref.watch(managerIdProvider); // userId = ref.watch(userProvider); return SelectionArea( child: AlertDialog( backgroundColor: Colors.white, content: Container( // color: Colors.yellow.shade50, width: MediaQuery.of(context).size.width * 0.62, height: MediaQuery.of(context).size.height * 0.7, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Container( // height: 30, // color: Colors.red.shade50, width: MediaQuery.of(context).size.width * 0.8, child: GestureDetector( onTap: () { context.go(AppRoutes.agentLst); }, child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.start, children: [ // Tooltip( // message: 'Back', // child: IconButton( // icon: const Icon( // Icons.arrow_left_sharp, // size: 25, // color: Color(0xFF425B5B), // ), // onPressed: () { // context.go(AppRoutes.agentLst); // }, // splashRadius: 18, // hoverColor: Colors.black12, // padding: const EdgeInsets.all(4), // constraints: const BoxConstraints(), // ), // ), const SizedBox(width: 15), // spacing between icon and text Text( "Partner", style: GoogleFonts.poppins( fontSize: 14, fontWeight: FontWeight.w500, ), ), Spacer(), GestureDetector( onTap: () => Navigator.pop(context), child: Container( padding: const EdgeInsets.all(5.0), decoration: BoxDecoration( color: const Color(0xFFF1F1F1), borderRadius: BorderRadius.circular(5.0), ), child: Tooltip( message: 'Close', child: const Icon(Icons.close, size: 18), ), ), ), // const SizedBox(width: 15), ], ), ), ), // SizedBox(height: 10), Expanded( child: Container( // color: Colors.green, // width: MediaQuery.of(context).size.width, // margin: EdgeInsets.all(8.0), padding: EdgeInsets.symmetric(horizontal: 14.0, vertical: 20.0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8.0), color: Colors.white, // color: Color(0xFFEDF6F5), ), child: Column( children: [ Row(children: [buildFormFields()]), Spacer(), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ GestureDetector( onTap: () { handleSave(); }, child: Container( padding: EdgeInsets.symmetric( horizontal: 45.0, vertical: 8, ), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8.0), color: Color(0xFF2E7D6E), // color: Color(0xFF425B5B), ), child: Text( 'Save', style: GoogleFonts.poppins( color: Colors.white, fontSize: 12, ), ), ), ), ], ), SizedBox(height: 30), ], ), ), ), SizedBox(height: 10), ], ), ), ),); } Widget buildFormFields() { return Form( key: _formKey, child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ buildName(), SizedBox(width: 25), buildEmail(), SizedBox(width: 25), buildPhNumber(), ], ), SizedBox(height: 20), Row( children: [ buildId(), SizedBox(width: 25), buildSalesExecutive(context), SizedBox(width: 25), buildRetentionRate(context), ], ), SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ buildAddress(), SizedBox(width: 25), buildUploadDocument(), SizedBox(width: 25), // Expanded(child: SizedBox.shrink()), ], ), // Column( // children: [ // Expanded(child: buildIncentiveFile()), // SizedBox(width: 25), // Expanded(child: SizedBox.shrink()), // ], // ), ], ), ); } Widget buildName() { return Column( crossAxisAlignment: CrossAxisAlignment.start, // mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text("Full Name *", style: _textStyle), SizedBox(height: 10), ThemedFormField( controller: controllers['name']!, validator: (value) => Validators.requiredField(value, "name"), inputFormatters: [ // This line now allows letters, numbers, hyphens, and underscores FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9\-_ ]')), ], borderColor: Color(0xFFE2E8F0), highlightColor: Color(0xFF50A398), txtwidth: MediaQuery.of(context).size.width * 0.18, ), ], ); } Widget buildEmail() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Email *", style: _textStyle), SizedBox(height: 10), ThemedFormField( controller: controllers['email']!, validator: (value) { final phone = controllers['mobile']!.text.trim(); if (value!.isEmpty && phone.isNotEmpty) { return null; // phone is given → email not required } return Validators.email(value, "email"); }, // validator: (value) => Validators.email(value, "email"), borderColor: Color(0xFFE2E8F0), highlightColor: Color(0xFF50A398), inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_@.]')), ], txtwidth: MediaQuery.of(context).size.width * 0.18, ), ], ); } Widget buildPhNumber() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Phone Number *", style: _textStyle), SizedBox(height: 10), ThemedFormField( controller: controllers['mobile']!, validator: (value) { final email = controllers['email']!.text.trim(); if (value!.isEmpty && email.isNotEmpty) { return null; // email is given → phone not required } return Validators.phone(value, "phNumber"); }, // validator: (value) => Validators.phone(value, "phNumber"), borderColor: Color(0xFFE2E8F0), highlightColor: Color(0xFF50A398), inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), ], txtwidth: MediaQuery.of(context).size.width * 0.18, ), ], ); } Widget buildId() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Partner Id *", style: _textStyle), SizedBox(height: 10), ThemedFormField( controller: controllers['code']!, inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9]')), ], borderColor: Color(0xFFE2E8F0), highlightColor: Color(0xFF50A398), validator: (value) => Validators.requiredField(value, "id"), txtwidth: MediaQuery.of(context).size.width * 0.18, ), ], ); } Widget buildRetentionRate(context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Retention Rate*", style: _textStyle), SizedBox(height: 10), ThemedFormField( controller: controllers['retenRate']!, inputFormatters: [ TextInputFormatter.withFunction((oldValue, newValue) { if (newValue.text.isEmpty) return newValue; final value = double.tryParse(newValue.text); if (value == null) return oldValue; // Allow only values <= 10 if (value <= 10) { return newValue; } return oldValue; }), ], keyboardType: TextInputType.numberWithOptions(decimal: true), borderColor: Color(0xFFE2E8F0), highlightColor: Color(0xFF50A398), validator: (value) => Validators.requiredField(value, "id"), txtwidth: MediaQuery.of(context).size.width * 0.18, ), ], ); } Widget buildAddress() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Address", style: _textStyle), SizedBox(height: 10), ThemedFormField( controller: controllers['address']!, borderColor: Color(0xFFE2E8F0), highlightColor: Color(0xFF50A398), txtwidth: MediaQuery.of(context).size.width * 0.18, inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'[ a-zA-Z0-9_#/.]')), ], ), ], ); } Widget buildSalesExecutive(BuildContext context) { Map? selectedSE; if (selectedSalesExectv != null && filteredSalesExecutiveData.isNotEmpty) { selectedSE = filteredSalesExecutiveData.firstWhere( (item) => item['id'].toString() == selectedSalesExectv.toString(), orElse: () => {}, // ✅ MUST be null ); } print('selectedSalesExectv = $selectedSalesExectv'); final isReadOnly = false; // final isReadOnly = widget.id != null; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Sales Executive *", style: _textStyle), SizedBox(height: 10), Container( decoration: BoxDecoration( // color: Colors.white, borderRadius: BorderRadius.circular(10.0), ), width: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.18, // height: 40, child: AbsorbPointer( absorbing: isReadOnly, child: DropdownSearch>( key: dropDownKey, selectedItem: selectedSE, items: (filter, infiniteScrollProps) { return filteredSalesExecutiveData; }, itemAsString: (val) => val['name'].toString(), // what to show compareFn: (item, selectedItem) => item['id'] == selectedItem['id'], // ✅ compare by id // validator: (val) { // if (val == null) { // return "Required"; // ✅ error message // } // return null; // }, decoratorProps: DropDownDecoratorProps( decoration: AppInputDecorations.dropdownDecoration( label: "Select Executive", ).copyWith( filled: true, fillColor: Colors.white, // 👈 makes the dropdown input white isDense: true, border: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: const BorderSide( color: Color(0xFFE2E8F0), width: 1, ), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(5), borderSide: const BorderSide( color: Color(0xFFE2E8F0), width: 1, ), ), contentPadding: EdgeInsets.symmetric( horizontal: 8, vertical: 6, ), ), ), popupProps: PopupProps.menu( fit: FlexFit.loose, constraints: BoxConstraints(maxHeight: 250), menuProps: MenuProps( backgroundColor: Colors.white, // 👈 sets dropdown background to white ), showSearchBox: true, searchFieldProps: TextFieldProps( autofocus: true, decoration: InputDecoration( contentPadding: EdgeInsets.all(3), filled: true, fillColor: Colors.white, hintText: "Select Executive...", hintStyle: GoogleFonts.inter( fontSize: 12, color: Colors.black, ), enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: Color(0xFFE2E8F0), // color: Colors.white, ), // 👈 Normal border ), focusedBorder: OutlineInputBorder( borderSide: BorderSide( color: Color(0xFFE2E8F0), // color: Colors.white, width: 1.5, ), // 👈 Focused border ), enabled: widget.id == null, ), ), itemBuilder: (context, item, isDisabled, isSelected) { return Container( color: isSelected ? Colors.blue.withOpacity(0.1) : Colors.white, padding: EdgeInsets.symmetric(horizontal: 5, vertical: 5), child: Text( item['name'].toString(), style: GoogleFonts.inter( fontSize: 11, color: Colors.black87, fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal, ), ), ); }, // constraints: BoxConstraints(), ), onChanged: (val) { setState(() { selectedSalesExectv = val?['id']?.toString(); }); print("UI Updated with ID: $selectedSalesExectv"); }, ), ), ), ], ); } Widget buildUploadDocument() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Upload Certificate", style: _textStyle), SizedBox(height: 10), Column( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end, children: [ ThemedUploadField( hintText: selectedFileNames ?? "Upload Document", txtwidth: MediaQuery.of(context).size.width * 0.18, txtheight: 45, borderColor: Color(0xFFE2E8F0), // highlightColor: Color(0xFF50A398), onFileSelected: (fileName, file) { print("Picked file: $fileName (${file.size} bytes)"); setState(() { docUploadedFile = file; }); }, ), const SizedBox(height: 5), if (docUploadedFile != null || passportFileUrlFromApi != null) Container( // color: Colors.white, child: Column( children: [ // IconButton( // onPressed: () { // setState(() { // docUploadedFile = null; // passportFileUrlFromApi = null; // selectedFileNames = null; // }); // }, // icon: Icon( // Icons.remove_circle_outline_rounded, // color: Colors.redAccent, // ), // tooltip: 'To Remove Upload', // ), InkWell( onTap: () => apiService.downloadFile( apiUrl: 'agent/downloadAgentCertificateFile?agent_id=$selectedId', apiId: selectedId, localFile: docUploadedFile, fileName: selectedFileNames, ), child: Container( // padding: const EdgeInsets.all(5), decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), // color: Color(0xFF425B5B), // color: Colors.green.shade300, ), child: Column( children: const [ Text( "Download", style: TextStyle( fontSize: 11, fontWeight: FontWeight.w600, // color: Colors.white, color: Color(0xFF2E7D6E), ), ), // SizedBox(width: 5), // Icon(Icons.download, size: 13, color: Colors.white), ], ), ), ), ], ), ), ], ), // Column( // crossAxisAlignment: CrossAxisAlignment.end, // children: [ // ThemedUploadField( // hintText: selectedFileNames ?? "Upload Document", // txtwidth: MediaQuery.of(context).size.width * 0.18, // // onFileSelected: (fileName, file) { // // print("File picked: ${fileName}"); // // print("Size: ${file.size}"); // // print("Path: ${file.path}"); // works on mobile/desktop // // print("Bytes: ${file.bytes}"); // print("Picked file: $fileName (${file.size} bytes)"); // setState(() { // docUploadedFile = file; // }); // }, // ), // SizedBox(height: 5), // // if (docUploadedFile != null || passportFileUrlFromApi != null) // // Centers the text // Container( // color: Colors.white, // child: Column( // mainAxisAlignment: MainAxisAlignment.end, // crossAxisAlignment: CrossAxisAlignment.end, // children: [ // GestureDetector( // onTap: () { // print('DOWNLOAD - $docUploadedFile'); // // if (docUploadedFile != null) { // try { // final blob = html.Blob([docUploadedFile!]); // // final url = html.Url.createObjectUrlFromBlob(blob); // // final anchor = html.AnchorElement(href: url) // ..setAttribute( // 'download', // selectedFileNames ?? "document.pdf", // ) // ..click(); // // html.Url.revokeObjectUrl(url); // // print("Download triggered successfully!"); // } catch (e) { // print("Error during download: $e"); // } // } else if (passportFileUrlFromApi != null) { // print("Raw file path: $passportFileUrlFromApi"); // // final path = // 'agent/downloadAgentCertificateFile?agent_id=$selectedId'; // // apiService.getPdfDownload(path, selectedId); // } else { // print("No file available to download."); // } // }, // // // onTap: () { // // print('DOWNLOAD - $docUploadedFile'); // // // // if (docUploadedFile != null) { // // try { // // if (kIsWeb) { // // // ✅ WEB: use bytes // // final blob = html.Blob([docUploadedFile!.bytes!]); // // final url = html.Url.createObjectUrlFromBlob( // // blob, // // ); // // // // final anchor = html.AnchorElement(href: url) // // ..setAttribute( // // 'download', // // selectedFileNames ?? "document.pdf", // // ) // // ..click(); // // // // html.Url.revokeObjectUrl(url); // // print("Download triggered successfully (web)!"); // // } else { // // // ✅ MOBILE/DESKTOP: use file path // // print( // // "Local file path: ${docUploadedFile!.path}", // // ); // // // // // Example: open the file using open_filex // // // await OpenFilex.open(docUploadedFile!.path!); // // } // // } catch (e) { // // print("Error during download: $e"); // // } // // } else if (passportFileUrlFromApi != null) { // // print("Raw file path: $passportFileUrlFromApi"); // // // // final path = // // 'agent/downloadAgentCertificateFile?agent_id=$selectedId'; // // // // apiService.getPdfDownload(path, selectedId); // // } else { // // print("No file available to download."); // // } // // }, // child: Container( // padding: const EdgeInsets.all(5), // decoration: BoxDecoration( // borderRadius: BorderRadius.circular(5), // color: Colors.green.shade300, // ), // child: Column( // mainAxisAlignment: MainAxisAlignment.end, // crossAxisAlignment: CrossAxisAlignment.end, // children: [ // Text( // "Download", // style: TextStyle( // fontSize: 12, // fontWeight: FontWeight.w200, // color: Colors.white, // ), // overflow: TextOverflow.ellipsis, // textAlign: TextAlign // .end, // Ensures text is centered within the Text widget // ), // SizedBox(width: 5), // Icon(Icons.download, size: 13, color: Colors.white), // ], // ), // ), // ), // ], // ), // ), // ], // ), ], ); } static final _textStyle = GoogleFonts.poppins( fontSize: 12, fontWeight: FontWeight.w500, ); }