import 'package:flutter/material.dart'; import 'package:file_picker/file_picker.dart'; import 'package:google_fonts/google_fonts.dart'; import 'fileUploadService.dart'; class ThemedUploadField extends StatefulWidget { final String? hintText; final double? txtwidth; final double? txtheight; final double? fontSZ; final double? borderCirculr; final Color? backgroundColor; final Color? borderColor; final Color? errorBorderColor; final Function(String fileName, PlatformFile file)? onFileSelected; final Function(List fileNames, List files)? onFilesSelected; FormFieldValidator? validator; final List? allowedExtensions; final bool isTxtBtnCase; final String? txtName; final double? padVertical; final double? padHorizontal; final bool allowMultiple; ThemedUploadField({ super.key, this.hintText, this.txtwidth, this.borderCirculr, this.fontSZ, this.txtheight, this.backgroundColor, this.borderColor, this.errorBorderColor, this.onFileSelected, this.onFilesSelected, this.validator, this.allowedExtensions, this.isTxtBtnCase = false, this.txtName, this.padVertical, this.padHorizontal, this.allowMultiple = false, }); @override State createState() => _ThemedUploadFieldState(); } class _ThemedUploadFieldState extends State { final fileService = FileUploadService(); String? selectedFileName; String? selectedMultipleFileNames; String? errorMessage; // @override // void didUpdateWidget(covariant ThemedUploadField oldWidget) { // super.didUpdateWidget(oldWidget); // // if (widget.hintText != oldWidget.hintText) { // setState(() { // selectedFileName = null; // errorMessage = null; // }); // } // } Future _pickFile() async { final error = widget.allowMultiple ? await fileService.pickMultipleFiles( allowedExtensions: widget.allowedExtensions, ) : await fileService.pickSingleFile( allowedExtensions: widget.allowedExtensions, ); if (error != null) { setState(() => errorMessage = error); ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text(error))); } else if (widget.allowMultiple && fileService.multipleFiles.isNotEmpty) { final names = fileService.multipleFiles.map((file) => file.name).toList(); setState(() { selectedMultipleFileNames = names.join(', '); errorMessage = null; }); widget.onFilesSelected?.call(names, fileService.multipleFiles); } else if (!widget.allowMultiple && fileService.singleFile != null) { setState(() { selectedFileName = fileService.singleFile!.name; errorMessage = null; }); widget.onFileSelected?.call( fileService.singleFile!.name, fileService.singleFile!, ); } } @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: widget.txtwidth ?? MediaQuery.of(context).size.width, height: widget.txtheight, child: DecoratedBox( decoration: BoxDecoration(borderRadius: BorderRadius.circular(10)), child: InkWell( onTap: _pickFile, borderRadius: BorderRadius.circular(10), child: Container( padding: EdgeInsets.symmetric( vertical: widget.padVertical ?? 10, horizontal: widget.padHorizontal ?? 15, ), decoration: BoxDecoration( color: widget.backgroundColor ?? Colors.white, borderRadius: BorderRadius.circular( widget.borderCirculr ?? 10, ), border: Border.all( color: errorMessage != null ? (widget.errorBorderColor ?? Colors.red) : (widget.borderColor ?? widget.backgroundColor ?? Colors.grey.shade50), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ if (!widget.isTxtBtnCase) ...[ Expanded( child: Text( (widget.allowMultiple ? selectedMultipleFileNames : selectedFileName) ?? widget.hintText ?? "Upload Document", style: TextStyle( fontSize: widget.fontSZ ?? 12, color: errorMessage != null ? Colors.red : Colors.black, ), overflow: TextOverflow.ellipsis, ), ), const Icon( Icons.file_upload_outlined, color: Colors.black, size: 12, ), ], if (widget.isTxtBtnCase) ...[ Center( child: Tooltip( message: 'Upload Documents', child: Text( widget.txtName!, style: GoogleFonts.inter(fontSize: 12), ), ), ), // const Icon( // Icons.file_upload_outlined, // color: Colors.black, // ), ], ], ), ), ), ), ), if (errorMessage != null) Padding( padding: const EdgeInsets.only(left: 8, top: 4), child: Text( errorMessage!, style: const TextStyle(color: Colors.red, fontSize: 10), ), ), ], ); } } // class ThemedUploadField extends FormField { // ThemedUploadField({ // Key? key, // String? hintText, // double? txtwidth, // double? txtheight, // Color? backgroundColor, // Color? borderColor, // Color? errorBorderColor, // FormFieldValidator? validator, // void Function(String fileName, PlatformFile file)? onFileSelected, // }) : super( // key: key, // validator: validator, // builder: (FormFieldState state) { // final fileService = FileUploadService(); // String? selectedFileName; // // Future _pickFile(BuildContext context) async { // final error = await fileService.pickSingleFile(maxFileSizeInMB: 3); // if (error != null) { // ScaffoldMessenger.of( // context, // ).showSnackBar(SnackBar(content: Text(error))); // state.didChange(null); // mark invalid // } else if (fileService.singleFile != null) { // selectedFileName = fileService.singleFile!.name; // state.didChange(selectedFileName); // update form value // // onFileSelected?.call( // fileService.singleFile!.name, // fileService.singleFile!, // ); // } // } // // return Column( // crossAxisAlignment: CrossAxisAlignment.start, // children: [ // Container( // width: txtwidth ?? MediaQuery.of(state.context).size.width, // height: txtheight, // child: InkWell( // onTap: () => _pickFile(state.context), // child: Container( // padding: const EdgeInsets.symmetric( // vertical: 10, // horizontal: 15, // ), // decoration: BoxDecoration( // color: backgroundColor ?? Colors.white, // borderRadius: BorderRadius.circular(10), // border: Border.all( // color: state.hasError // ? (errorBorderColor ?? Colors.red) // : (borderColor ?? Colors.grey.shade50), // ), // ), // child: Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, // children: [ // Expanded( // child: Text( // selectedFileName ?? hintText ?? "Upload Document", // style: TextStyle( // fontSize: 12, // color: state.hasError // ? Colors.red // : Colors.black, // ), // overflow: TextOverflow.ellipsis, // ), // ), // const Icon( // Icons.file_upload_outlined, // color: Colors.black, // ), // ], // ), // ), // ), // ), // if (state.hasError) // Padding( // padding: const EdgeInsets.only(left: 8, top: 4), // child: Text( // state.errorText ?? "", // style: const TextStyle(color: Colors.red, fontSize: 10), // ), // ), // ], // ); // }, // ); // }