enrollment-app/lib/service/multi_file_upload_widget.dart
2026-02-05 19:15:46 +05:30

227 lines
7.4 KiB
Dart
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import '../responsive.dart';
import 'file_upload_service.dart';
class MultiFileUploadWidget extends StatefulWidget {
final bool forceMobile;
const MultiFileUploadWidget({super.key, this.forceMobile = false});
@override
State<MultiFileUploadWidget> createState() => _MultiFileUploadWidgetState();
static bool hasFiles = false;
}
class _MultiFileUploadWidgetState extends State<MultiFileUploadWidget> {
final fileService = FileUploadService();
String? errorMessage;
void _pickFiles() async {
final error = await fileService.pickFiles(maxFileSizeInMB: 10); // 5 MB limit
if (error != null) {
if (mounted) {
setState(() {
errorMessage = error;
});
// also show alert dialog for big error messages
// showDialog(
// context: context,
// builder: (ctx) => AlertDialog(
// title: const Text("File Upload Error"),
// content: Text(error),
// actions: [
// TextButton(
// onPressed: () => Navigator.pop(ctx),
// child: const Text("OK"),
// ),
// ],
// ),
// );
}
} else {
setState(() {
errorMessage = null;
MultiFileUploadWidget.hasFiles = fileService.files.isNotEmpty;
});
}
}
void _removeFile(int index) {
fileService.removeFileAt(index);
setState(() {
MultiFileUploadWidget.hasFiles = fileService.files.isNotEmpty;
});
}
@override
Widget build(BuildContext context) {
final files = fileService.files;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (widget.forceMobile || Responsive.isMobile(context)) ...[
OutlinedButton.icon(
onPressed: _pickFiles,
icon: const Icon(Icons.file_upload_outlined,
color: Color(0xFF00999E), size: 24),
label: const Text(
"Upload Documents",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
overflow: TextOverflow.ellipsis,
),
style: OutlinedButton.styleFrom(
side: const BorderSide(color: Color(0xFF00999E)),
),
),
const SizedBox(height: 6),
const Text(
"Supports only PDF, PNG, JPG, JPEG,HEIC formats (max 10 MB each)",
style: TextStyle(fontSize: 12, color: Colors.grey),
),
] else ...[
Row(
children: [
OutlinedButton.icon(
onPressed: _pickFiles,
icon: const Icon(Icons.file_upload_outlined,
color: Color(0xFF00999E), size: 24),
label: const Text(
"Upload Documents",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
overflow: TextOverflow.ellipsis,
),
style: OutlinedButton.styleFrom(
side: const BorderSide(color: Color(0xFF00999E)),
),
),
const SizedBox(width: 12),
const Expanded(
child: Text(
"Supports only PDF, PNG, JPG, JPEG,HEIC formats (max 10 MB each)",
style: TextStyle(fontSize: 12, color: Colors.grey),
overflow: TextOverflow.ellipsis,
),
),
],
),
// InkWell(
// onTap: _pickFiles, // ✅ SAME FUNCTION
// child: Container(
// width: double.infinity,
// padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 16),
// decoration: BoxDecoration(
// color: const Color(0xFFF9F9F9),
// borderRadius: BorderRadius.circular(12),
// border: Border.all(
// color: const Color(0xFF00A6A6),
// width: 1,
// style: BorderStyle.solid, // dotted look via color + spacing
// ),
// ),
// child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// /// Icon circle
// Container(
// padding: const EdgeInsets.all(10),
// decoration: BoxDecoration(
// shape: BoxShape.circle,
// border: Border.all(color: const Color(0xFF00A6A6)),
// ),
// child: const Icon(
// Icons.insert_drive_file,
// size: 28,
// color: Color(0xFF00A6A6),
// ),
// ),
//
// const SizedBox(height: 10),
//
// // /// File name (static text logic unchanged)
// // const Text(
// // "Sample_file.PDF",
// // style: TextStyle(
// // fontSize: 14,
// // fontWeight: FontWeight.w500,
// // ),
// // overflow: TextOverflow.ellipsis,
// // ),
// //
// // const SizedBox(height: 6),
//
// /// Helper text
// const Text(
// "(Supported formats: PDF, PNG, JPG, JPEG, HEIC | Max 10MB each)",
// style: TextStyle(
// fontSize: 11,
// color: Colors.grey,
// ),
// textAlign: TextAlign.center,
// ),
// ],
// ),
// ),
// ),
],
if (fileService.files.isEmpty && errorMessage == null) ...[
const SizedBox(height: 4),
const Text(
"Required",
style: TextStyle(color: Colors.red, fontSize: 12),
),
],
if (errorMessage != null) ...[
const SizedBox(height: 4),
Text(
errorMessage!,
style: const TextStyle(color: Colors.red, fontSize: 12),
),
],
const SizedBox(height: 8),
...fileService.files.asMap().entries.map((entry) {
final index = entry.key;
final uploaded = entry.value; // UploadedFile
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ListTile(
dense: true,
contentPadding: EdgeInsets.zero,
title: Text(uploaded.file.name, style: const TextStyle(fontSize: 14)),
trailing: IconButton(
icon: const Icon(Icons.close, color: Colors.red),
onPressed: () => _removeFile(index),
),
),
Padding(
padding: const EdgeInsets.only(left: 8.0, bottom: 8.0, right: 8.0),
child: TextField(
controller: uploaded.controller,
decoration: const InputDecoration(
labelText: 'Enter document name',
border: OutlineInputBorder(),
isDense: true,
),
),
),
],
);
}),
],
);
}
}