break down nonBokable Bloc into two blocs

This commit is contained in:
Rafeek-Khoudare
2025-07-17 14:50:29 +03:00
parent 9d130139f7
commit 0e4d37ccac
10 changed files with 254 additions and 158 deletions

View File

@ -1,9 +1,7 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_model.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/params/non_bookable_spaces_params.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/params/send_bookable_spaces_to_api_params.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/service/non_bookable_spaces_service.dart';
import 'package:syncrow_web/pages/space_management_v2/main_module/shared/models/paginated_data_model.dart';
@ -13,24 +11,13 @@ part 'non_bookaable_spaces_state.dart';
class NonBookableSpacesBloc
extends Bloc<NonBookableSpacesEvent, NonBookableSpacesState> {
NonBookableSpacesService nonBookableSpacesService;
List<BookableSpacemodel> selectedBookableSpaces = [];
NonBookableSpacesBloc(this.nonBookableSpacesService)
: super(NonBookableSpacesInitial()) {
on<CallInitStateEvent>(_onCallInitStateEvent);
on<LoadUnBookableSpacesEvent>(_onLoadUnBookableSpacesEvent);
on<AddToBookableSpaceEvent>(_onAddToBookableSpaceEvent);
on<RemoveFromBookableSpaceEvent>(_onRemoveFromBookableSpaceEvent);
on<SendBookableSpacesToApi>(_onSendBookableSpacesToApi);
on<CheckConfigurValidityEvent>(_onCheckConfigurValidityEvent);
on<EditModeSelected>(_onEditModeSelected);
}
TimeOfDay? get endTime =>
selectedBookableSpaces.first.spaceConfig!.bookingEndTime;
TimeOfDay? get startTime =>
selectedBookableSpaces.first.spaceConfig!.bookingStartTime;
void _onCallInitStateEvent(
CallInitStateEvent event, Emitter<NonBookableSpacesState> emit) {
emit(NonBookableSpacesInitial());
@ -75,76 +62,4 @@ class NonBookableSpacesBloc
}
}
}
void _onAddToBookableSpaceEvent(
AddToBookableSpaceEvent event,
Emitter<NonBookableSpacesState> emit,
) {
if (state is NonBookableSpacesLoaded) {
final currentState = state as NonBookableSpacesLoaded;
emit(AddNonBookableSpaceIntoBookableState());
final updatedSelectedSpaces =
List<BookableSpacemodel>.from(currentState.selectedBookableSpaces)
..add(event.nonBookableSpace);
selectedBookableSpaces.add(event.nonBookableSpace);
emit(
NonBookableSpacesLoaded(
nonBookableSpaces: currentState.nonBookableSpaces,
selectedBookableSpaces: updatedSelectedSpaces,
),
);
}
}
void _onRemoveFromBookableSpaceEvent(RemoveFromBookableSpaceEvent event,
Emitter<NonBookableSpacesState> emit) {
if (state is NonBookableSpacesLoaded) {
final currentState = state as NonBookableSpacesLoaded;
emit(RemoveBookableSpaceIntoNonBookableState());
if (currentState.selectedBookableSpaces.isNotEmpty) {
currentState.selectedBookableSpaces.remove(event.bookableSpace);
}
selectedBookableSpaces.remove(event.bookableSpace);
emit(
NonBookableSpacesLoaded(
nonBookableSpaces: currentState.nonBookableSpaces,
selectedBookableSpaces: currentState.selectedBookableSpaces,
),
);
}
}
Future<void> _onSendBookableSpacesToApi(SendBookableSpacesToApi event,
Emitter<NonBookableSpacesState> emit) async {
emit(const NonBookableSpacesLoading());
try {
await nonBookableSpacesService.sendBookableSpacesToApi(
SendBookableSpacesToApiParams.fromBookableSpacesModel(
selectedBookableSpaces,
),
);
add(CallInitStateEvent());
} catch (e) {
emit(
NonBookableSpacesError(e.toString()),
);
}
}
void _onCheckConfigurValidityEvent(
CheckConfigurValidityEvent event, Emitter<NonBookableSpacesState> emit) {
if (selectedBookableSpaces.first.spaceConfig!.isValid) {
emit(ValidSaveButtonState());
} else {
emit(UnValidSaveButtonState());
}
}
void _onEditModeSelected(
EditModeSelected event, Emitter<NonBookableSpacesState> emit) {
selectedBookableSpaces.clear();
selectedBookableSpaces.add(event.editingBookableSpace);
}
}

View File

@ -15,28 +15,3 @@ class LoadUnBookableSpacesEvent extends NonBookableSpacesEvent {
required this.nonBookableSpacesParams,
});
}
class AddToBookableSpaceEvent extends NonBookableSpacesEvent {
final BookableSpacemodel nonBookableSpace;
const AddToBookableSpaceEvent({
required this.nonBookableSpace,
});
}
class RemoveFromBookableSpaceEvent extends NonBookableSpacesEvent {
final BookableSpacemodel bookableSpace;
const RemoveFromBookableSpaceEvent({
required this.bookableSpace,
});
}
class SendBookableSpacesToApi extends NonBookableSpacesEvent {}
class CheckConfigurValidityEvent extends NonBookableSpacesEvent {}
class EditModeSelected extends NonBookableSpacesEvent {
final BookableSpacemodel editingBookableSpace;
const EditModeSelected({
required this.editingBookableSpace,
});
}

View File

@ -30,10 +30,3 @@ class NonBookableSpacesError extends NonBookableSpacesState {
const NonBookableSpacesError(this.error);
}
class AddNonBookableSpaceIntoBookableState extends NonBookableSpacesState {}
class RemoveBookableSpaceIntoNonBookableState extends NonBookableSpacesState {}
class ValidSaveButtonState extends NonBookableSpacesState {}
class UnValidSaveButtonState extends NonBookableSpacesState {}

View File

@ -0,0 +1,78 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_model.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/params/send_bookable_spaces_to_api_params.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/service/non_bookable_spaces_service.dart';
part 'setup_bookable_spaces_event.dart';
part 'setup_bookable_spaces_state.dart';
class SetupBookableSpacesBloc
extends Bloc<SetupBookableSpacesEvent, SetupBookableSpacesState> {
NonBookableSpacesService nonBookableSpacesService;
List<BookableSpacemodel> selectedBookableSpaces = [];
SetupBookableSpacesBloc(this.nonBookableSpacesService)
: super(SetupBookableSpacesInitial()) {
on<AddToBookableSpaceEvent>(_onAddToBookableSpaceEvent);
on<RemoveFromBookableSpaceEvent>(_onRemoveFromBookableSpaceEvent);
on<SendBookableSpacesToApi>(_onSendBookableSpacesToApi);
on<CheckConfigurValidityEvent>(_onCheckConfigurValidityEvent);
on<EditModeSelected>(_onEditModeSelected);
}
TimeOfDay? get endTime =>
selectedBookableSpaces.first.spaceConfig!.bookingEndTime;
TimeOfDay? get startTime =>
selectedBookableSpaces.first.spaceConfig!.bookingStartTime;
void _onAddToBookableSpaceEvent(
AddToBookableSpaceEvent event,
Emitter<SetupBookableSpacesState> emit,
) {
emit(InProgressState());
selectedBookableSpaces.add(event.nonBookableSpace);
emit(AddNonBookableSpaceIntoBookableState(
bookableSpaces: selectedBookableSpaces));
}
void _onRemoveFromBookableSpaceEvent(RemoveFromBookableSpaceEvent event,
Emitter<SetupBookableSpacesState> emit) {
emit(InProgressState());
selectedBookableSpaces.remove(event.bookableSpace);
emit(RemoveBookableSpaceIntoNonBookableState(
bookableSpaces: selectedBookableSpaces));
}
Future<void> _onSendBookableSpacesToApi(SendBookableSpacesToApi event,
Emitter<SetupBookableSpacesState> emit) async {
emit(SendBookableSpacesLoading());
try {
await nonBookableSpacesService.sendBookableSpacesToApi(
SendBookableSpacesToApiParams.fromBookableSpacesModel(
selectedBookableSpaces,
),
);
emit(SendBookableSpacesSuccess());
} catch (e) {
emit(
SendBookableSpacesError(e.toString()),
);
}
}
void _onCheckConfigurValidityEvent(CheckConfigurValidityEvent event,
Emitter<SetupBookableSpacesState> emit) {
if (selectedBookableSpaces.first.spaceConfig!.isValid) {
emit(ValidSaveButtonState());
} else {
emit(UnValidSaveButtonState());
}
}
void _onEditModeSelected(
EditModeSelected event, Emitter<SetupBookableSpacesState> emit) {
selectedBookableSpaces.clear();
selectedBookableSpaces.add(event.editingBookableSpace);
}
}

View File

@ -0,0 +1,32 @@
part of 'setup_bookable_spaces_bloc.dart';
sealed class SetupBookableSpacesEvent extends Equatable {
const SetupBookableSpacesEvent();
@override
List<Object> get props => [];
}
class AddToBookableSpaceEvent extends SetupBookableSpacesEvent {
final BookableSpacemodel nonBookableSpace;
const AddToBookableSpaceEvent({
required this.nonBookableSpace,
});
}
class RemoveFromBookableSpaceEvent extends SetupBookableSpacesEvent {
final BookableSpacemodel bookableSpace;
const RemoveFromBookableSpaceEvent({
required this.bookableSpace,
});
}
class SendBookableSpacesToApi extends SetupBookableSpacesEvent {}
class CheckConfigurValidityEvent extends SetupBookableSpacesEvent {}
class EditModeSelected extends SetupBookableSpacesEvent {
final BookableSpacemodel editingBookableSpace;
const EditModeSelected({
required this.editingBookableSpace,
});
}

View File

@ -0,0 +1,39 @@
part of 'setup_bookable_spaces_bloc.dart';
sealed class SetupBookableSpacesState extends Equatable {
const SetupBookableSpacesState();
@override
List<Object> get props => [];
}
final class SetupBookableSpacesInitial extends SetupBookableSpacesState {}
class AddNonBookableSpaceIntoBookableState extends SetupBookableSpacesState {
final List<BookableSpacemodel> bookableSpaces;
const AddNonBookableSpaceIntoBookableState({
required this.bookableSpaces,
});
}
class InProgressState extends SetupBookableSpacesState {}
class RemoveBookableSpaceIntoNonBookableState extends SetupBookableSpacesState {
final List<BookableSpacemodel> bookableSpaces;
const RemoveBookableSpaceIntoNonBookableState({
required this.bookableSpaces,
});
}
class ValidSaveButtonState extends SetupBookableSpacesState {}
class UnValidSaveButtonState extends SetupBookableSpacesState {}
class SendBookableSpacesLoading extends SetupBookableSpacesState {}
class SendBookableSpacesSuccess extends SetupBookableSpacesState {}
class SendBookableSpacesError extends SetupBookableSpacesState {
final String error;
const SendBookableSpacesError(this.error);
}

View File

@ -0,0 +1,18 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
part 'toggle_points_switch_state.dart';
class TogglePointsSwitchCubit extends Cubit<TogglePointsSwitchState> {
TogglePointsSwitchCubit() : super(TogglePointsSwitchInitial());
bool switchValue = true;
void activateSwitch() {
switchValue = true;
emit(ActivatePointsSwitch());
}
void unActivateSwitch() {
switchValue = false;
emit(UnActivatePointsSwitch());
}
}

View File

@ -0,0 +1,14 @@
part of 'toggle_points_switch_cubit.dart';
sealed class TogglePointsSwitchState extends Equatable {
const TogglePointsSwitchState();
@override
List<Object> get props => [];
}
final class TogglePointsSwitchInitial extends TogglePointsSwitchState {}
class ActivatePointsSwitch extends TogglePointsSwitchState {}
class UnActivatePointsSwitch extends TogglePointsSwitchState {}

View File

@ -4,6 +4,7 @@ import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/data/
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_model.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/params/non_bookable_spaces_params.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/blocs/non_bookable_spaces_bloc/non_bookaable_spaces_bloc.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/blocs/setup_bookable_spaces_bloc/setup_bookable_spaces_bloc.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/blocs/steps_cubit/cubit/steps_cubit.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/widgets/details_steps_widget.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/widgets/next_first_step_button.dart';
@ -42,22 +43,25 @@ class _SetupBookableSpacesDialogState extends State<SetupBookableSpacesDialog> {
: (context) => StepsCubit()..editValueInit(),
),
BlocProvider<NonBookableSpacesBloc>(
create: widget.editingBookableSpace == null
? (context) => NonBookableSpacesBloc(
RemoteNonBookableSpaces(HTTPService()),
)..add(
LoadUnBookableSpacesEvent(
nonBookableSpacesParams:
NonBookableSpacesParams(currentPage: 1),
),
)
: (context) => NonBookableSpacesBloc(
RemoteNonBookableSpaces(HTTPService()),
)..add(
EditModeSelected(
editingBookableSpace: widget.editingBookableSpace!),
),
create: (context) => NonBookableSpacesBloc(
RemoteNonBookableSpaces(HTTPService()),
)..add(
LoadUnBookableSpacesEvent(
nonBookableSpacesParams:
NonBookableSpacesParams(currentPage: 1),
),
),
),
BlocProvider<SetupBookableSpacesBloc>(
create: widget.editingBookableSpace == null
? (context) => SetupBookableSpacesBloc(
RemoteNonBookableSpaces(HTTPService()))
: (context) => SetupBookableSpacesBloc(
RemoteNonBookableSpaces(HTTPService()))
..add(EditModeSelected(
editingBookableSpace: widget.editingBookableSpace!,
)),
)
],
child: AlertDialog(
backgroundColor: ColorsManager.whiteColors,
@ -101,8 +105,10 @@ class _SetupBookableSpacesDialogState extends State<SetupBookableSpacesDialog> {
),
Builder(builder: (context) {
final stepsState = context.watch<StepsCubit>().state;
final nonBookableBloc = context.watch<NonBookableSpacesBloc>();
final selectedSpaces = nonBookableBloc.selectedBookableSpaces;
final setupBookableSpacesBloc =
context.watch<SetupBookableSpacesBloc>();
final selectedSpaces =
setupBookableSpacesBloc.selectedBookableSpaces;
return stepsState is StepOneState
? NextFirstStepButton(selectedSpaces: selectedSpaces)
: SaveSecondStepButton(

View File

@ -1,7 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_model.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/blocs/non_bookable_spaces_bloc/non_bookaable_spaces_bloc.dart';
import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/presentation/blocs/setup_bookable_spaces_bloc/setup_bookable_spaces_bloc.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class CheckBoxSpaceWidget extends StatelessWidget {
final BookableSpacemodel nonBookableSpace;
@ -15,33 +16,58 @@ class CheckBoxSpaceWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final isChecked = selectedSpaces.any(
(element) => element.spaceUuid == nonBookableSpace.spaceUuid,
);
return Row(
children: [
Checkbox(
value: isChecked,
onChanged: (value) {
final bloc = context.read<NonBookableSpacesBloc>();
if (value ?? false) {
bloc.add(
AddToBookableSpaceEvent(
nonBookableSpace: nonBookableSpace,
),
);
} else {
bloc.add(
RemoveFromBookableSpaceEvent(
bookableSpace: nonBookableSpace,
),
);
}
BlocBuilder<SetupBookableSpacesBloc, SetupBookableSpacesState>(
builder: (context, state) {
final isChecked = switch (state) {
AddNonBookableSpaceIntoBookableState(
bookableSpaces: final spaces
) =>
spaces.any((s) => s.spaceUuid == nonBookableSpace.spaceUuid),
RemoveBookableSpaceIntoNonBookableState(
bookableSpaces: final spaces
) =>
spaces.any((s) => s.spaceUuid == nonBookableSpace.spaceUuid),
_ => false,
};
return Checkbox(
value: isChecked,
onChanged: (value) {
final bloc = context.read<SetupBookableSpacesBloc>();
if (value ?? false) {
bloc.add(AddToBookableSpaceEvent(
nonBookableSpace: nonBookableSpace));
} else {
bloc.add(RemoveFromBookableSpaceEvent(
bookableSpace: nonBookableSpace));
}
},
);
},
),
const SizedBox(width: 5),
Expanded(child: Text(nonBookableSpace.spaceName)),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
nonBookableSpace.spaceName,
style: const TextStyle(
fontWeight: FontWeight.bold,
color: ColorsManager.textGray,
),
),
Text(
nonBookableSpace.spaceVirtualAddress,
style: const TextStyle(
fontSize: 12,
color: ColorsManager.textGray,
),
),
],
)),
],
);
}