3import 'package:easy_localization/easy_localization.dart';
4import 'package:flutter/material.dart';
5import 'package:flutter_bloc/flutter_bloc.dart';
6import 'package:flutter_screenutil/flutter_screenutil.dart';
8import '../../../../../core/services/check_in_service.dart';
9import '../../../../../core/ui/theme/color_palette.dart';
10import '../../../../../core/ui/widgets/custom_scaffold.dart';
11import '../../../../../core/ui/widgets/custom_slider.dart';
12import '../../../../../core/ui/widgets/custom_snackbar.dart';
13import '../../../../../core/ui/widgets/empty_content.dart';
14import '../../../../../core/ui/widgets/error_widget.dart';
15import '../../../../../core/ui/widgets/loading.dart';
16import '../../../../../core/ui/widgets/stats_card.dart';
17import '../../../../auth/presentation/bloc/authentication_bloc/authentication_bloc.dart';
18import '../../../../auth/presentation/bloc/check_in_out_bloc/check_in_out_bloc.dart';
19import '../../../data/models/collection_voucher_model.dart';
20import '../../../domain/entities/unloading_collection_entity.dart';
21import '../../bloc/unloading_bloc.dart';
22import '../../bloc/unloading_event.dart';
23import '../../bloc/unloading_state.dart';
24import '../../widgets/unloading_confirmation_dialog.dart';
25import '../widgets/unloading_collection_item.dart';
31 State<UnloadingProcessView>
createState() => _UnloadingProcessViewState();
34class _UnloadingProcessViewState
extends State<UnloadingProcessView> {
62 if (selected ??
false) {
70 final state = context.read<UnloadingBloc>().state;
71 if (state is PendingUnloadingCollectionsLoaded) {
92 Widget
build(BuildContext context) {
93 return CustomScaffold(
95 body: MultiBlocListener(
97 BlocListener<UnloadingBloc, UnloadingState>(
98 listenWhen: (previous, current) => current is SendUnloadingSuccess || current is
UnloadingError,
101 BlocListener<CheckInOutBloc, CheckInOutState>(
103 listener: (context, state) {
108 "Checkout failed: ${state.failure.message}"
114 child: BlocBuilder<UnloadingBloc, UnloadingState>(
115 buildWhen: (previous, current) =>
116 current is UnloadingLoading ||
117 current is SendUnloadingLoading ||
119 current is PendingUnloadingCollectionsLoaded,
120 builder: (context, state) {
122 return const Loading();
124 return CustomErrorWidget(
125 message:
"unloading.connection_failed".tr(),
128 }
else if (state is PendingUnloadingCollectionsLoaded) {
131 return Center(
child:
Text(
'unloading.no_data'.tr()));
140 if (state is SendUnloadingSuccess) {
144 "unloading.unloading_success".tr(),
167 final authState = context.read<AuthenticationBloc>().state;
168 if (authState is AuthenticatedState) {
174 barrierDismissible:
false,
175 builder: (BuildContext dialogContext) {
177 shape: RoundedRectangleBorder(
178 borderRadius: BorderRadius.circular(16),
185 'unloading.checkout_required'.tr(),
188 fontWeight: FontWeight.bold,
195 mainAxisSize: MainAxisSize.min,
196 crossAxisAlignment: CrossAxisAlignment.start,
199 'unloading.checkout_completed'.tr(),
200 style: TextStyle(fontSize: 16.sp),
204 'unloading.checkout_instruction'.tr(),
207 fontWeight: FontWeight.w500,
215 width:
double.infinity,
216 padding: EdgeInsets.symmetric(horizontal: 16.sp),
217 child: ElevatedButton(
220 checkInService.clearCheckInStatus().then((
_) {
221 if(dialogContext.mounted) Navigator.of(dialogContext).pop();
223 context.read<AuthenticationBloc>().add(SignOutEvent());
227 "unloading.checkout_success".tr()
232 style: ElevatedButton.styleFrom(
234 padding: EdgeInsets.symmetric(vertical: 12.sp),
235 shape: RoundedRectangleBorder(
236 borderRadius: BorderRadius.circular(8),
240 'unloading.checkout_button'.tr(),
244 fontWeight: FontWeight.bold,
265 return SingleChildScrollView(
267 crossAxisAlignment: CrossAxisAlignment.start,
283 padding: EdgeInsets.symmetric(horizontal: 15.sp),
285 gradient: LinearGradient(
291 title:
'unloading.collections_to_unload'.tr(),
299 if (volume == null)
return "--";
300 double volumeValue = volume is
double ? volume :
double.tryParse(volume.toString()) ?? 0.0;
301 if (volumeValue > 999) {
302 return '${(volumeValue / 1000).toStringAsFixed(2)} MT';
304 return '$volumeValue KG';
310 padding: EdgeInsets.symmetric(horizontal: 15.sp, vertical: 16.sp),
319 shape: RoundedRectangleBorder(
320 borderRadius: BorderRadius.circular(4),
322 side: BorderSide(width: 1.5,
color: Colors.grey[400]!),
327 'common.select_all'.tr(),
330 fontWeight: FontWeight.w500,
331 color: Colors.grey[700],
343 padding: EdgeInsets.only(top: 90.sp),
344 child: EmptyContent(text:
'unloading.no_pending_collections'.tr()),
349 return ListView.builder(
351 physics:
const NeverScrollableScrollPhysics(),
353 itemBuilder: (context, index) {
354 final collection = collections[index];
355 return UnloadingCollectionItem(
356 collection: collection,
357 number: (index + 1).toString(),
358 isSelected: _selectedItems[collection.id ?? 0] ?? false,
359 onCheckboxChanged: (selected) => _handleItemSelection(selected, collection),
367 padding: EdgeInsets.symmetric(horizontal: 15.sp),
370 text:
'unloading.unloading_action'.tr(),
380 "unloading.select_collection_error".tr(),
385 final authState = context.read<AuthenticationBloc>().state;
386 if (authState is AuthenticatedState) {
388 userId: authState.session.uid.toString(),
390 onConfirm: (user, firstWeight) {
392 _isProcessingUnloading = true;
394 context.read<UnloadingBloc>().add(
396 warehouseResponsibleId:
int.parse(user),
397 firstWeight: firstWeight,
398 userId: authState.session.uid ?? 0,
400 (e) => CollectionVoucherModel(
413 final authState = context.read<AuthenticationBloc>().state;
414 if (authState is AuthenticatedState) {
415 context.read<UnloadingBloc>().add(
override void initState()
class App extends StatefulWidget build(BuildContext context)
sealed class CheckInOutEvent extends Equatable userId
const SendVehicleCheckFailureState({required this.failure})
static const antiFlashWhite
static ScaffoldFeatureController< SnackBar, SnackBarClosedReason > display(final BuildContext context, final Color color, final String message,)
void _handleBlocStateChanges(BuildContext context, CollectionsState state)
sealed class CollectionsState extends Equatable collections
void showUnloadingConfirmationDialog({ required BuildContext context, required Function(String user, double firstWeight) onConfirm, required String userId, })
const GetPendingUnloadingCollectionsEvent({required this.userId})
String formatVolume(dynamic volume)
double _calculateTotalVolume(List< dynamic > history)
void _handleUnloadingAction()
Widget _buildSelectAllOption(List< UnloadingCollectionEntity > collections)
void _handleItemSelection(bool? selected, UnloadingCollectionEntity collection)
void _handleSelectAll(bool? value, List< UnloadingCollectionEntity > collections)
bool _isProcessingUnloading
final List< UnloadingCollectionEntity > _selectedCollections
Widget _buildStatsCard(List< UnloadingCollectionEntity > collections)
void _updateSelectAllState(List< UnloadingCollectionEntity > collections)
void _loadPendingUnloading()
Widget _buildUnloadingSlider()
class UnloadingProcessView extends StatefulWidget _selectedItems
double _calculateTotalVolume(List< UnloadingCollectionEntity > collections)
Widget _buildCollectionsContent(List< UnloadingCollectionEntity > collections)
const UnloadingError({required this.message})
class SearchWeeklyCollectionsEvent extends WeeklyCollectionsEvent collection
style Text( '${ 'scheduling.reference'.tr()}:${collection.internalCode}', style:Theme.of(context).textTheme.bodySmall,)
style SizedBox(height:2.h)
Widget _buildCollectionsList()
style Column(crossAxisAlignment:CrossAxisAlignment.end, children:[Container(padding:EdgeInsets.symmetric(horizontal:8.w, vertical:4.h), decoration:BoxDecoration(color:ColorPalette.tiffanyBlue.withValues(alpha:0.1), borderRadius:BorderRadius.circular(12),), child:Text(collection.type ?? '', style:Theme.of(context).textTheme.bodySmall?.copyWith(color:ColorPalette.tiffanyBlue, fontWeight:FontWeight.bold,),),),],)