diff --git a/assets/icons/Booking.svg b/assets/icons/Booking.svg
new file mode 100644
index 0000000..f68bb61
--- /dev/null
+++ b/assets/icons/Booking.svg
@@ -0,0 +1,12 @@
+
diff --git a/lib/features/auth/model/user_model.dart b/lib/features/auth/model/user_model.dart
index 0f50a8b..c23da27 100644
--- a/lib/features/auth/model/user_model.dart
+++ b/lib/features/auth/model/user_model.dart
@@ -22,7 +22,7 @@ class UserModel {
final DateTime? appAgreementAcceptedAt;
final Role? role;
final Project? project;
-
+ final int? points;
UserModel({
required this.uuid,
required this.email,
@@ -41,6 +41,7 @@ class UserModel {
required this.appAgreementAcceptedAt,
required this.role,
required this.project,
+ this.points,
});
factory UserModel.fromJson(Map json) {
@@ -67,33 +68,36 @@ class UserModel {
role: json['role'] != null ? Role.fromJson(json['role']) : null,
project:
json['project'] != null ? Project.fromJson(json['project']) : null,
+ points: json['points'],
);
}
factory UserModel.fromToken(Token token) {
Map tempJson = Token.decodeToken(token.accessToken);
return UserModel(
- uuid: tempJson['uuid'].toString(),
- email: tempJson['email'],
- lastName: tempJson['lastName'],
- firstName: tempJson['firstName'],
- profilePicture: UserModel.decodeBase64Image(tempJson['profilePicture']),
- phoneNumber: null,
- isEmailVerified: null,
- isAgreementAccepted: null,
- regionUuid: null,
- regionName: tempJson['region']?['regionName'],
- timeZone: tempJson['timezone']?['timeZoneOffset'],
- hasAcceptedWebAgreement: tempJson['hasAcceptedWebAgreement'],
- webAgreementAcceptedAt: tempJson['webAgreementAcceptedAt'] != null
- ? DateTime.parse(tempJson['webAgreementAcceptedAt'])
- : null,
- hasAcceptedAppAgreement: tempJson['hasAcceptedAppAgreement'],
- appAgreementAcceptedAt: tempJson['appAgreementAcceptedAt'] != null
- ? DateTime.parse(tempJson['appAgreementAcceptedAt'])
- : null,
- role: tempJson['role'] != null ? Role.fromJson(tempJson['role']) : null,
- project: null);
+ uuid: tempJson['uuid'].toString(),
+ email: tempJson['email'],
+ lastName: tempJson['lastName'],
+ firstName: tempJson['firstName'],
+ profilePicture: UserModel.decodeBase64Image(tempJson['profilePicture']),
+ phoneNumber: null,
+ isEmailVerified: null,
+ isAgreementAccepted: null,
+ regionUuid: null,
+ regionName: tempJson['region']?['regionName'],
+ timeZone: tempJson['timezone']?['timeZoneOffset'],
+ hasAcceptedWebAgreement: tempJson['hasAcceptedWebAgreement'],
+ webAgreementAcceptedAt: tempJson['webAgreementAcceptedAt'] != null
+ ? DateTime.parse(tempJson['webAgreementAcceptedAt'])
+ : null,
+ hasAcceptedAppAgreement: tempJson['hasAcceptedAppAgreement'],
+ appAgreementAcceptedAt: tempJson['appAgreementAcceptedAt'] != null
+ ? DateTime.parse(tempJson['appAgreementAcceptedAt'])
+ : null,
+ role: tempJson['role'] != null ? Role.fromJson(tempJson['role']) : null,
+ project: null,
+ points: tempJson['points'],
+ );
}
static Uint8List? decodeBase64Image(String? base64String) {
diff --git a/lib/features/booking_system/data/booking_dummy_source.dart b/lib/features/booking_system/data/booking_dummy_source.dart
new file mode 100644
index 0000000..d44e40d
--- /dev/null
+++ b/lib/features/booking_system/data/booking_dummy_source.dart
@@ -0,0 +1,32 @@
+import 'package:syncrow_app/features/booking_system/domain/booking_model.dart';
+import 'package:syncrow_app/features/booking_system/domain/booking_service.dart';
+
+class BookingDummySource implements BookingService {
+ @override
+ Future> get() async {
+ await Future.delayed(Duration(seconds: 2));
+ return [
+ BookingModel(
+ uuid: 'uuid1',
+ roomName: 'roomName1',
+ date: 'wed 28th May 2025',
+ timeSlot: '10:30 AM - 11:30 AM',
+ cost: 4,
+ ),
+ BookingModel(
+ uuid: 'uuid2',
+ roomName: 'roomName2',
+ date: 'wed 28th May 2025',
+ timeSlot: '10:30 AM - 11:30 AM',
+ cost: 6,
+ ),
+ BookingModel(
+ uuid: 'uuid3',
+ roomName: 'roomName3',
+ date: 'thur 2th june 2025',
+ timeSlot: '10:30 AM - 1:30 PM',
+ cost: 10,
+ )
+ ];
+ }
+}
diff --git a/lib/features/booking_system/data/booking_remote_source.dart b/lib/features/booking_system/data/booking_remote_source.dart
new file mode 100644
index 0000000..bb9b2f9
--- /dev/null
+++ b/lib/features/booking_system/data/booking_remote_source.dart
@@ -0,0 +1,35 @@
+import 'package:dio/dio.dart';
+import 'package:syncrow_app/features/booking_system/domain/booking_model.dart';
+import 'package:syncrow_app/features/booking_system/domain/booking_service.dart';
+import 'package:syncrow_app/services/api/api_links_endpoints.dart';
+import 'package:syncrow_app/services/api/http_service.dart';
+
+class BookingRemoteSource implements BookingService {
+ final HTTPService _httpService;
+ BookingRemoteSource(this._httpService);
+
+ @override
+ Future> get() async {
+ try {
+ return _httpService.get(
+ path: ApiEndpoints.upcomingBookings,
+ expectedResponseModel: (json) {
+ return BookingModel.fromJsonList(json['data']);
+ },
+ );
+ } on DioException catch (e) {
+ return [];
+ // 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/features/booking_system/domain/booking_model.dart b/lib/features/booking_system/domain/booking_model.dart
new file mode 100644
index 0000000..83b90e2
--- /dev/null
+++ b/lib/features/booking_system/domain/booking_model.dart
@@ -0,0 +1,39 @@
+class BookingModel {
+ final String uuid, roomName, date, timeSlot;
+ final int cost;
+ BookingModel({
+ required this.uuid,
+ required this.roomName,
+ required this.date,
+ required this.timeSlot,
+ required this.cost,
+ });
+ factory BookingModel.zero() => BookingModel(
+ uuid: '',
+ roomName: '',
+ date: '',
+ timeSlot: '',
+ cost: -1,
+ );
+ factory BookingModel.fromJson(Map json) => BookingModel(
+ uuid: json['uuid'] as String,
+ roomName: json['roomName'] as String,
+ date: json['date'] as String,
+ timeSlot: json['timeSlot'] as String,
+ cost: json['cost'] as int,
+ );
+
+ static List fromJsonList(List jsonList) => jsonList
+ .map(
+ (bookModel) => BookingModel.fromJson(bookModel),
+ )
+ .toList();
+
+ Map toJson() => {
+ 'uuid': uuid,
+ 'roomName': roomName,
+ 'date': date,
+ 'timeSlot': timeSlot,
+ 'cost': cost,
+ };
+}
diff --git a/lib/features/booking_system/domain/booking_service.dart b/lib/features/booking_system/domain/booking_service.dart
new file mode 100644
index 0000000..f015712
--- /dev/null
+++ b/lib/features/booking_system/domain/booking_service.dart
@@ -0,0 +1,5 @@
+import 'package:syncrow_app/features/booking_system/domain/booking_model.dart';
+
+abstract interface class BookingService {
+ Future> get();
+}
diff --git a/lib/features/booking_system/presentation/blocs/past_bookings_bloc/past_bookings_bloc.dart b/lib/features/booking_system/presentation/blocs/past_bookings_bloc/past_bookings_bloc.dart
new file mode 100644
index 0000000..d9718c5
--- /dev/null
+++ b/lib/features/booking_system/presentation/blocs/past_bookings_bloc/past_bookings_bloc.dart
@@ -0,0 +1,32 @@
+import 'package:bloc/bloc.dart';
+import 'package:equatable/equatable.dart';
+
+import '../../../domain/booking_model.dart';
+import '../../../domain/booking_service.dart';
+
+part 'past_bookings_event.dart';
+part 'past_bookings_state.dart';
+
+class PastBookingsBloc extends Bloc {
+ final BookingService _bookingService;
+
+ PastBookingsBloc(this._bookingService) : super(PastBookingsInitial()) {
+ on(_onGetPastBookingsEvent);
+ }
+ Future _onGetPastBookingsEvent(
+ GetPastBookingsEvent event,
+ Emitter emit,
+ ) async {
+ emit(PastBookingLoadingState());
+ try {
+ final pastBookings = await _bookingService.get();
+ emit(
+ PastBookingLoadedState(pastBookings: pastBookings),
+ );
+ } catch (e) {
+ emit(
+ PastBookingErrorState(e.toString()),
+ );
+ }
+ }
+}
diff --git a/lib/features/booking_system/presentation/blocs/past_bookings_bloc/past_bookings_event.dart b/lib/features/booking_system/presentation/blocs/past_bookings_bloc/past_bookings_event.dart
new file mode 100644
index 0000000..70b831d
--- /dev/null
+++ b/lib/features/booking_system/presentation/blocs/past_bookings_bloc/past_bookings_event.dart
@@ -0,0 +1,10 @@
+part of 'past_bookings_bloc.dart';
+
+sealed class PastBookingsEvent extends Equatable {
+ const PastBookingsEvent();
+
+ @override
+ List