import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/access_management/bloc/access_event.dart'; import 'package:syncrow_web/pages/access_management/bloc/access_state.dart'; import 'package:syncrow_web/pages/access_management/model/password_model.dart'; import 'package:syncrow_web/services/access_mang_api.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/const.dart'; import 'package:syncrow_web/utils/snack_bar.dart'; class AccessBloc extends Bloc { AccessBloc() : super((AccessInitial())) { on(_onFetchTableData); // on(selectFilterTap); on(selectTime); on(_filterData); on(resetSearch); on(onTabChanged); } String startTime = 'Start Date'; String endTime = 'End Date'; int? effectiveTimeTimeStamp; int? expirationTimeTimeStamp; TextEditingController passwordName = TextEditingController(); List filteredData = []; List data = []; Future _onFetchTableData( FetchTableData event, Emitter emit) async { try { emit(AccessLoaded()); data = await AccessMangApi().fetchVisitorPassword(); filteredData = data; updateTabsCount(); emit(TableLoaded(data)); } catch (e) { emit(FailedState(e.toString())); } } void updateTabsCount() { int toBeEffectiveCount = data .where((item) => item.passwordStatus.value == 'To Be Effective') .length; int effectiveCount = data.where((item) => item.passwordStatus.value == 'Effective').length; int expiredCount = data.where((item) => item.passwordStatus.value == 'Expired').length; tabs[1] = 'To Be Effective ($toBeEffectiveCount)'; tabs[2] = 'Effective ($effectiveCount)'; tabs[3] = 'Expired ($expiredCount)'; } int selectedIndex = 0; final List tabs = [ 'All', 'To Be Effective (0)', 'Effective (0)', 'Expired' ]; Future selectFilterTap( TabChangedEvent event, Emitter emit) async { try { emit(AccessLoaded()); selectedIndex = event.selectedIndex; emit(AccessInitial()); emit(TableLoaded(data)); } catch (e) { emit(FailedState(e.toString())); return; } } Future selectTime(SelectTime event, Emitter emit) async { emit(AccessLoaded()); final DateTime? picked = await showDatePicker( context: event.context, initialDate: DateTime.now(), firstDate: DateTime(2015, 8), lastDate: DateTime(2101), ); if (picked != null) { final TimeOfDay? timePicked = await showTimePicker( context: event.context, initialTime: TimeOfDay.now(), builder: (context, child) { return Theme( data: ThemeData.light().copyWith( colorScheme: const ColorScheme.light( primary: ColorsManager.primaryColor, onSurface: Colors.black, ), buttonTheme: const ButtonThemeData( colorScheme: ColorScheme.light( primary: Colors.green, ), ), ), child: child!, ); }, ); if (timePicked != null) { final selectedDateTime = DateTime( picked.year, picked.month, picked.day, timePicked.hour, timePicked.minute, ); final selectedTimestamp = DateTime( selectedDateTime.year, selectedDateTime.month, selectedDateTime.day, selectedDateTime.hour, selectedDateTime.minute, ).millisecondsSinceEpoch ~/ 1000; // Divide by 1000 to remove milliseconds if (event.isStart) { if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) { CustomSnackBar.displaySnackBar( 'Effective Time cannot be later than Expiration Time.'); } else { startTime = selectedDateTime .toString() .split('.') .first; // Remove seconds and milliseconds effectiveTimeTimeStamp = selectedTimestamp; } } else { if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) { CustomSnackBar.displaySnackBar( 'Expiration Time cannot be earlier than Effective Time.'); } else { endTime = selectedDateTime .toString() .split('.') .first; // Remove seconds and milliseconds expirationTimeTimeStamp = selectedTimestamp; } } } } emit(ChangeTimeState()); } Future _filterData( FilterDataEvent event, Emitter emit) async { emit(AccessLoaded()); try { filteredData = data.where((item) { bool matchesCriteria = true; if (event.passwordName != null && event.passwordName!.isNotEmpty) { final bool matchesName = item.passwordName != null && item.passwordName.contains(event.passwordName); if (!matchesName) { matchesCriteria = false; } } if (event.startTime != null && event.endTime != null) { final int? effectiveTime = int.tryParse(item.effectiveTime.toString()); final int? invalidTime = int.tryParse(item.invalidTime.toString()); if (effectiveTime == null || invalidTime == null) { matchesCriteria = false; } else { final bool matchesStartTime = effectiveTime >= event.startTime!; final bool matchesEndTime = invalidTime <= event.endTime!; if (!matchesStartTime || !matchesEndTime) { matchesCriteria = false; } } } if (event.selectedTabIndex == 1 && item.passwordStatus.value != 'To Be Effective') { matchesCriteria = false; } else if (event.selectedTabIndex == 2 && item.passwordStatus.value != 'Effective') { matchesCriteria = false; } else if (event.selectedTabIndex == 3 && item.passwordStatus.value != 'Expired') { matchesCriteria = false; } return matchesCriteria; }).toList(); emit(TableLoaded(filteredData)); } catch (e) { emit(FailedState(e.toString())); } } resetSearch(ResetSearch event, Emitter emit) async { emit(AccessLoaded()); startTime = 'Start Time'; endTime = 'End Time'; passwordName.clear(); selectedIndex = 0; effectiveTimeTimeStamp = null; expirationTimeTimeStamp = null; add(FetchTableData()); } String timestampToDate(dynamic timestamp) { DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(int.parse(timestamp) * 1000); return "${dateTime.year}/${dateTime.month.toString().padLeft(2, '0')}/${dateTime.day.toString().padLeft(2, '0')}"; } Future onTabChanged( TabChangedEvent event, Emitter emit) async { try { emit(AccessLoaded()); selectedIndex = event.selectedIndex; switch (selectedIndex) { case 0: // All filteredData = data; break; case 1: // To Be Effective filteredData = data .where((item) => item.passwordStatus.value == "To Be Effective") .toList(); break; case 2: // Effective filteredData = data .where((item) => item.passwordStatus.value == "Effective") .toList(); break; case 3: // Expired filteredData = data .where((item) => item.passwordStatus.value == "Expired") .toList(); break; default: filteredData = data; } add(FilterDataEvent( selectedTabIndex: selectedIndex, passwordName: passwordName.text.toLowerCase(), startTime: effectiveTimeTimeStamp, endTime: expirationTimeTimeStamp)); emit(TableLoaded(filteredData)); } catch (e) { emit(FailedState(e.toString())); } } }