Aidra Driver 1.3.5+68
Aidra Driver - Your path to green energy
Loading...
Searching...
No Matches
collection_request_confirmation_screen.dart
Go to the documentation of this file.
1import 'dart:io';
2
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';
7import 'package:go_router/go_router.dart';
8import 'package:image_picker/image_picker.dart';
9
10import '../../../../../core/common/models/confirmation_param_model.dart';
11import '../../../../../core/router/routes.dart';
12import '../../../../../core/services/image_service.dart';
13import '../../../../../core/ui/theme/color_palette.dart';
14import '../../../../../core/ui/widgets/custom_scaffold.dart';
15import '../../../../../core/ui/widgets/custom_slider.dart';
16import '../../../../../core/ui/widgets/custom_snackbar.dart';
17import '../../../../auth/presentation/bloc/authentication_bloc/authentication_bloc.dart';
18import '../../bloc/collections_information_bloc/collections_information_bloc.dart';
19import '../widgets/collection_request_details_header.dart';
20import 'widgets/pictures_sections.dart';
21import 'widgets/scanned_drums_section.dart';
22import 'widgets/status_card_section.dart';
23
24class CollectionRequestConfirmationScreen extends StatefulWidget {
25 final GoRouterState state;
26 const CollectionRequestConfirmationScreen({super.key, required this.state});
27
28 @override
29 State<CollectionRequestConfirmationScreen> createState() => _CollectionRequestConfirmationScreenState();
30}
31
32class _CollectionRequestConfirmationScreenState extends State<CollectionRequestConfirmationScreen> {
34 final ImagePicker _picker = ImagePicker();
39 bool isLoading = false;
40
41 @override
42 void initState() {
43 confirmationParam = widget.state.extra as ConfirmationParamModel?;
44 super.initState();
45 }
46
47 Future<void> _takePhoto(bool isVoucher) async {
48 try {
49 final XFile? image = await _picker.pickImage(
50 source: ImageSource.camera,
51 imageQuality: 80,
52 maxWidth: 1200,
53 maxHeight: 1200,
54 );
55 final String? imageBase64 = await ImageService.instance.processImage(image);
56
57 if (imageBase64 == null) return;
58 if (isVoucher) {
59 setState(() {
60 voucherImageFile = File(image!.path);
61 voucherImageBase64 = imageBase64;
62 });
63 } else {
64 setState(() {
65 drumImageFile = File(image!.path);
66 drumImageBase64 = imageBase64;
67 });
68 }
69 } catch (e) {
70 if (mounted) {
71 ScaffoldMessenger.of(context).showSnackBar(
72 SnackBar(content: Text('Error capturing image: $e')),
73 );
74 }
75 }
76 }
77
78 @override
79 Widget build(BuildContext context) {
80 final ConfirmationParamModel confirmationParamModel = confirmationParam ?? widget.state.extra as ConfirmationParamModel;
81 return PopScope(
82 canPop: false,
83 onPopInvokedWithResult: (didPop, _) {
84 if (didPop) return;
85 ScaffoldMessenger.of(context).showSnackBar(
86 const SnackBar(
87 content: Text('You cannot go back'),
88 backgroundColor: ColorPalette.red,
89 duration: Duration(seconds: 2),
90 ),
91 );
92 },
93 child: BlocListener<CollectionsInformationBloc, CollectionsInformationState>(
94 listenWhen: (previous, current) => current is CollectionConfirmationLoading || current is CollectionConfirmationLoaded || current is CollectionConfirmationError,
95 listener: (context, state) {
96 if (state is CollectionConfirmationError) {
97 setState(() {
98 isLoading = false;
99 });
100 CustomSnackBar.display(context, ColorPalette.orange, state.failure.message);
101 } else if (state is CollectionConfirmationLoaded) {
102 setState(() {
103 isLoading = false;
104 });
105 context.push(Routes.collectionRequestPaymentScreen.route, extra: state.confirmation);
106 } else if (state is CollectionConfirmationLoading) {
107 setState(() {
108 isLoading = true;
109 });
110 }
111 },
112 child: CustomScaffold(
113 isLeadingVisible: false,
115 title: 'confirmation.title'.tr(),
116 backgroundColor: ColorPalette.antiFlashWhite,
117 body: SafeArea(
118 child: Column(
119 children: [
120 Expanded(
121 child: SingleChildScrollView(
122 padding: EdgeInsets.all(20.sp),
123 child: Column(
124 crossAxisAlignment: CrossAxisAlignment.start,
125 children: [
126 CollectionRequestDetailsHeader(
127 address: confirmationParamModel.resCollectionInformationEntity.address,
128 name: confirmationParamModel.resCollectionInformationEntity.restaurant,
129 stepNumber: 2,
130 ),
131 SizedBox(height: 15.sp),
132 StatusCardSection(
133 reference: confirmationParamModel.resCollectionInformationEntity.reference,
134 collectedVolume: confirmationParamModel.resCollectionInformationEntity.volumeCollected,
135 ),
136 SizedBox(height: 15.sp),
137 ScannedDrumsSection(
138 depositedDrums: confirmationParamModel.resCollectionInformationEntity.depositedDrum.split(','),
139 recoveredDrums: confirmationParamModel.resCollectionInformationEntity.recoveredDrum.split(','),
140 ),
141 SizedBox(height: 15.sp),
142 PicturesSections(
143 voucherPicture: voucherImageFile?.path,
144 drumPicture: drumImageFile?.path,
145 onAddVoucherPicture: () => _takePhoto(true),
146 onAddDrumPicture: () => _takePhoto(false),
147 onDeletePicture: (picture) {
148 setState(() {
149 if (picture == voucherImageFile?.path) {
150 voucherImageFile = null;
151 voucherImageBase64 = null;
152 } else if (picture == drumImageFile?.path) {
153 drumImageFile = null;
154 drumImageBase64 = null;
155 }
156 });
157 },
158 ),
159 SizedBox(height: 15.sp),
160 CustomSlider(
161 text: "> > ${'confirmation.confirm_collection'.tr()}",
162 action: (p0) {
164 confirmationParamModel: confirmationParamModel,
165 );
166 },
167 ),
168 ],
169 ),
170 ),
171 ),
172 ],
173 ),
174 ),
175 ),
176 ),
177 );
178 }
179
180 Future<void> _submitData({
181 required ConfirmationParamModel confirmationParamModel,
182 }) async {
183 // if (voucherImageBase64 == null || drumImageBase64 == null) {
184 // CustomSnackBar.display(context, ColorPalette.red, 'Please take photos of both the voucher and drum');
185 // return;
186 // }
187 final authState = context.read<AuthenticationBloc>().state;
188 final int? userId;
189 if (authState is AuthenticatedState) {
190 userId = authState.session.uid;
191 } else {
192 return;
193 }
194 context.read<CollectionsInformationBloc>().add(
195 SendCollectionConfirmationEvent(
196 containerImage: drumImageBase64 ?? "",
197 voucherImage: voucherImageBase64 ?? "",
198 id: confirmationParamModel.resCollectionInformationEntity.id.toString(),
199 invoiceDateDue: DateTime.now(),
200 userId: userId.toString(),
201 address: confirmationParamModel.collectionEntity.address ?? '',
202 reference: confirmationParamModel.collectionEntity.reference ?? '',
203 restaurant: confirmationParamModel.collectionEntity.restaurant ?? '',
204 restaurantId: confirmationParamModel.collectionEntity.restaurantId,
205 volumeCollected: confirmationParamModel.collectionEntity.volumeCollected ?? 0,
206 volumeDeclared: confirmationParamModel.collectionEntity.volume ?? 0,
207 )
208 );
209 }
210}
override void initState()
class App extends StatefulWidget build(BuildContext context)
Definition app.dart:31
AuthGuard _()
List< DrumScan > depositedDrums
class BarCodesScan extends StatefulWidget recoveredDrums
sealed class CheckInOutEvent extends Equatable userId
bool isLoading
static const red
static const antiFlashWhite
static const orange
final ResCollectionInformationEntity resCollectionInformationEntity
static ScaffoldFeatureController< SnackBar, SnackBarClosedReason > display(final BuildContext context, final Color color, final String message,)
static final ImageService instance
Future< String?> processImage(XFile? image) async
const CollectionRequestConfirmationScreen({super.key, required this.state})
override State< CollectionRequestConfirmationScreen > createState()
Future< void > _submitData({ required ConfirmationParamModel confirmationParamModel, }) async
class CollectionRequestConfirmationScreen extends StatefulWidget confirmationParam
final ImagePicker _picker
Future< void > _takePhoto(bool isVoucher) async
final String volumeDeclared
final String invoiceDateDue
final int restaurantId
final String volumeCollected
final String restaurant
const CollectionConfirmationLoaded({required this.confirmation})
final Widget child
final EdgeInsets padding
final String path
class Partner String
final String address
Routes
Definition routes.dart:30
final String title
style Text( '${ 'scheduling.reference'.tr()}:${collection.internalCode}', style:Theme.of(context).textTheme.bodySmall,)
style SizedBox(height:2.h)
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,),),),],)