6177214e-ce7c-49e3-99de-ff9721b26f63 — Commit f81b19fc
Changed files
.../booking_details/bloc/booking_details_bloc.dart | 41 ++++++++-- .../bloc/booking_details_event.dart | 11 +++ .../bloc/booking_details_state.dart | 9 ++- .../lib/booking_details/booking_details_page.dart | 87 ++-------------------- .../components/booking_details_bottom_sheet.dart | 72 ++++++++++++++++++ .../components/check_in_button_timer.dart | 33 +------- .../components/room_number_container.dart | 34 +++++++++ 7 files changed, 170 insertions(+), 117 deletions(-)
Diff
diff --git a/comwell_key_app/lib/booking_details/bloc/booking_details_bloc.dart b/comwell_key_app/lib/booking_details/bloc/booking_details_bloc.dart
index bea9e3be..441db6a8 100644
--- a/comwell_key_app/lib/booking_details/bloc/booking_details_bloc.dart
+++ b/comwell_key_app/lib/booking_details/bloc/booking_details_bloc.dart
@@ -1,3 +1,5 @@
+import 'dart:async';
+
import 'package:bloc/bloc.dart';
import 'package:comwell_key_app/overview/models/guest.dart';
import 'package:comwell_key_app/profile/profile_repository.dart';
@@ -21,6 +23,10 @@ class BookingDetailsBloc
final BookingDetailsRepository bookingDetailsRepository;
final ProfileRepository profileRepository;
final SeosRepository seosRepository = locator<SeosRepository>();
+ late final Timer timer = Timer.periodic(
+ const Duration(seconds: 1), (_) => add(UpdateRemainingEvent(getCheckInTime().difference(DateTime.now()))));
+ Duration _remainingTime = Duration.zero;
+
BookingDetailsBloc(
this.booking, {
@@ -30,9 +36,10 @@ class BookingDetailsBloc
on<InitialEvent>((event, emit) async {
try {
emit(state.loading());
- await checkIfHouseKeepingOrdered(emit);
- await checkMobileKeys(emit);
- booking = await getBookingDetails(emit);
+ add(CheckIfHouseKeepingOrdered());
+ add(CheckMobileKeys());
+ add(GetBookingDetailsEvent(booking.confirmationId));
+ add(UpdateRemainingEvent(getCheckInTime().difference(DateTime.now())));
} catch (e, st) {
if (kDebugMode) print("err=$e, $st");
@@ -40,6 +47,14 @@ class BookingDetailsBloc
}
});
+ on<UpdateRemainingEvent>((event, emit) async {
+ await updateRemainingTime(emit);
+ });
+
+ on<CheckMobileKeys>((event, emit) async {
+ await checkMobileKeys(emit);
+ });
+
on<CheckIfHouseKeepingOrdered>((event, emit) async {
await checkIfHouseKeepingOrdered(emit);
});
@@ -47,12 +62,17 @@ class BookingDetailsBloc
on<UpdateBookingEvent>((event, emit) async {
await updateBooking(emit, booking, event);
});
+
+ on<GetBookingDetailsEvent>((event, emit) async {
+ await getBookingDetails(emit, event.bookingId);
+ });
}
- Future<Booking> getBookingDetails(Emitter<BookingDetailsState> emit) async {
+ Future<Booking> getBookingDetails(
+ Emitter<BookingDetailsState> emit, String bookingId) async {
try {
final bookingDetails =
- await profileRepository.getBookingDetails(booking.confirmationId);
+ await profileRepository.getBookingDetails(bookingId);
emit(state.copyWith(status: BookingDetailsStatus.main));
return bookingDetails;
} catch (e) {
@@ -95,6 +115,17 @@ class BookingDetailsBloc
}
}
+ Future<void> updateRemainingTime(Emitter<BookingDetailsState> emit) async {
+ final now = DateTime.now();
+ _remainingTime = getCheckInTime().difference(now);
+
+ if (_remainingTime.isNegative) {
+ timer?.cancel();
+ }
+
+ emit(state.updateRemainingTime(_remainingTime));
+ }
+
//TODO add checkin time from backend when we have it
DateTime getCheckInTime() => booking.startDate.add(const Duration(hours: 15));
}
diff --git a/comwell_key_app/lib/booking_details/bloc/booking_details_event.dart b/comwell_key_app/lib/booking_details/bloc/booking_details_event.dart
index ab895b67..f12eec4a 100644
--- a/comwell_key_app/lib/booking_details/bloc/booking_details_event.dart
+++ b/comwell_key_app/lib/booking_details/bloc/booking_details_event.dart
@@ -11,6 +11,17 @@ final class InitialEvent extends BookingDetailsEvent {}
final class CheckIfHouseKeepingOrdered extends BookingDetailsEvent {}
+final class GetBookingDetailsEvent extends BookingDetailsEvent {
+ final String bookingId;
+
+ const GetBookingDetailsEvent(this.bookingId);
+
+ @override
+ List<Object> get props => [bookingId];
+}
+
+final class CheckMobileKeys extends BookingDetailsEvent {}
+
final class UpdateRemainingEvent extends BookingDetailsEvent {
final Duration remaining;
diff --git a/comwell_key_app/lib/booking_details/bloc/booking_details_state.dart b/comwell_key_app/lib/booking_details/bloc/booking_details_state.dart
index 4828f296..367a979b 100644
--- a/comwell_key_app/lib/booking_details/bloc/booking_details_state.dart
+++ b/comwell_key_app/lib/booking_details/bloc/booking_details_state.dart
@@ -6,6 +6,7 @@ class BookingDetailsState extends Equatable {
final MobileKeysKey? key;
final List<MobileKeysKey> keys;
final Iterable<Guest> guests;
+ final Duration remainingTime;
final bool isLoading;
const BookingDetailsState._(
@@ -14,6 +15,7 @@ class BookingDetailsState extends Equatable {
required this.keys,
required this.isHouseKeepingOrdered,
required this.guests,
+ required this.remainingTime,
required this.isLoading});
BookingDetailsState.initial(Booking booking)
@@ -23,6 +25,7 @@ class BookingDetailsState extends Equatable {
keys: [],
isHouseKeepingOrdered: false,
guests: booking.guests,
+ remainingTime: Duration.zero,
isLoading: false);
BookingDetailsState setupError() =>
copyWith(status: BookingDetailsStatus.setupError);
@@ -34,11 +37,11 @@ class BookingDetailsState extends Equatable {
BookingDetailsState updateGuests(Iterable<Guest> guests) =>
copyWith(status: BookingDetailsStatus.guestsUpdated, guests: guests);
BookingDetailsState loading() => copyWith(status: BookingDetailsStatus.loading);
-
+ BookingDetailsState updateRemainingTime(Duration remainingTime) => copyWith(remainingTime: remainingTime);
BookingDetailsState main() => copyWith(status: BookingDetailsStatus.main);
@override
- List<Object?> get props => [status, guests, isLoading];
+ List<Object?> get props => [status, guests, isLoading, remainingTime];
BookingDetailsState copyWith({
BookingDetailsStatus? status,
@@ -47,6 +50,7 @@ class BookingDetailsState extends Equatable {
bool? isHouseKeepingOrdered,
Iterable<Guest>? guests,
bool? isLoading,
+ Duration? remainingTime,
}) {
return BookingDetailsState._(
status: status ?? this.status,
@@ -56,6 +60,7 @@ class BookingDetailsState extends Equatable {
isHouseKeepingOrdered ?? this.isHouseKeepingOrdered,
guests: guests ?? this.guests,
isLoading: isLoading ?? this.isLoading,
+ remainingTime: remainingTime ?? this.remainingTime,
);
}
diff --git a/comwell_key_app/lib/booking_details/booking_details_page.dart b/comwell_key_app/lib/booking_details/booking_details_page.dart
index 8b475d98..d621a440 100644
--- a/comwell_key_app/lib/booking_details/booking_details_page.dart
+++ b/comwell_key_app/lib/booking_details/booking_details_page.dart
@@ -1,5 +1,7 @@
+import 'package:comwell_key_app/booking_details/components/booking_details_bottom_sheet.dart';
import 'package:comwell_key_app/booking_details/components/check_in_button_timer.dart';
import 'package:comwell_key_app/booking_details/components/preregister_button.dart';
+import 'package:comwell_key_app/booking_details/components/room_number_container.dart';
import 'package:comwell_key_app/booking_details/components/share_button.dart';
import 'package:comwell_key_app/common/components/bottom_sheet_widget.dart';
import 'package:comwell_key_app/common/components/comwell_app_bar.dart';
@@ -29,6 +31,7 @@ class BookingDetailsPage extends StatelessWidget {
if (state.status == BookingDetailsStatus.initial) {
cubit.add(InitialEvent());
+ cubit.add(GetBookingDetailsEvent(cubit.booking.confirmationId));
}
return Scaffold(
@@ -87,8 +90,8 @@ class BookingDetailsPage extends StatelessWidget {
children: [
const Spacer(),
if (cubit.booking.roomNumber != '')
- _buildRoomNumberContainer(context, theme, cubit),
- _buildBookingDetails(context, state, cubit, theme),
+ RoomNumberContainer(cubit: cubit),
+ _buildBookingDetailsInformation(context, state, cubit, theme),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Divider(color: Colors.grey[400]),
@@ -107,90 +110,14 @@ class BookingDetailsPage extends StatelessWidget {
),
],
),
- BottomSheetWidget(
- widgetChildren: [
- cubit.booking.roomNumber != ''
- ? HousekeepingButton(
- key: ValueKey(state.isHouseKeepingOrdered),
- roomNumber: cubit.booking.roomNumber)
- : const SizedBox(),
- const SizedBox(height: 20),
- const CheckOutButton(),
- const SizedBox(height: 20),
- Text("booking_details_page_practical_information".tr()),
- const SizedBox(height: 20),
- Row(children: [
- Expanded(
- child: AspectRatio(
- aspectRatio: 175 / 220,
- child: PracticalInformationButton(
- iconPath: "assets/icons/ic_bed.svg",
- title:
- "booking_details_page_hotel_information_button_title"
- .tr(),
- subtitle:
- "booking_details_page_hotel_information_button_subtitle"
- .tr(),
- onClick: () {
- context.pushNamed(AppRoutes.hotelInformation.name);
- }),
- ),
- ),
- const SizedBox(width: 8),
- Expanded(
- child: AspectRatio(
- aspectRatio: 175 / 220,
- child: PracticalInformationButton(
- iconPath: "assets/icons/ic_telephone.svg",
- title:
- "booking_details_page_contact_button_title".tr(),
- subtitle:
- "booking_details_page_contact_button_subtitle"
- .tr(),
- onClick: () {
- context.pushNamed(AppRoutes.contact.name);
- }),
- ),
- ),
- ]),
- const SizedBox(height: 16),
- Text('rooms'.tr()),
- const SizedBox(height: 16),
- Text('room_keys'.tr()),
- const SizedBox(height: 400),
- ],
- )
+ BookingDetailsBottomSheet(cubit: cubit, state: state),
],
)
],
);
}
- Widget _buildRoomNumberContainer(
- BuildContext context, ThemeData theme, BookingDetailsBloc cubit) {
- return Align(
- alignment: Alignment.topLeft,
- child: Padding(
- padding: const EdgeInsets.all(8.0),
- child: Container(
- padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(32),
- border: Border.all(color: Colors.white, width: 2),
- ),
- child: Text(
- 'room_prefix'.tr(args: [cubit.booking.roomNumber]),
- style: theme.textTheme.titleLarge!.copyWith(
- color: Colors.white,
- fontWeight: FontWeight.bold,
- ),
- ),
- ),
- ),
- );
- }
-
- Widget _buildBookingDetails(BuildContext context, BookingDetailsState state,
+ Widget _buildBookingDetailsInformation(BuildContext context, BookingDetailsState state,
BookingDetailsBloc cubit, ThemeData theme) {
return InkWell(
onTap: () {
diff --git a/comwell_key_app/lib/booking_details/components/booking_details_bottom_sheet.dart b/comwell_key_app/lib/booking_details/components/booking_details_bottom_sheet.dart
new file mode 100644
index 00000000..da655ebc
--- /dev/null
+++ b/comwell_key_app/lib/booking_details/components/booking_details_bottom_sheet.dart
@@ -0,0 +1,72 @@
+import 'package:comwell_key_app/booking_details/bloc/booking_details_bloc.dart';
+import 'package:comwell_key_app/booking_details/components/check_in_button_timer.dart';
+import 'package:comwell_key_app/booking_details/components/check_out_button.dart';
+import 'package:comwell_key_app/booking_details/components/housekeeping_button.dart';
+import 'package:comwell_key_app/booking_details/components/practical_information_button.dart';
+import 'package:comwell_key_app/booking_details/components/preregister_button.dart';
+
+import 'package:comwell_key_app/common/components/bottom_sheet_widget.dart';
+import 'package:comwell_key_app/routing/app_routes.dart';
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
+import 'package:go_router/go_router.dart';
+
+class BookingDetailsBottomSheet extends StatelessWidget {
+ final BookingDetailsBloc cubit;
+ final BookingDetailsState state;
+ const BookingDetailsBottomSheet(
+ {super.key, required this.cubit, required this.state});
+
+ @override
+ Widget build(BuildContext context) {
+ return BottomSheetWidget(
+ widgetChildren: [
+ cubit.booking.roomNumber != ''
+ ? HousekeepingButton(
+ key: ValueKey(state.isHouseKeepingOrdered),
+ roomNumber: cubit.booking.roomNumber)
+ : const SizedBox(),
+ const SizedBox(height: 20),
+ const CheckOutButton(),
+ const SizedBox(height: 20),
+ Text("booking_details_page_practical_information".tr()),
+ const SizedBox(height: 20),
+ Row(children: [
+ Expanded(
+ child: AspectRatio(
+ aspectRatio: 175 / 220,
+ child: PracticalInformationButton(
+ iconPath: "assets/icons/ic_bed.svg",
+ title: "booking_details_page_hotel_information_button_title"
+ .tr(),
+ subtitle:
+ "booking_details_page_hotel_information_button_subtitle"
+ .tr(),
+ onClick: () {
+ context.pushNamed(AppRoutes.hotelInformation.name);
+ }),
+ ),
+ ),
+ const SizedBox(width: 8),
+ Expanded(
+ child: AspectRatio(
+ aspectRatio: 175 / 220,
+ child: PracticalInformationButton(
+ iconPath: "assets/icons/ic_telephone.svg",
+ title: "booking_details_page_contact_button_title".tr(),
+ subtitle: "booking_details_page_contact_button_subtitle".tr(),
+ onClick: () {
+ context.pushNamed(AppRoutes.contact.name);
+ }),
+ ),
+ ),
+ ]),
+ const SizedBox(height: 16),
+ Text('rooms'.tr()),
+ const SizedBox(height: 16),
+ Text('room_keys'.tr()),
+ const SizedBox(height: 400),
+ ],
+ );
+ }
+}
diff --git a/comwell_key_app/lib/booking_details/components/check_in_button_timer.dart b/comwell_key_app/lib/booking_details/components/check_in_button_timer.dart
index 5e57d345..dcc40fc6 100644
--- a/comwell_key_app/lib/booking_details/components/check_in_button_timer.dart
+++ b/comwell_key_app/lib/booking_details/components/check_in_button_timer.dart
@@ -16,37 +16,10 @@ class CheckInButtonTimer extends StatefulWidget {
}
class _CheckInButtonTimerState extends State<CheckInButtonTimer> {
- late Duration _remaining;
- Timer? _timer;
-
- @override
- void initState() {
- super.initState();
- _updateRemaining();
- _timer =
- Timer.periodic(const Duration(seconds: 1), (_) => _updateRemaining());
- }
-
- void _updateRemaining() {
- final now = DateTime.now();
- setState(() {
- _remaining = widget.checkInTime.difference(now);
-
- print("remaining=$_remaining");
- if (_remaining.isNegative) {
- _timer?.cancel();
- }
- });
- }
-
- @override
- void dispose() {
- _timer?.cancel();
- super.dispose();
- }
@override
Widget build(BuildContext context) {
+ final cubit = context.read<BookingDetailsBloc>();
return AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
transitionBuilder: (Widget child, Animation<double> animation) {
@@ -55,7 +28,7 @@ class _CheckInButtonTimerState extends State<CheckInButtonTimer> {
child: child,
);
},
- child: _remaining.isNegative
+ child: cubit.state.remainingTime.isNegative
? const CheckInButton(key: ValueKey('check_in_button'))
: getTimerWidget()
);
@@ -65,7 +38,7 @@ class _CheckInButtonTimerState extends State<CheckInButtonTimer> {
return BlocBuilder<BookingDetailsBloc, BookingDetailsState>(
key: const ValueKey('timer_view'),
builder: (context, state) {
- final (days, hours, minutes, seconds) = getDurationInMinutes(_remaining);
+ final (days, hours, minutes, seconds) = getDurationInMinutes(state.remainingTime);
final dateStr =
DateFormat('d. MMM', 'da').format(widget.checkInTime);
final theme = Theme.of(context);
diff --git a/comwell_key_app/lib/booking_details/components/room_number_container.dart b/comwell_key_app/lib/booking_details/components/room_number_container.dart
new file mode 100644
index 00000000..39413475
--- /dev/null
+++ b/comwell_key_app/lib/booking_details/components/room_number_container.dart
@@ -0,0 +1,34 @@
+import 'package:comwell_key_app/booking_details/bloc/booking_details_bloc.dart';
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
+
+class RoomNumberContainer extends StatelessWidget {
+ final BookingDetailsBloc cubit;
+ const RoomNumberContainer({super.key, required this.cubit});
+
+ @override
+ Widget build(BuildContext context) {
+ final theme = Theme.of(context);
+
+ return Align(
+ alignment: Alignment.topLeft,
+ child: Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Container(
+ padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(32),
+ border: Border.all(color: Colors.white, width: 2),
+ ),
+ child: Text(
+ 'room_prefix'.tr(args: [cubit.booking.roomNumber]),
+ style: theme.textTheme.titleLarge!.copyWith(
+ color: Colors.white,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ ),
+ ),
+ );;
+ }
+}
\ No newline at end of file