Aidra Driver 1.3.5+68
Aidra Driver - Your path to green energy
Loading...
Searching...
No Matches
collection_request_payment_screen.dart
Go to the documentation of this file.
1import 'dart:convert';
2
3import 'package:easy_localization/easy_localization.dart';
4import 'package:flutter_screenutil/flutter_screenutil.dart';
5import 'package:flutter_bloc/flutter_bloc.dart';
6import 'package:go_router/go_router.dart';
7import 'package:signature/signature.dart';
8import 'package:flutter/material.dart';
9
10import '../../../../../core/router/routes.dart';
11import '../../../../auth/presentation/bloc/authentication_bloc/authentication_bloc.dart';
12import '../../bloc/collections_information_bloc/collections_information_bloc.dart';
13import '../../../domain/entities/res/res_collection_confirmation_entity.dart';
14import '../../../../../core/ui/widgets/custom_scaffold.dart';
15import '../../../../../core/ui/widgets/custom_snackbar.dart';
16import '../../../../../core/ui/widgets/custom_slider.dart';
17import '../widgets/collection_request_details_header.dart';
18import '../../../../../core/ui/theme/color_palette.dart';
19import 'widgets/payment_method_section.dart';
20import 'widgets/volume_info_section.dart';
21import 'widgets/signature_section.dart';
22import 'widgets/contact_selector.dart';
23import 'widgets/rating_dialog.dart';
24
25class CollectionRequestPaymentScreen extends StatefulWidget {
26 final GoRouterState state;
27 const CollectionRequestPaymentScreen({super.key, required this.state});
28
29 @override
30 State<CollectionRequestPaymentScreen> createState() => _CollectionRequestPaymentScreenState();
31}
32
33class _CollectionRequestPaymentScreenState extends State<CollectionRequestPaymentScreen> {
34 bool isLoading = false;
37 final SignatureController _signatureController = SignatureController(
38 penStrokeWidth: 3,
39 penColor: Colors.black,
40 exportBackgroundColor: Colors.white,
41 );
42
43 bool _isDrawingMode = false;
44
47
48 @override
49 void initState() {
51 final int restaurantId = collectionConfirmation?.restaurantId ?? 0;
52 context.read<CollectionsInformationBloc>().add(
54 );
55 context.read<CollectionsInformationBloc>().add(
56 GetCollectionContactListEvent(restaurentId: restaurantId),
57 );
58 super.initState();
59 }
60
61 Future<void> _handleSignatureComplete(int? contactId, String confirmationId) async {
62 if (_signatureController.isEmpty) {
64 context,
66 'full_fill_collection.required_signature_text'.tr(),
67 );
68 return;
69 }
70
71 final image = await _signatureController.toPngBytes();
72 if (image != null) {
73 setState(() {
74 signatureBase64 = base64Encode(image);
75 });
76 if (mounted) {
77 final authState = context.read<AuthenticationBloc>().state;
78 final int? userId;
79 if (authState is AuthenticatedState) {
80 userId = authState.session.uid;
81 } else {
82 return;
83 }
84 context.read<CollectionsInformationBloc>().add(
86 id: confirmationId,
87 invoiceDateDue: DateTime.now().toIso8601String(),
88 userId: userId ?? 0,
92 ),
93 );
94 }
95 }
96 }
97
99 showDialog(
100 context: context,
101 barrierDismissible: false,
102 builder: (context) => BlocProvider.value(
103 value: context.read<CollectionsInformationBloc>(),
104 child: RatingDialog(
105 collectionId: id,
106 onRatingSuccess: () {
107 context.push(Routes.collectionRequestSuccessScreen.route);
108 },
109 ),
110 ),
111 );
112 }
113
114 @override
115 void dispose() {
116 _signatureController.dispose();
117 super.dispose();
118 }
119
120 @override
121 Widget build(BuildContext context) {
123 return PopScope(
124 canPop: false,
125 onPopInvokedWithResult: (didPop, _) {
126 if (didPop) return;
127 ScaffoldMessenger.of(context).showSnackBar(
128 const SnackBar(
129 content: Text('You cannot go back'),
130 backgroundColor: ColorPalette.red,
131 duration: Duration(seconds: 2),
132 ),
133 );
134 },
135 child: BlocListener<CollectionsInformationBloc, CollectionsInformationState>(
136 listenWhen: (previous, current) => current is CollectionPaymentLoading || current is CollectionPaymentLoaded || current is CollectionPaymentError,
137 listener: (context, state) {
138 if (state is CollectionPaymentLoading) setState(() {isLoading = true;});
139 if (state is CollectionPaymentLoaded){
140 setState(() {isLoading = false;});
142 context,
144 'Payment successful',
145 );
146 _showRatingDialog(confirmation.id.toString());
147 }
148 if (state is CollectionPaymentError) {
149 setState(() {isLoading = false;});
151 context,
153 state.failure.message,
154 );
155 }
156 },
157 child: CustomScaffold(
158 isLeadingVisible: false,
160 backgroundColor: ColorPalette.antiFlashWhite,
161 title: "Full-fill Collection",
162 body: SingleChildScrollView(
163 physics: _isDrawingMode
164 ? const NeverScrollableScrollPhysics()
165 : const AlwaysScrollableScrollPhysics(),
166 child: Column(
167 children: [
168 CollectionRequestDetailsHeader(
169 margin: EdgeInsets.all(16.sp),
170 address: confirmation.address ?? '--',
171 name: confirmation.restaurant ?? '--',
172 stepNumber: 3,
173 ),
174 SizedBox(height: 5.sp),
175 VolumeInfoSection(
176 declaredVolume: "${confirmation.volumeDeclared ?? "0"}",
177 collectedVolume: "${confirmation.volumeCollected ?? "0"}",
178 ),
179 SizedBox(height: 16.sp),
180 Padding(
181 padding: EdgeInsets.symmetric(horizontal: 16.sp),
182 child: Column(
183 children: [
184 PaymentMethodSection(
185 restaurantId: confirmation.restaurantId ?? 0,
187 onChanged: (String? newValue) {
188 setState(() {
189 selectedPaymentMethod = newValue!;
190 });
191 },
192 ),
193 SizedBox(height: 16.sp),
194 ContactSelector(
195 selectedContactId: selectedContact,
196 onChanged: (int? newValue) {
197 setState(() {
198 selectedContact = newValue;
199 });
200 },
201 ),
202 SizedBox(height: 16.sp),
203 SignatureSection(
204 isDrawingMode: _isDrawingMode,
205 onDrawingModeToggle: () => setState(() => _isDrawingMode = !_isDrawingMode),
206 onClear: () => _signatureController.clear(),
207 controller: _signatureController,
208 ),
209 SizedBox(height: 16.sp),
210 CustomSlider(
211 text: 'full_fill_collection.full_fill_collection_action'.tr(),
212 action: (controller) {
214 },
215 ),
216 SizedBox(height: 16.sp),
217 ],
218 ),
219 ),
220 ],
221 ),
222 ),
223 ),
224 ),
225 );
226 }
227}
override void initState()
override void dispose()
class App extends StatefulWidget build(BuildContext context)
Definition app.dart:31
AuthGuard _()
sealed class CheckInOutEvent extends Equatable userId
bool isLoading
static const red
static const antiFlashWhite
static const darkGreen
static const orange
static ScaffoldFeatureController< SnackBar, SnackBarClosedReason > display(final BuildContext context, final Color color, final String message,)
override State< CollectionRequestPaymentScreen > createState()
const CollectionRequestPaymentScreen({super.key, required this.state})
void _showRatingDialog(String id)
ResCollectionConfirmationEntity collectionConfirmation
final SignatureController _signatureController
Future< void > _handleSignatureComplete(int? contactId, String confirmationId) async
class UpdateCollectionStatusEvent extends CollectionsEvent collectionId
const SendCollectionPaymentEvent({ required this.id, required this.invoiceDateDue, required this.userId, required this.signatureImage, required this.paymentModeId, required this.contactId, })
final String invoiceDateDue
const GetCollectionPaymentModeListEvent({ required this.restaurentId, })
final int restaurantId
class GetCollectionContactListEvent extends CollectionsInformationEvent restaurentId
final String signatureImage
const CollectionPaymentLoaded({required this.isDone})
final Widget child
final EdgeInsets padding
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,),),),],)