feat: Refactor document upload flow to support selected file path management

This commit is contained in:
Achintha Isuru
2026-03-01 20:09:23 -05:00
parent 632e0cca3d
commit e0e7bd51ce
4 changed files with 32 additions and 38 deletions

View File

@@ -50,21 +50,11 @@ class DocumentsRepositoryImpl implements DocumentsRepository {
);
final String description = (currentDoc.description ?? '').toLowerCase();
String verificationType = 'government_id';
if (description.contains('permit')) {
verificationType = 'work_permit';
} else if (description.contains('passport')) {
verificationType = 'passport';
} else if (description.contains('ssn') ||
description.contains('social security')) {
verificationType = 'ssn';
}
final String staffId = await _service.getStaffId();
final VerificationResponse verificationRes = await _verificationService
.createVerification(
fileUri: uploadRes.fileUri,
type: verificationType,
type: 'government_id',
subjectType: 'worker',
subjectId: staffId,
rules: <String, dynamic>{
@@ -75,7 +65,7 @@ class DocumentsRepositoryImpl implements DocumentsRepository {
// 4. Update/Create StaffDocument in Data Connect
await _service.getStaffRepository().upsertStaffDocument(
documentId: documentId,
documentUrl: uploadRes.fileUri,
documentUrl: signedUrlRes.signedUrl,
status: domain.DocumentStatus.pending,
verificationId: verificationRes.verificationId,
);

View File

@@ -19,6 +19,11 @@ class DocumentUploadCubit extends Cubit<DocumentUploadState> {
emit(state.copyWith(isAttested: value));
}
/// Sets the selected file path for the document.
void setSelectedFilePath(String filePath) {
emit(state.copyWith(selectedFilePath: filePath));
}
/// Uploads the selected document if the user has attested.
///
/// Requires [state.isAttested] to be true before proceeding.

View File

@@ -7,6 +7,7 @@ class DocumentUploadState extends Equatable {
const DocumentUploadState({
this.status = DocumentUploadStatus.initial,
this.isAttested = false,
this.selectedFilePath,
this.documentUrl,
this.updatedDocument,
this.errorMessage,
@@ -14,6 +15,7 @@ class DocumentUploadState extends Equatable {
final DocumentUploadStatus status;
final bool isAttested;
final String? selectedFilePath;
final String? documentUrl;
final StaffDocument? updatedDocument;
final String? errorMessage;
@@ -21,6 +23,7 @@ class DocumentUploadState extends Equatable {
DocumentUploadState copyWith({
DocumentUploadStatus? status,
bool? isAttested,
String? selectedFilePath,
String? documentUrl,
StaffDocument? updatedDocument,
String? errorMessage,
@@ -28,6 +31,7 @@ class DocumentUploadState extends Equatable {
return DocumentUploadState(
status: status ?? this.status,
isAttested: isAttested ?? this.isAttested,
selectedFilePath: selectedFilePath ?? this.selectedFilePath,
documentUrl: documentUrl ?? this.documentUrl,
updatedDocument: updatedDocument ?? this.updatedDocument,
errorMessage: errorMessage ?? this.errorMessage,
@@ -38,6 +42,7 @@ class DocumentUploadState extends Equatable {
List<Object?> get props => <Object?>[
status,
isAttested,
selectedFilePath,
documentUrl,
updatedDocument,
errorMessage,

View File

@@ -17,7 +17,7 @@ import '../widgets/document_upload/pdf_file_types_banner.dart';
///
/// Mirrors the pattern used in [AttireCapturePage] for a consistent upload flow:
/// file selection → attestation → submit → poll for result.
class DocumentUploadPage extends StatefulWidget {
class DocumentUploadPage extends StatelessWidget {
const DocumentUploadPage({
super.key,
required this.document,
@@ -30,20 +30,17 @@ class DocumentUploadPage extends StatefulWidget {
/// Optional URL of an already-uploaded document.
final String? initialUrl;
@override
State<DocumentUploadPage> createState() => _DocumentUploadPageState();
}
class _DocumentUploadPageState extends State<DocumentUploadPage> {
String? _selectedFilePath;
@override
Widget build(BuildContext context) {
if (widget.initialUrl != null) {
_selectedFilePath = widget.initialUrl;
}
return BlocProvider<DocumentUploadCubit>(
create: (BuildContext _) => Modular.get<DocumentUploadCubit>(),
create: (BuildContext _) {
final DocumentUploadCubit cubit =
Modular.get<DocumentUploadCubit>();
if (initialUrl != null) {
cubit.setSelectedFilePath(initialUrl!);
}
return cubit;
},
child: BlocConsumer<DocumentUploadCubit, DocumentUploadState>(
listener: (BuildContext context, DocumentUploadState state) {
if (state.status == DocumentUploadStatus.success) {
@@ -64,8 +61,8 @@ class _DocumentUploadPageState extends State<DocumentUploadPage> {
builder: (BuildContext context, DocumentUploadState state) {
return Scaffold(
appBar: UiAppBar(
title: widget.document.name,
subtitle: widget.document.description,
title: document.name,
subtitle: document.description,
onLeadingPressed: () => Modular.to.toDocuments(),
),
body: SingleChildScrollView(
@@ -78,11 +75,10 @@ class _DocumentUploadPageState extends State<DocumentUploadPage> {
),
const SizedBox(height: UiConstants.space6),
DocumentFileSelector(
selectedFilePath: _selectedFilePath,
selectedFilePath: state.selectedFilePath,
onFileSelected: (String path) {
setState(() {
_selectedFilePath = path;
});
BlocProvider.of<DocumentUploadCubit>(context)
.setSelectedFilePath(path);
},
),
],
@@ -109,15 +105,13 @@ class _DocumentUploadPageState extends State<DocumentUploadPage> {
DocumentUploadFooter(
isUploading:
state.status == DocumentUploadStatus.uploading,
canSubmit: _selectedFilePath != null && state.isAttested,
canSubmit: state.selectedFilePath != null && state.isAttested,
onSubmit: () {
BlocProvider.of<DocumentUploadCubit>(
context,
).uploadDocument(
widget.document.documentId,
_selectedFilePath!,
);
BlocProvider.of<DocumentUploadCubit>(context)
.uploadDocument(
document.documentId,
state.selectedFilePath!,
);
},
),
],