1import 'package:flutter_svg/svg.dart';
2import 'package:flutter/material.dart';
3import 'package:flutter_bloc/flutter_bloc.dart';
4import 'package:go_router/go_router.dart';
5import 'package:shimmer/shimmer.dart';
7import '../../../../../core/common/models/check_in_status_model.dart';
8import '../../../../../core/constants/assets.dart';
9import '../../../../../core/router/routes.dart';
10import '../../../../../core/services/check_in_service.dart';
11import '../../../../../core/ui/theme/color_palette.dart';
12import '../../../../../core/ui/widgets/custom_slider.dart';
13import '../../../../../core/ui/widgets/custom_scaffold.dart';
14import '../../bloc/authentication_bloc/authentication_bloc.dart';
15import '../../../../../features/home/presentation/bloc/home_bloc.dart';
16import '../../../../../features/home/domain/entities/res/res_schedule_status_entity.dart';
25class _CheckInScreenState
extends State<CheckInScreen> {
35 final authState = context.read<AuthenticationBloc>().state;
36 if (authState is AuthenticationInitialState) {
37 context.read<AuthenticationBloc>().add(LoadSessionEvent());
38 }
else if (authState is AuthenticatedState) {
51 userId: authState.session.uid ?? 0,
60 errorMessage =
"Failed to load assigned vehicle: ${e.toString()}";
67 Widget
build(BuildContext context) {
68 return MultiBlocListener(
70 BlocListener<AuthenticationBloc, AuthenticationState>(
71 listenWhen: (previous, current) => current is AuthenticatedState || current is
AuthenticationFailureState || current is AuthenticationInitialState,
72 listener: (context, state) {
73 if (state is AuthenticatedState) {
78 BlocListener<HomeBloc, HomeState>(
79 listener: (context, state) {
82 context.go(
Routes.startLocationChooserScreen.route);
84 context.go(
Routes.homeScreen.route);
86 context.go(
Routes.scheduleConfirmationScreen.route);
88 }
else if (state is ScheduleStatusError) {
89 context.go(
Routes.homeScreen.route);
94 child: CustomScaffold(
96 body: SingleChildScrollView(
98 padding:
const EdgeInsets.symmetric(horizontal: 24.0),
104 mainAxisAlignment: MainAxisAlignment.center,
122 textAlign: TextAlign.center,
127 color: Colors.grey[600],
131 text:
'Thanks for your daily environmental impact',
137 text:
"let's check in and start our day",
145 padding:
const EdgeInsets.symmetric(vertical: 20),
148 CircularProgressIndicator(
156 fontWeight: FontWeight.w500,
157 color: Colors.grey[600],
162 'Please wait while we verify your location',
165 color: Colors.grey[500],
174 text:
"> > CHECK IN",
200 decoration: BoxDecoration(
202 borderRadius: BorderRadius.circular(16),
205 color: Colors.black.withValues(alpha: 0.05),
207 offset:
const Offset(0, 2),
211 padding:
const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
213 crossAxisAlignment: CrossAxisAlignment.start,
220 'Your Assigned Vehicle',
222 color: Colors.grey[600],
224 fontWeight: FontWeight.w500,
235 style:
const TextStyle(
237 fontWeight: FontWeight.w600,
238 color: Color(0xFF1A1A1A),
243 padding:
const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
244 decoration: BoxDecoration(
246 borderRadius: BorderRadius.circular(12),
249 'ID: ${vehicle.vehicleId}',
252 fontWeight: FontWeight.w500,
267 final authState = context.read<AuthenticationBloc>().state;
268 if (authState is! AuthenticatedState) {
282 driverId: authState.session.uid ?? 0,
288 final now = DateTime.now();
289 final dateString =
'${now.day.toString().padLeft(2, '0
')}/${now.month.toString().padLeft(2, '0
')}/${now.year}';
291 driverId: authState.session.uid ?? 0,
296 _showError(
'Failed to check in. Please ensure location services are enabled and try again.');
299 _showError(
'Check-in failed: ${e.toString()}');
314 ScaffoldMessenger.of(context).showSnackBar(
317 backgroundColor: Colors.red,
318 duration:
const Duration(seconds: 3),
324 return Shimmer.fromColors(
325 baseColor: Colors.grey[300]!,
326 highlightColor: Colors.grey[100]!,
329 decoration: BoxDecoration(
331 borderRadius: BorderRadius.circular(16),
339 decoration: BoxDecoration(
341 borderRadius: BorderRadius.circular(16),
344 color: Colors.black.withValues(alpha: 0.05),
346 offset:
const Offset(0, 2),
351 padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
353 crossAxisAlignment: CrossAxisAlignment.start,
357 const Icon(Icons.error_outline,
color: Colors.red, size: 18),
361 'Error loading assigned vehicle',
362 style:
const TextStyle(
364 fontWeight: FontWeight.w500,
366 overflow: TextOverflow.ellipsis,
376 color: Colors.grey[600],
380 overflow: TextOverflow.ellipsis,
385 alignment: Alignment.centerRight,
388 final authState = context.read<AuthenticationBloc>().state;
389 if (authState is AuthenticatedState) {
393 style: TextButton.styleFrom(
395 const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
396 minimumSize: Size.zero,
409 decoration: BoxDecoration(
411 borderRadius: BorderRadius.circular(16),
414 color: Colors.black.withValues(alpha: 0.05),
416 offset:
const Offset(0, 2),
421 padding:
const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
424 Icon(Icons.car_rental,
color: Colors.grey[400]),
428 'No vehicle assigned to you',
430 color: Colors.grey[400],
432 fontWeight: FontWeight.w400,
434 overflow: TextOverflow.ellipsis,
override void initState()
class App extends StatefulWidget build(BuildContext context)
const AuthenticationFailureState({required this.failure})
sealed class CheckInOutEvent extends Equatable userId
void _performCheckIn() async
Future< void > _loadAssignedVehicle(AuthenticatedState authState) async
Widget _buildVehicleDisplay()
Widget _buildAssignedVehicleDisplay(CheckInStatusModel vehicle)
final CheckInService _checkInService
class CheckInScreen extends StatefulWidget assignedVehicle
Widget _buildErrorDisplay(String errorMessage)
Widget _buildNoVehicleDisplay()
Widget _buildLoadingDisplay()
void _showError(String message)
static const String aidraLogo
static const String environmentalEarth
final String immatriculation
static const antiFlashWhite
const LoadScheduleStatusEvent({ required this.driverId, required this.date, })
const ScheduleStatusLoaded({required this.status})
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,),),),],)