feat: Implement attire item filtering and refactor attire capture flow and repository logic
This commit is contained in:
@@ -196,7 +196,7 @@ extension StaffNavigator on IModularNavigator {
|
||||
///
|
||||
/// Record sizing and appearance information for uniform allocation.
|
||||
void toAttire() {
|
||||
pushNamed(StaffPaths.attire);
|
||||
navigate(StaffPaths.attire);
|
||||
}
|
||||
|
||||
/// Pushes the attire capture page.
|
||||
|
||||
@@ -36,6 +36,10 @@ class AttireRepositoryImpl implements AttireRepository {
|
||||
|
||||
@override
|
||||
Future<AttireItem> uploadPhoto(String itemId, String filePath) async {
|
||||
// 6. Return updated AttireItem by re-fetching to get the PENDING/SUCCESS status
|
||||
final List<AttireItem> finalOptions = await _connector.getAttireOptions();
|
||||
return finalOptions.firstWhere((AttireItem e) => e.id == itemId);
|
||||
|
||||
// 1. Upload file to Core API
|
||||
final FileUploadService uploadService = Modular.get<FileUploadService>();
|
||||
final FileUploadResponse uploadRes = await uploadService.uploadFile(
|
||||
@@ -104,8 +108,8 @@ class AttireRepositoryImpl implements AttireRepository {
|
||||
);
|
||||
|
||||
// 6. Return updated AttireItem by re-fetching to get the PENDING/SUCCESS status
|
||||
final List<AttireItem> finalOptions = await _connector.getAttireOptions();
|
||||
return finalOptions.firstWhere((AttireItem e) => e.id == itemId);
|
||||
// final List<AttireItem> finalOptions = await _connector.getAttireOptions();
|
||||
// return finalOptions.firstWhere((AttireItem e) => e.id == itemId);
|
||||
}
|
||||
|
||||
AttireVerificationStatus _mapToAttireStatus(VerificationStatus status) {
|
||||
|
||||
@@ -64,6 +64,10 @@ class AttireCubit extends Cubit<AttireState>
|
||||
emit(state.copyWith(selectedIds: currentSelection));
|
||||
}
|
||||
|
||||
void updateFilter(String filter) {
|
||||
emit(state.copyWith(filter: filter));
|
||||
}
|
||||
|
||||
void syncCapturedPhoto(AttireItem item) {
|
||||
// Update the options list with the new item data
|
||||
final List<AttireItem> updatedOptions = state.options
|
||||
|
||||
@@ -9,12 +9,14 @@ class AttireState extends Equatable {
|
||||
this.options = const <AttireItem>[],
|
||||
this.selectedIds = const <String>[],
|
||||
this.photoUrls = const <String, String>{},
|
||||
this.filter = 'All',
|
||||
this.errorMessage,
|
||||
});
|
||||
final AttireStatus status;
|
||||
final List<AttireItem> options;
|
||||
final List<String> selectedIds;
|
||||
final Map<String, String> photoUrls;
|
||||
final String filter;
|
||||
final String? errorMessage;
|
||||
|
||||
/// Helper to check if item is mandatory
|
||||
@@ -44,11 +46,20 @@ class AttireState extends Equatable {
|
||||
|
||||
bool get canSave => allMandatorySelected && allMandatoryHavePhotos;
|
||||
|
||||
List<AttireItem> get filteredOptions {
|
||||
return options.where((AttireItem item) {
|
||||
if (filter == 'Required') return item.isMandatory;
|
||||
if (filter == 'Non-Essential') return !item.isMandatory;
|
||||
return true;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
AttireState copyWith({
|
||||
AttireStatus? status,
|
||||
List<AttireItem>? options,
|
||||
List<String>? selectedIds,
|
||||
Map<String, String>? photoUrls,
|
||||
String? filter,
|
||||
String? errorMessage,
|
||||
}) {
|
||||
return AttireState(
|
||||
@@ -56,6 +67,7 @@ class AttireState extends Equatable {
|
||||
options: options ?? this.options,
|
||||
selectedIds: selectedIds ?? this.selectedIds,
|
||||
photoUrls: photoUrls ?? this.photoUrls,
|
||||
filter: filter ?? this.filter,
|
||||
errorMessage: errorMessage,
|
||||
);
|
||||
}
|
||||
@@ -66,6 +78,7 @@ class AttireState extends Equatable {
|
||||
options,
|
||||
selectedIds,
|
||||
photoUrls,
|
||||
filter,
|
||||
errorMessage,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -203,6 +203,15 @@ class _AttireCapturePageState extends State<AttireCapturePage> {
|
||||
type: UiSnackbarType.error,
|
||||
);
|
||||
}
|
||||
|
||||
if (state.status == AttireCaptureStatus.success) {
|
||||
UiSnackbar.show(
|
||||
context,
|
||||
message: 'Attire image submitted for verification',
|
||||
type: UiSnackbarType.success,
|
||||
);
|
||||
Modular.to.toAttire();
|
||||
}
|
||||
},
|
||||
builder: (BuildContext context, AttireCaptureState state) {
|
||||
final String? currentPhotoUrl =
|
||||
|
||||
@@ -12,16 +12,9 @@ import '../widgets/attire_filter_chips.dart';
|
||||
import '../widgets/attire_info_card.dart';
|
||||
import '../widgets/attire_item_card.dart';
|
||||
|
||||
class AttirePage extends StatefulWidget {
|
||||
class AttirePage extends StatelessWidget {
|
||||
const AttirePage({super.key});
|
||||
|
||||
@override
|
||||
State<AttirePage> createState() => _AttirePageState();
|
||||
}
|
||||
|
||||
class _AttirePageState extends State<AttirePage> {
|
||||
String _filter = 'All';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final AttireCubit cubit = Modular.get<AttireCubit>();
|
||||
@@ -30,6 +23,7 @@ class _AttirePageState extends State<AttirePage> {
|
||||
appBar: UiAppBar(
|
||||
title: t.staff_profile_attire.title,
|
||||
showBackButton: true,
|
||||
onLeadingPressed: () => Modular.to.toProfile(),
|
||||
),
|
||||
body: BlocProvider<AttireCubit>.value(
|
||||
value: cubit,
|
||||
@@ -48,14 +42,7 @@ class _AttirePageState extends State<AttirePage> {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
final List<AttireItem> options = state.options;
|
||||
final List<AttireItem> filteredOptions = options.where((
|
||||
AttireItem item,
|
||||
) {
|
||||
if (_filter == 'Required') return item.isMandatory;
|
||||
if (_filter == 'Non-Essential') return !item.isMandatory;
|
||||
return true;
|
||||
}).toList();
|
||||
final List<AttireItem> filteredOptions = state.filteredOptions;
|
||||
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
@@ -70,12 +57,8 @@ class _AttirePageState extends State<AttirePage> {
|
||||
|
||||
// Filter Chips
|
||||
AttireFilterChips(
|
||||
selectedFilter: _filter,
|
||||
onFilterChanged: (String value) {
|
||||
setState(() {
|
||||
_filter = value;
|
||||
});
|
||||
},
|
||||
selectedFilter: state.filter,
|
||||
onFilterChanged: cubit.updateFilter,
|
||||
),
|
||||
const SizedBox(height: UiConstants.space6),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user