From fd0208efa0cc938e133cc8a160a14fdefa0ae744 Mon Sep 17 00:00:00 2001 From: Achintha Isuru Date: Tue, 24 Feb 2026 17:31:41 -0500 Subject: [PATCH] feat: Introduce AttireVerificationStatus enum and add verificationId to staff attire items. --- .../staff_connector_repository_impl.dart | 17 +++++++++-- .../staff_connector_repository.dart | 1 + .../packages/domain/lib/krow_domain.dart | 1 + .../lib/src/entities/profile/attire_item.dart | 9 +++++- .../profile/attire_verification_status.dart | 11 ++++++++ .../pages/attire_capture_page.dart | 28 ++++++++++++------- .../widgets/attire_item_card.dart | 7 ++++- .../connector/staffAttire/mutations.gql | 2 ++ .../connector/staffAttire/queries.gql | 1 + backend/dataconnect/schema/staffAttire.gql | 1 + 10 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 apps/mobile/packages/domain/lib/src/entities/profile/attire_verification_status.dart diff --git a/apps/mobile/packages/data_connect/lib/src/connectors/staff/data/repositories/staff_connector_repository_impl.dart b/apps/mobile/packages/data_connect/lib/src/connectors/staff/data/repositories/staff_connector_repository_impl.dart index b8ab50c9..9cdf0888 100644 --- a/apps/mobile/packages/data_connect/lib/src/connectors/staff/data/repositories/staff_connector_repository_impl.dart +++ b/apps/mobile/packages/data_connect/lib/src/connectors/staff/data/repositories/staff_connector_repository_impl.dart @@ -1,6 +1,7 @@ // ignore_for_file: always_specify_types, depend_on_referenced_packages, dead_code, dead_null_aware_expression, unused_local_variable, unused_import, sort_constructors_first, prefer_final_fields, prefer_const_constructors, deprecated_member_use, implicit_call_tearoffs, implementation_imports import 'package:firebase_data_connect/firebase_data_connect.dart'; -import 'package:krow_data_connect/krow_data_connect.dart'; +import 'package:krow_data_connect/krow_data_connect.dart' + hide AttireVerificationStatus; import 'package:krow_domain/krow_domain.dart'; /// Implementation of [StaffConnectorRepository]. @@ -233,17 +234,28 @@ class StaffConnectorRepositoryImpl implements StaffConnectorRepository { description: e.description, imageUrl: e.imageUrl, isMandatory: e.isMandatory ?? false, - verificationStatus: userAttire?.verificationStatus?.stringValue, + verificationStatus: _mapAttireStatus( + userAttire?.verificationStatus?.stringValue, + ), photoUrl: userAttire?.verificationPhotoUrl, ); }).toList(); }); } + AttireVerificationStatus? _mapAttireStatus(String? status) { + if (status == null) return null; + return AttireVerificationStatus.values.firstWhere( + (e) => e.name.toUpperCase() == status.toUpperCase(), + orElse: () => AttireVerificationStatus.pending, + ); + } + @override Future upsertStaffAttire({ required String attireOptionId, required String photoUrl, + String? verificationId, }) async { await _service.run(() async { final String staffId = await _service.getStaffId(); @@ -251,6 +263,7 @@ class StaffConnectorRepositoryImpl implements StaffConnectorRepository { await _service.connector .upsertStaffAttire(staffId: staffId, attireOptionId: attireOptionId) .verificationPhotoUrl(photoUrl) + // .verificationId(verificationId) // Uncomment after SDK regeneration .execute(); }); } diff --git a/apps/mobile/packages/data_connect/lib/src/connectors/staff/domain/repositories/staff_connector_repository.dart b/apps/mobile/packages/data_connect/lib/src/connectors/staff/domain/repositories/staff_connector_repository.dart index b674b6f1..e4cc2db8 100644 --- a/apps/mobile/packages/data_connect/lib/src/connectors/staff/domain/repositories/staff_connector_repository.dart +++ b/apps/mobile/packages/data_connect/lib/src/connectors/staff/domain/repositories/staff_connector_repository.dart @@ -54,6 +54,7 @@ abstract interface class StaffConnectorRepository { Future upsertStaffAttire({ required String attireOptionId, required String photoUrl, + String? verificationId, }); /// Signs out the current user. diff --git a/apps/mobile/packages/domain/lib/krow_domain.dart b/apps/mobile/packages/domain/lib/krow_domain.dart index 3d2a9b15..9c67574f 100644 --- a/apps/mobile/packages/domain/lib/krow_domain.dart +++ b/apps/mobile/packages/domain/lib/krow_domain.dart @@ -68,6 +68,7 @@ export 'src/adapters/financial/bank_account/bank_account_adapter.dart'; // Profile export 'src/entities/profile/staff_document.dart'; export 'src/entities/profile/attire_item.dart'; +export 'src/entities/profile/attire_verification_status.dart'; export 'src/entities/profile/relationship_type.dart'; export 'src/entities/profile/industry.dart'; export 'src/entities/profile/tax_form.dart'; diff --git a/apps/mobile/packages/domain/lib/src/entities/profile/attire_item.dart b/apps/mobile/packages/domain/lib/src/entities/profile/attire_item.dart index 40d90b32..d830add4 100644 --- a/apps/mobile/packages/domain/lib/src/entities/profile/attire_item.dart +++ b/apps/mobile/packages/domain/lib/src/entities/profile/attire_item.dart @@ -1,5 +1,7 @@ import 'package:equatable/equatable.dart'; +import 'attire_verification_status.dart'; + /// Represents an attire item that a staff member might need or possess. /// /// Attire items are specific clothing or equipment required for jobs. @@ -13,6 +15,7 @@ class AttireItem extends Equatable { this.isMandatory = false, this.verificationStatus, this.photoUrl, + this.verificationId, }); /// Unique identifier of the attire item. @@ -31,11 +34,14 @@ class AttireItem extends Equatable { final bool isMandatory; /// The current verification status of the uploaded photo. - final String? verificationStatus; + final AttireVerificationStatus? verificationStatus; /// The URL of the photo uploaded by the staff member. final String? photoUrl; + /// The ID of the verification record. + final String? verificationId; + @override List get props => [ id, @@ -45,5 +51,6 @@ class AttireItem extends Equatable { isMandatory, verificationStatus, photoUrl, + verificationId, ]; } diff --git a/apps/mobile/packages/domain/lib/src/entities/profile/attire_verification_status.dart b/apps/mobile/packages/domain/lib/src/entities/profile/attire_verification_status.dart new file mode 100644 index 00000000..bc5a3430 --- /dev/null +++ b/apps/mobile/packages/domain/lib/src/entities/profile/attire_verification_status.dart @@ -0,0 +1,11 @@ +/// Represents the verification status of an attire item photo. +enum AttireVerificationStatus { + /// The photo is waiting for review. + pending, + + /// The photo was rejected. + failed, + + /// The photo was approved. + success, +} diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/pages/attire_capture_page.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/pages/attire_capture_page.dart index acc0f983..5585f500 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/pages/attire_capture_page.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/pages/attire_capture_page.dart @@ -74,18 +74,26 @@ class _AttireCapturePageState extends State { state.photoUrl ?? widget.initialPhotoUrl; final bool hasUploadedPhoto = currentPhotoUrl != null; - final String statusText = - widget.item.verificationStatus ?? - (hasUploadedPhoto - ? 'Pending Verification' - : 'Not Uploaded'); + final String statusText = switch (widget + .item + .verificationStatus) { + AttireVerificationStatus.success => 'Approved', + AttireVerificationStatus.failed => 'Rejected', + AttireVerificationStatus.pending => 'Pending Verification', + _ => + hasUploadedPhoto ? 'Pending Verification' : 'Not Uploaded', + }; final Color statusColor = - widget.item.verificationStatus == 'SUCCESS' - ? UiColors.textPrimary - : (hasUploadedPhoto - ? UiColors.textWarning - : UiColors.textInactive); + switch (widget.item.verificationStatus) { + AttireVerificationStatus.success => UiColors.textSuccess, + AttireVerificationStatus.failed => UiColors.textError, + AttireVerificationStatus.pending => UiColors.textWarning, + _ => + hasUploadedPhoto + ? UiColors.textWarning + : UiColors.textInactive, + }; return Column( children: [ diff --git a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/widgets/attire_item_card.dart b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/widgets/attire_item_card.dart index 3b122a39..43c88fbc 100644 --- a/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/widgets/attire_item_card.dart +++ b/apps/mobile/packages/features/staff/profile_sections/onboarding/attire/lib/src/presentation/widgets/attire_item_card.dart @@ -19,7 +19,12 @@ class AttireItemCard extends StatelessWidget { @override Widget build(BuildContext context) { final bool hasPhoto = item.photoUrl != null; - final String statusText = item.verificationStatus ?? 'Not Uploaded'; + final String statusText = switch (item.verificationStatus) { + AttireVerificationStatus.success => 'Approved', + AttireVerificationStatus.failed => 'Rejected', + AttireVerificationStatus.pending => 'Pending', + _ => hasPhoto ? 'Pending' : 'To Do', + }; return GestureDetector( onTap: onTap, diff --git a/backend/dataconnect/connector/staffAttire/mutations.gql b/backend/dataconnect/connector/staffAttire/mutations.gql index 54628d89..25184389 100644 --- a/backend/dataconnect/connector/staffAttire/mutations.gql +++ b/backend/dataconnect/connector/staffAttire/mutations.gql @@ -2,12 +2,14 @@ mutation upsertStaffAttire( $staffId: UUID! $attireOptionId: UUID! $verificationPhotoUrl: String + $verificationId: String ) @auth(level: USER) { staffAttire_upsert( data: { staffId: $staffId attireOptionId: $attireOptionId verificationPhotoUrl: $verificationPhotoUrl + verificationId: $verificationId verificationStatus: PENDING } ) diff --git a/backend/dataconnect/connector/staffAttire/queries.gql b/backend/dataconnect/connector/staffAttire/queries.gql index 6a6d8822..bb7d097c 100644 --- a/backend/dataconnect/connector/staffAttire/queries.gql +++ b/backend/dataconnect/connector/staffAttire/queries.gql @@ -3,5 +3,6 @@ query getStaffAttire($staffId: UUID!) @auth(level: USER) { attireOptionId verificationStatus verificationPhotoUrl + verificationId } } diff --git a/backend/dataconnect/schema/staffAttire.gql b/backend/dataconnect/schema/staffAttire.gql index d1f94ebf..e61e8f9b 100644 --- a/backend/dataconnect/schema/staffAttire.gql +++ b/backend/dataconnect/schema/staffAttire.gql @@ -15,6 +15,7 @@ type StaffAttire @table(name: "staff_attires", key: ["staffId", "attireOptionId" verificationStatus: AttireVerificationStatus @default(expr: "'PENDING'") verifiedAt: Timestamp verificationPhotoUrl: String # Proof of ownership + verificationId: String createdAt: Timestamp @default(expr: "request.time") updatedAt: Timestamp @default(expr: "request.time")