From c473325883fe3bc12d17cb30a7f9b1efe0eed519 Mon Sep 17 00:00:00 2001 From: Rafeek-Khoudare Date: Mon, 21 Jul 2025 15:01:38 +0300 Subject: [PATCH] add decorator layer --- .../data/non_bookable_spaces_decorator.dart | 32 ++++++++ .../data/remote_non_bookable_spaces.dart | 73 +++++++++---------- .../screens/setup_bookable_spaces_dialog.dart | 5 +- 3 files changed, 69 insertions(+), 41 deletions(-) create mode 100644 lib/pages/access_management/manage_bookable_spaces/data/non_bookable_spaces_decorator.dart diff --git a/lib/pages/access_management/manage_bookable_spaces/data/non_bookable_spaces_decorator.dart b/lib/pages/access_management/manage_bookable_spaces/data/non_bookable_spaces_decorator.dart new file mode 100644 index 00000000..af24439f --- /dev/null +++ b/lib/pages/access_management/manage_bookable_spaces/data/non_bookable_spaces_decorator.dart @@ -0,0 +1,32 @@ +import 'dart:async'; + +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/service/non_bookable_spaces_service.dart'; +import 'package:syncrow_web/pages/space_management_v2/main_module/shared/models/paginated_data_model.dart'; + +class NonBookableSpacesDebouncerDecoratorService + implements NonBookableSpacesService { + final NonBookableSpacesService _delegate; + Timer? _debounce; + + NonBookableSpacesDebouncerDecoratorService(this._delegate); + + @override + Future> load( + NonBookableSpacesParams params) { + final completer = Completer>(); + + _debounce?.cancel(); + _debounce = Timer(const Duration(milliseconds: 500), () async { + try { + final result = await _delegate.load(params); + completer.complete(result); + } catch (e) { + completer.completeError(e); + } + }); + + return completer.future; + } +} diff --git a/lib/pages/access_management/manage_bookable_spaces/data/remote_non_bookable_spaces.dart b/lib/pages/access_management/manage_bookable_spaces/data/remote_non_bookable_spaces.dart index 47d08963..1db35a8e 100644 --- a/lib/pages/access_management/manage_bookable_spaces/data/remote_non_bookable_spaces.dart +++ b/lib/pages/access_management/manage_bookable_spaces/data/remote_non_bookable_spaces.dart @@ -10,51 +10,44 @@ import 'package:syncrow_web/services/api/http_service.dart'; import 'package:syncrow_web/utils/constants/api_const.dart'; class RemoteNonBookableSpaces implements NonBookableSpacesService { - Timer? _debounce; - final HTTPService _httpService; + RemoteNonBookableSpaces(this._httpService); + static const _defaultErrorMessage = 'Failed to load Spaces'; @override Future> load( - NonBookableSpacesParams params) { - final completer = Completer>(); - - _debounce?.cancel(); - _debounce = Timer(const Duration(milliseconds: 500), () async { - try { - final response = await _httpService.get( - path: ApiEndpoints.bookableSpaces, - queryParameters: { - 'configured': false, - 'page': params.currentPage, - 'search': params.searchedWords, - }, - expectedResponseModel: (json) { - final result = json as Map; - return PaginatedDataModel.fromJson( - result, - BookableSpacemodel.fromJsonList, - ); - }, - ); - completer.complete(response); - } on DioException catch (e) { - final message = e.response?.data as Map?; - final error = message?['error'] as Map?; - final errorMessage = error?['error'] as String? ?? ''; - final formattedErrorMessage = [ - _defaultErrorMessage, - errorMessage, - ].join(': '); - completer.completeError(APIException(formattedErrorMessage)); - } catch (e) { - final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); - completer.completeError(APIException(formattedErrorMessage)); - } - }); - - return completer.future; + NonBookableSpacesParams params) async { + try { + final response = await _httpService.get( + path: ApiEndpoints.bookableSpaces, + queryParameters: { + 'configured': false, + 'page': params.currentPage, + 'search': params.searchedWords, + }, + expectedResponseModel: (json) { + final result = json as Map; + return PaginatedDataModel.fromJson( + result, + BookableSpacemodel.fromJsonList, + ); + }, + ); + return response; + } on DioException catch (e) { + final message = e.response?.data as Map?; + final error = message?['error'] as Map?; + final errorMessage = error?['error'] as String? ?? ''; + final formattedErrorMessage = [ + _defaultErrorMessage, + errorMessage, + ].join(': '); + throw APIException(formattedErrorMessage); + } catch (e) { + final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); + throw APIException(formattedErrorMessage); + } } } diff --git a/lib/pages/access_management/manage_bookable_spaces/presentation/screens/setup_bookable_spaces_dialog.dart b/lib/pages/access_management/manage_bookable_spaces/presentation/screens/setup_bookable_spaces_dialog.dart index 77d07e52..a0e8da84 100644 --- a/lib/pages/access_management/manage_bookable_spaces/presentation/screens/setup_bookable_spaces_dialog.dart +++ b/lib/pages/access_management/manage_bookable_spaces/presentation/screens/setup_bookable_spaces_dialog.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/data/non_bookable_spaces_decorator.dart'; import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/data/remote_non_bookable_spaces.dart'; import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/data/remote_send_bookable_spaces.dart'; import 'package:syncrow_web/pages/access_management/manage_bookable_spaces/domain/models/bookable_space_model.dart'; @@ -46,7 +47,9 @@ class _SetupBookableSpacesDialogState extends State { ), BlocProvider( create: (context) => NonBookableSpacesBloc( - RemoteNonBookableSpaces(HTTPService()), + NonBookableSpacesDebouncerDecoratorService( + RemoteNonBookableSpaces(HTTPService()), + ), )..add( LoadUnBookableSpacesEvent( nonBookableSpacesParams: