6177214e-ce7c-49e3-99de-ff9721b26f63 — Commit 4594f9ed

AuthorEdmir Suljic<esu@dwarf.dk>
Date2025-06-19 13:25:31 +0200
Almost finished with feature. Making a PR for current state of the feature

Changed files

.../components/booking_details_bottom_sheet.dart   | 105 ++++++++++------
 .../lib/common/components/bottom_sheet_widget.dart |  11 +-
 .../pregistration/bloc/preregistration_cubit.dart  |  43 ++++++-
 .../pregistration/bloc/preregistration_state.dart  |  23 +++-
 .../components/prereg_bottom_button.dart           |  54 ++++++++
 .../pregistration/pages/prereg_address_page.dart   |  17 +--
 .../pages/prereg_up_sales_catalog_page.dart        |  84 +++++++++++++
 .../lib/pregistration/preregistration_flow.dart    |  38 +++---
 comwell_key_app/lib/pregistration/utils/utils.dart |  10 ++
 .../components/catalog/other_upgrade_catalog.dart  |   8 +-
 .../components/catalog/room_uprade_catalog.dart    |   8 +-
 .../components/catalog/service_catalog.dart        |  36 ++++--
 .../up_sales/components/comwell_radio_button.dart  |   1 +
 .../components/up_sales_services_widget.dart       | 139 ++++++++++-----------
 .../lib/up_sales/cubit/up_sales_cubit.dart         |   1 +
 comwell_key_app/lib/up_sales/up_sales_catalog.dart |  98 ++-------------
 16 files changed, 426 insertions(+), 250 deletions(-)

Diff

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
index b74f18e3..d39054f2 100644
--- 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
@@ -23,54 +23,79 @@ class BookingDetailsBottomSheet extends StatelessWidget {
final theme = Theme.of(context);
return BottomSheetWidget(
widgetChildren: [
+ const SizedBox(height: 16),
cubit.booking.reservationStatus == ReservationStatus.checkedin
- ? HousekeepingButton(
- key: ValueKey(state.isHouseKeepingOrdered),
- booking: cubit.booking)
+ ? Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16.0),
+ child: HousekeepingButton(
+ key: ValueKey(state.isHouseKeepingOrdered),
+ booking: cubit.booking),
+ )
+ : const SizedBox(),
+ const SizedBox(height: 16),
+ cubit.booking.reservationStatus == ReservationStatus.checkedin
+ ? const Padding(
+ padding: EdgeInsets.symmetric(horizontal: 16.0),
+ child: CheckOutButton(),
+ )
: const SizedBox(),
- const SizedBox(height: 20),
- const CheckOutButton(),
const SizedBox(height: 20),
_buildUpSalesCatalogButton(cubit.booking.reservationStatus, context),
const SizedBox(height: 20),
- Text("booking_details_page_practical_information".tr()),
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: Text("booking_details_page_practical_information".tr(), style: theme.textTheme.headlineMedium),
+ ),
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,
- extra: cubit.booking);
- }),
+ child: Padding(
+ padding: const EdgeInsets.only(left: 16),
+ 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,
+ extra: cubit.booking);
+ }),
+ ),
),
),
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,
- extra: cubit.booking);
- }),
+ child: Padding(
+ padding: const EdgeInsets.only(right: 16),
+ 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,
+ extra: cubit.booking);
+ }),
+ ),
),
),
]),
const SizedBox(height: 16),
- Text('rooms'.tr()),
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: Text('rooms'.tr(), style: theme.textTheme.headlineMedium),
+ ),
const SizedBox(height: 16),
- Text('room_keys'.tr()),
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: Text('room_keys'.tr(), style: theme.textTheme.headlineMedium),
+ ),
const SizedBox(height: 400),
],
);
@@ -80,7 +105,10 @@ class BookingDetailsBottomSheet extends StatelessWidget {
ReservationStatus reservationStatus, BuildContext context) {
switch (reservationStatus) {
case ReservationStatus.checkedin:
- return const UpSalesCatalogButton();
+ return const Padding(
+ padding: EdgeInsets.symmetric(horizontal: 16.0),
+ child: UpSalesCatalogButton(),
+ );
case ReservationStatus.newreservation:
return _buildServices(context);
case ReservationStatus.preregistered:
@@ -102,18 +130,25 @@ class BookingDetailsBottomSheet extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
- Text('services'.tr(), style: theme.textTheme.headlineMedium),
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child:
+ Text('services'.tr(), style: theme.textTheme.headlineMedium),
+ ),
const SizedBox(width: 8),
- OutlinedPillButton(
- text: 'up_sales_see_all'.tr(),
- onTap: () {
- context.pushNamed(AppRoutes.upSalesCatalog.name);
- },
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: OutlinedPillButton(
+ text: 'up_sales_see_all'.tr(),
+ onTap: () {
+ context.pushNamed(AppRoutes.upSalesCatalog.name);
+ },
+ ),
),
],
),
const SizedBox(height: 16),
- ServiceCatalog(upSales: cubit.upSales, height: 252),
+ ServiceCatalog(upSales: cubit.upSales, height: 252, showRadioButton: false),
],
);
}
diff --git a/comwell_key_app/lib/common/components/bottom_sheet_widget.dart b/comwell_key_app/lib/common/components/bottom_sheet_widget.dart
index 9e0eced8..00d0eff8 100644
--- a/comwell_key_app/lib/common/components/bottom_sheet_widget.dart
+++ b/comwell_key_app/lib/common/components/bottom_sheet_widget.dart
@@ -57,13 +57,10 @@ class BottomSheetWidget extends StatelessWidget {
draggable: true,
child: Container(
color: Colors.white,
- child: Padding(
- padding: const EdgeInsets.all(16.0),
- child: SingleChildScrollView(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: widgetChildren)),
- ),
+ child: SingleChildScrollView(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: widgetChildren)),
),
),
);
diff --git a/comwell_key_app/lib/pregistration/bloc/preregistration_cubit.dart b/comwell_key_app/lib/pregistration/bloc/preregistration_cubit.dart
index ad2fbc91..a4631991 100644
--- a/comwell_key_app/lib/pregistration/bloc/preregistration_cubit.dart
+++ b/comwell_key_app/lib/pregistration/bloc/preregistration_cubit.dart
@@ -46,6 +46,18 @@ class PreregistrationCubit extends Cubit<PreregistrationState> {
"Pre-registration - Betalingskort",
"/pre-registration/betalingskort",
);
+
+ addressTextController.addListener(() {
+ emit(state.copyWith(isAddressValid: isAddressValid));
+ });
+
+ postalCodeTextController.addListener(() {
+ emit(state.copyWith(isPostalCodeValid: isPostalCodeValid));
+ });
+
+ cityTextController.addListener(() {
+ emit(state.copyWith(isCityValid: isCityValid));
+ });
}
void init() async {
@@ -105,6 +117,10 @@ class PreregistrationCubit extends Cubit<PreregistrationState> {
_navigateNextPage();
}
+ void onUpSalesContinueClicked() {
+ _navigateNextPage();
+ }
+
void onContinueClicked(BuildContext context) {
if (_isAnimating) return;
switch (currentPage) {
@@ -117,6 +133,9 @@ class PreregistrationCubit extends Cubit<PreregistrationState> {
case PreregistrationPage.payment:
onPaymentContinueClicked();
break;
+ case PreregistrationPage.upSales:
+ onUpSalesContinueClicked();
+ break;
case PreregistrationPage.confirmation:
_onConfirmPressed(context);
break;
@@ -246,11 +265,11 @@ class PreregistrationCubit extends Cubit<PreregistrationState> {
return super.close();
}
- bool get isAddressValid => addressTextController.text.isNotEmpty;
+ bool get isAddressValid => addressTextController.text.length > 0;
- bool get isPostalCodeValid => postalCodeTextController.text.isNotEmpty;
+ bool get isPostalCodeValid => postalCodeTextController.text.length > 0;
- bool get isCityValid => cityTextController.text.isNotEmpty;
+ bool get isCityValid => cityTextController.text.length > 0;
bool get isPhoneNumberValid =>
phoneNumberTextController.text.isNotEmpty &&
@@ -263,14 +282,25 @@ class PreregistrationCubit extends Cubit<PreregistrationState> {
bool get canContinue {
int page = pageController.page?.ceil() ?? 0;
+
final preregPage = PreregistrationPage.fromIndex(page);
+
+ print("isAddressValid: $isAddressValid");
+ print("isPostalCodeValid: $isPostalCodeValid");
+ print("isCityValid: $isCityValid");
+ print("isPhoneNumberValid: $isPhoneNumberValid");
+ print("isFirstNameValid: $isFirstNameValid");
+ print("isLastNameValid: $isLastNameValid");
+ print("state.isTermsAccepted: ${state.isTermsAccepted}");
switch (preregPage) {
case PreregistrationPage.profile:
return isFirstNameValid && isLastNameValid && isPhoneNumberValid;
case PreregistrationPage.address:
- return isAddressValid || isPostalCodeValid || isCityValid;
+ return isAddressValid && isPostalCodeValid && isCityValid;
case PreregistrationPage.payment:
return state.isTermsAccepted;
+ case PreregistrationPage.upSales:
+ return true;
case PreregistrationPage.confirmation:
return true;
}
@@ -286,6 +316,10 @@ class PreregistrationCubit extends Cubit<PreregistrationState> {
return "generic_continue".tr();
case PreregistrationPage.payment:
return "generic_continue".tr();
+ case PreregistrationPage.upSales:
+ return state.selectedUpSales.isEmpty
+ ? "continue_without_up_sales".tr()
+ : "generic_continue".tr();
case PreregistrationPage.confirmation:
return "generic_confirm".tr();
}
@@ -294,5 +328,4 @@ class PreregistrationCubit extends Cubit<PreregistrationState> {
void onTermsAndConditionsToggled(bool toggle) {
emit(state.copyWith(isTermsAccepted: toggle));
}
-
}
diff --git a/comwell_key_app/lib/pregistration/bloc/preregistration_state.dart b/comwell_key_app/lib/pregistration/bloc/preregistration_state.dart
index 22c6972f..52cac5bf 100644
--- a/comwell_key_app/lib/pregistration/bloc/preregistration_state.dart
+++ b/comwell_key_app/lib/pregistration/bloc/preregistration_state.dart
@@ -1,3 +1,4 @@
+import 'package:comwell_key_app/up_sales/models/room_upgrade.dart';
import 'package:country_code_picker/country_code_picker.dart';
import 'package:equatable/equatable.dart';
@@ -18,6 +19,10 @@ class PreregistrationState extends Equatable {
final bool isFirstNameValid;
final bool isLastNameValid;
final bool isTermsAccepted;
+ final bool isAddressValid;
+ final bool isPostalCodeValid;
+ final bool isCityValid;
+ final List<RoomUpgrade> selectedUpSales;
const PreregistrationState({
required this.loading,
@@ -34,6 +39,10 @@ class PreregistrationState extends Equatable {
this.isFirstNameValid = false,
this.isLastNameValid = false,
this.isTermsAccepted = false,
+ this.isAddressValid = false,
+ this.isPostalCodeValid = false,
+ this.isCityValid = false,
+ this.selectedUpSales = const [],
});
@override
@@ -52,6 +61,10 @@ class PreregistrationState extends Equatable {
isFirstNameValid,
isLastNameValid,
isTermsAccepted,
+ isAddressValid,
+ isPostalCodeValid,
+ isCityValid,
+ selectedUpSales,
];
PreregistrationState copyWith({
@@ -69,6 +82,10 @@ class PreregistrationState extends Equatable {
bool? isFirstNameValid,
bool? isLastNameValid,
bool? isTermsAccepted,
+ bool? isAddressValid,
+ bool? isPostalCodeValid,
+ bool? isCityValid,
+ List<RoomUpgrade>? selectedUpSales,
}) {
return PreregistrationState(
forceUpdate: forceUpdate ? !this.forceUpdate : this.forceUpdate,
@@ -85,6 +102,10 @@ class PreregistrationState extends Equatable {
isPhoneNumberValid: isPhoneNumberValid ?? this.isPhoneNumberValid,
isFirstNameValid: isFirstNameValid ?? this.isFirstNameValid,
isLastNameValid: isLastNameValid ?? this.isLastNameValid,
- isTermsAccepted: isTermsAccepted ?? this.isTermsAccepted);
+ isTermsAccepted: isTermsAccepted ?? this.isTermsAccepted,
+ isAddressValid: isAddressValid ?? this.isAddressValid,
+ isPostalCodeValid: isPostalCodeValid ?? this.isPostalCodeValid,
+ isCityValid: isCityValid ?? this.isCityValid,
+ selectedUpSales: selectedUpSales ?? this.selectedUpSales);
}
}
diff --git a/comwell_key_app/lib/pregistration/components/prereg_bottom_button.dart b/comwell_key_app/lib/pregistration/components/prereg_bottom_button.dart
new file mode 100644
index 00000000..935709c6
--- /dev/null
+++ b/comwell_key_app/lib/pregistration/components/prereg_bottom_button.dart
@@ -0,0 +1,54 @@
+import 'package:comwell_key_app/pregistration/bloc/preregistration_cubit.dart';
+import 'package:flutter/material.dart';
+
+class PreregBottomButton extends StatelessWidget {
+ final bool loading;
+ final PreregistrationCubit cubit;
+ final String buttonText;
+ const PreregBottomButton({super.key, required this.loading, required this.cubit, required this.buttonText});
+
+ @override
+ Widget build(BuildContext context) {
+ return Builder(builder: (context) {
+ if (loading) return const SizedBox();
+ return Column(
+ // BOTTOM NAVIGATION
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const Divider(
+ color: Colors.black12,
+ height: 0,
+ ),
+ Row(
+ children: [
+ Expanded(
+ child: Padding(
+ padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 40.0),
+ child: ElevatedButton(
+ onPressed: cubit.canContinue
+ ? () => cubit.onContinueClicked(context)
+ : null,
+ style: ButtonStyle(
+ backgroundColor:
+ WidgetStateProperty.resolveWith((states) {
+ if (states.contains(WidgetState.disabled)) {
+ return Colors.grey;
+ }
+ return const Color(0xffAA8D65);
+ }),
+ foregroundColor:
+ const WidgetStatePropertyAll(Colors.white)),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(vertical: 16.0),
+ child: Text(buttonText),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ],
+ );
+ });
+ }
+}
diff --git a/comwell_key_app/lib/pregistration/pages/prereg_address_page.dart b/comwell_key_app/lib/pregistration/pages/prereg_address_page.dart
index 15614d71..fd0dd5e5 100644
--- a/comwell_key_app/lib/pregistration/pages/prereg_address_page.dart
+++ b/comwell_key_app/lib/pregistration/pages/prereg_address_page.dart
@@ -49,10 +49,7 @@ class PreregAddressPage extends StatelessWidget {
initialValue: "",
readOnly: false,
errorMessage: addressErrorMessage,
- controller: cubit.addressTextController,
- onChanged: (value) {
- cubit.addressTextController.text = value;
- }),
+ controller: cubit.addressTextController),
const SizedBox(height: 12),
ComwellTextField(
fieldName: "preregistration_address_label_postal_code".tr(),
@@ -60,22 +57,14 @@ class PreregAddressPage extends StatelessWidget {
textInputType: TextInputType.number,
errorMessage: postalCodeErrorMessage,
readOnly: false,
- controller: cubit.postalCodeTextController,
- onChanged: (value) {
- cubit.postalCodeTextController.text = value;
-
- }),
+ controller: cubit.postalCodeTextController),
const SizedBox(height: 12),
ComwellTextField(
fieldName: "preregistration_address_label_city".tr(),
initialValue: "",
readOnly: false,
errorMessage: cityErrorMessage,
- controller: cubit.cityTextController,
- onChanged: (value) {
- cubit.cityTextController.text = value;
-
- }),
+ controller: cubit.cityTextController),
const SizedBox(height: 12),
Container(
height: 62,
diff --git a/comwell_key_app/lib/pregistration/pages/prereg_up_sales_catalog_page.dart b/comwell_key_app/lib/pregistration/pages/prereg_up_sales_catalog_page.dart
new file mode 100644
index 00000000..e44dd426
--- /dev/null
+++ b/comwell_key_app/lib/pregistration/pages/prereg_up_sales_catalog_page.dart
@@ -0,0 +1,84 @@
+import 'package:comwell_key_app/up_sales/components/catalog/other_upgrade_catalog.dart';
+import 'package:comwell_key_app/up_sales/components/catalog/room_uprade_catalog.dart';
+import 'package:comwell_key_app/up_sales/components/catalog/service_catalog.dart';
+import 'package:comwell_key_app/up_sales/components/up_sales_bottom_button.dart';
+import 'package:comwell_key_app/up_sales/cubit/up_sales_cubit.dart';
+import 'package:comwell_key_app/up_sales/cubit/up_sales_state.dart';
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+class PreregUpSalesCatalogPage extends StatelessWidget {
+ const PreregUpSalesCatalogPage({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ final theme = Theme.of(context);
+ return BlocBuilder<UpSalesCubit, UpSalesState>(builder: (context, state) {
+ final cubit = context.read<UpSalesCubit>();
+
+ if (state.isLoading) {
+ return const Center(
+ child: CircularProgressIndicator(),
+ );
+ }
+
+ return SingleChildScrollView(
+ child: Padding(
+ padding: const EdgeInsets.only(
+ top: 24,
+ bottom: 100,
+ left: 0,
+ right: 0,
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: Text('up_sales_catalog_title'.tr(),
+ style: theme.textTheme.headlineLarge),
+ ),
+ const SizedBox(height: 40),
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: Text('services'.tr(),
+ style: theme.textTheme.headlineMedium),
+ ),
+ const SizedBox(height: 8),
+ ServiceCatalog(
+ upSales: cubit.upSales,
+ selectedUpSales: cubit.state.selectedUpSales,
+ onTap: (roomUpgrade) {
+ final isSelected =
+ cubit.state.selectedUpSales.contains(roomUpgrade);
+ if (isSelected) {
+ cubit.removeUpgrade(roomUpgrade);
+ } else {
+ cubit.addSelected(roomUpgrade);
+ }
+ }),
+ const SizedBox(height: 24),
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: Text('room_upgrades'.tr(),
+ style: theme.textTheme.headlineMedium),
+ ),
+ const SizedBox(height: 8),
+ RoomUpgradeCatalog(cubit: cubit),
+ const SizedBox(height: 24),
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: Text('other_up_sales'.tr(),
+ style: theme.textTheme.headlineMedium),
+ ),
+ const SizedBox(height: 8),
+ OtherUpgradeCatalog(cubit: cubit),
+ const SizedBox(height: 24),
+ ],
+ ),
+ ),
+ );
+ });
+ }
+}
diff --git a/comwell_key_app/lib/pregistration/preregistration_flow.dart b/comwell_key_app/lib/pregistration/preregistration_flow.dart
index 119985f9..18b082fd 100644
--- a/comwell_key_app/lib/pregistration/preregistration_flow.dart
+++ b/comwell_key_app/lib/pregistration/preregistration_flow.dart
@@ -6,7 +6,6 @@ import 'package:comwell_key_app/pregistration/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
-
class PreregistrationFlow extends StatefulWidget {
final Booking booking;
const PreregistrationFlow({super.key, required this.booking});
@@ -28,6 +27,23 @@ class _PreregistrationFlowState extends State<PreregistrationFlow> {
return Scaffold(
backgroundColor: Colors.white,
appBar: const ComwellAppBar(),
+ body: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 12.0),
+ child: Builder(
+ builder: (context) {
+ if (state.loading) {
+ return const Center(child: CircularProgressIndicator());
+ }
+ return PageView(
+ key: const PageStorageKey("prereg_flow"),
+ physics: const NeverScrollableScrollPhysics(),
+ controller: cubit.pageController,
+ children:
+ PreregistrationPage.getPages(ValueKey(state)).toList(),
+ );
+ },
+ ),
+ ),
bottomNavigationBar: Builder(builder: (context) {
if (state.loading) return const SizedBox();
return Column(
@@ -42,7 +58,8 @@ class _PreregistrationFlowState extends State<PreregistrationFlow> {
children: [
Expanded(
child: Padding(
- padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 40.0),
+ padding:
+ const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 40.0),
child: ElevatedButton(
onPressed: cubit.canContinue
? () => cubit.onContinueClicked(context)
@@ -70,23 +87,6 @@ class _PreregistrationFlowState extends State<PreregistrationFlow> {
],
);
}),
- body: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 12.0),
- child: Builder(
- builder: (context) {
- if (state.loading) {
- return const Center(child: CircularProgressIndicator());
- }
- return PageView(
- key: const PageStorageKey("prereg_flow"),
- physics: const NeverScrollableScrollPhysics(),
- controller: cubit.pageController,
- children:
- PreregistrationPage.getPages(ValueKey(state)).toList(),
- );
- },
- ),
- ),
);
},
),
diff --git a/comwell_key_app/lib/pregistration/utils/utils.dart b/comwell_key_app/lib/pregistration/utils/utils.dart
index 6db9e391..d754af68 100644
--- a/comwell_key_app/lib/pregistration/utils/utils.dart
+++ b/comwell_key_app/lib/pregistration/utils/utils.dart
@@ -3,6 +3,11 @@ import 'package:comwell_key_app/payment_cards/payment_cards_page.dart';
import 'package:comwell_key_app/pregistration/pages/prereg_address_page.dart';
import 'package:comwell_key_app/pregistration/pages/prereg_confirmation_page.dart';
import 'package:comwell_key_app/pregistration/pages/prereg_profile_page.dart';
+import 'package:comwell_key_app/pregistration/pages/prereg_up_sales_catalog_page.dart';
+import 'package:comwell_key_app/up_sales/cubit/up_sales_cubit.dart';
+import 'package:comwell_key_app/up_sales/up_sale_repository.dart';
+import 'package:comwell_key_app/up_sales/up_sales_catalog.dart';
+import 'package:comwell_key_app/utils/locator.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -10,6 +15,7 @@ enum PreregistrationPage {
profile,
address,
payment,
+ upSales,
confirmation;
static PreregistrationPage fromIndex(int index) {
@@ -27,6 +33,10 @@ enum PreregistrationPage {
return BlocProvider(
create: (context) => PaymentCardsCubit(),
child: const PaymentCardsPage());
+ case PreregistrationPage.upSales:
+ return BlocProvider(
+ create: (context) => UpSalesCubit(upSaleRepository: locator<UpSaleRepository>())..init(),
+ child: const PreregUpSalesCatalogPage());
case PreregistrationPage.confirmation:
return PreregConfirmationPage(key: key);
}
diff --git a/comwell_key_app/lib/up_sales/components/catalog/other_upgrade_catalog.dart b/comwell_key_app/lib/up_sales/components/catalog/other_upgrade_catalog.dart
index 71c22968..30c309aa 100644
--- a/comwell_key_app/lib/up_sales/components/catalog/other_upgrade_catalog.dart
+++ b/comwell_key_app/lib/up_sales/components/catalog/other_upgrade_catalog.dart
@@ -1,4 +1,5 @@
import 'package:comwell_key_app/routing/app_routes.dart';
+import 'package:comwell_key_app/themes/light_theme.dart';
import 'package:comwell_key_app/up_sales/components/up_sales_upgrades_widget.dart';
import 'package:comwell_key_app/up_sales/cubit/up_sales_cubit.dart';
import 'package:comwell_key_app/up_sales/models/room_upgrade.dart';
@@ -17,8 +18,11 @@ class OtherUpgradeCatalog extends StatelessWidget {
.toList();
if (otherUpSales.isEmpty) {
- return Text('no_room_upgrades_available'.tr(),
- style: theme.textTheme.headlineMedium);
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: Text('no_room_upgrades_available'.tr(),
+ style: theme.textTheme.headlineMedium?.copyWith(color: colorHeadlineText)),
+ );
}
return SizedBox(
diff --git a/comwell_key_app/lib/up_sales/components/catalog/room_uprade_catalog.dart b/comwell_key_app/lib/up_sales/components/catalog/room_uprade_catalog.dart
index a8f407ff..461b651d 100644
--- a/comwell_key_app/lib/up_sales/components/catalog/room_uprade_catalog.dart
+++ b/comwell_key_app/lib/up_sales/components/catalog/room_uprade_catalog.dart
@@ -1,4 +1,5 @@
import 'package:comwell_key_app/routing/app_routes.dart';
+import 'package:comwell_key_app/themes/light_theme.dart';
import 'package:comwell_key_app/up_sales/components/up_sales_upgrades_widget.dart';
import 'package:comwell_key_app/up_sales/cubit/up_sales_cubit.dart';
import 'package:comwell_key_app/up_sales/models/room_upgrade.dart';
@@ -17,8 +18,11 @@ class RoomUpgradeCatalog extends StatelessWidget {
.toList();
if (roomUpSales.isEmpty) {
- return Text('no_room_upgrades_available'.tr(),
- style: theme.textTheme.headlineMedium);
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: Text('no_room_upgrades_available'.tr(),
+ style: theme.textTheme.headlineMedium?.copyWith(color: colorHeadlineText)),
+ );
}
return SizedBox(
diff --git a/comwell_key_app/lib/up_sales/components/catalog/service_catalog.dart b/comwell_key_app/lib/up_sales/components/catalog/service_catalog.dart
index fe0d3257..7bd4652e 100644
--- a/comwell_key_app/lib/up_sales/components/catalog/service_catalog.dart
+++ b/comwell_key_app/lib/up_sales/components/catalog/service_catalog.dart
@@ -1,3 +1,4 @@
+import 'package:comwell_key_app/themes/light_theme.dart';
import 'package:comwell_key_app/up_sales/components/up_sales_services_widget.dart';
import 'package:comwell_key_app/up_sales/cubit/up_sales_cubit.dart';
import 'package:comwell_key_app/up_sales/models/room_upgrade.dart';
@@ -5,9 +6,18 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
class ServiceCatalog extends StatelessWidget {
- final List<RoomUpgrade> upSales;
- final double? height;
- const ServiceCatalog({super.key, required this.upSales, this.height});
+ final List<RoomUpgrade> upSales;
+ final double? height;
+ final Function(RoomUpgrade)? onTap;
+ final List<RoomUpgrade>? selectedUpSales;
+ final bool showRadioButton;
+ const ServiceCatalog(
+ {super.key,
+ required this.upSales,
+ this.height,
+ this.onTap,
+ this.selectedUpSales,
+ this.showRadioButton = true});
@override
Widget build(BuildContext context) {
@@ -16,9 +26,12 @@ class ServiceCatalog extends StatelessWidget {
.where((roomUpgrade) => roomUpgrade.type == UpgradeType.service)
.toList();
-
if (services.isEmpty) {
- return Text('no_services_available'.tr(), style: theme.textTheme.headlineMedium);
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: Text('no_services_available'.tr(),
+ style: theme.textTheme.headlineMedium?.copyWith(color: colorHeadlineText)),
+ );
}
return SizedBox(
@@ -28,9 +41,18 @@ class ServiceCatalog extends StatelessWidget {
itemCount: services.length,
itemBuilder: (context, index) {
final isPopular = services.elementAt(index).tags.contains('popular');
- return UpSalesServicesWidget(width: 328, roomUpgrade: services.elementAt(index), isPopular: isPopular);
+ return UpSalesServicesWidget(
+ showRadioButton: showRadioButton,
+ width: 328,
+ roomUpgrade: services.elementAt(index),
+ isSelected: selectedUpSales?.map((e) => e.id).toList().contains(services.elementAt(index).id) ?? false,
+ isPopular: isPopular,
+ onTap: (roomUpgrade) {
+ onTap?.call(roomUpgrade);
+ },
+ );
},
),
);
}
-}
\ No newline at end of file
+}
diff --git a/comwell_key_app/lib/up_sales/components/comwell_radio_button.dart b/comwell_key_app/lib/up_sales/components/comwell_radio_button.dart
index fbd99f7c..23f56a9d 100644
--- a/comwell_key_app/lib/up_sales/components/comwell_radio_button.dart
+++ b/comwell_key_app/lib/up_sales/components/comwell_radio_button.dart
@@ -8,6 +8,7 @@ class ComwellRadioButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
+
return InkWell(
onTap: onTap,
child: Container(
diff --git a/comwell_key_app/lib/up_sales/components/up_sales_services_widget.dart b/comwell_key_app/lib/up_sales/components/up_sales_services_widget.dart
index d6140182..72ccac11 100644
--- a/comwell_key_app/lib/up_sales/components/up_sales_services_widget.dart
+++ b/comwell_key_app/lib/up_sales/components/up_sales_services_widget.dart
@@ -1,14 +1,8 @@
-import 'package:comwell_key_app/services/api.dart';
import 'package:comwell_key_app/themes/light_theme.dart';
import 'package:comwell_key_app/up_sales/components/comwell_radio_button.dart';
import 'package:comwell_key_app/up_sales/components/tags.dart';
-import 'package:comwell_key_app/up_sales/cubit/up_sales_cubit.dart';
-import 'package:comwell_key_app/up_sales/cubit/up_sales_state.dart';
import 'package:comwell_key_app/up_sales/models/room_upgrade.dart';
-import 'package:comwell_key_app/up_sales/up_sale_repository.dart';
-import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
class UpSalesServicesWidget extends StatelessWidget {
final double width;
@@ -16,89 +10,90 @@ class UpSalesServicesWidget extends StatelessWidget {
final RoomUpgrade roomUpgrade;
final bool? isSelected;
final bool? isPopular;
+ final Function(RoomUpgrade)? onTap;
+ final bool showRadioButton;
const UpSalesServicesWidget(
{super.key,
this.width = 328,
this.height = 252,
required this.roomUpgrade,
this.isSelected,
- this.isPopular});
+ this.isPopular,
+ this.onTap,
+ this.showRadioButton = true});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
- return Container(
- width: width,
- height: height,
- margin: const EdgeInsets.only(left: 16, right: 0, top: 8, bottom: 8),
- padding: const EdgeInsets.all(12),
- decoration: BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.circular(12),
- border: Border.all(color: colorDivider, width: 1),
- ),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Row(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Expanded(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(roomUpgrade.name,
- style: theme.textTheme.headlineMedium),
- ],
- ),
- ),
- Column(
- crossAxisAlignment: CrossAxisAlignment.end,
+ return Container(
+ width: width,
+ height: height,
+ margin: const EdgeInsets.only(left: 16, right: 0, top: 8, bottom: 8),
+ padding: const EdgeInsets.all(12),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(12),
+ border: Border.all(color: colorDivider, width: 1),
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Row(
- children: [
- Text(
- '${roomUpgrade.price} kr.',
- style: theme.textTheme.headlineMedium,
- ),
- const SizedBox(width: 8),
+ Text(roomUpgrade.name,
+ style: theme.textTheme.headlineMedium),
+ ],
+ ),
+ ),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ Row(
+ children: [
+ Text(
+ '${roomUpgrade.price} kr.',
+ style: theme.textTheme.headlineMedium,
+ ),
+ const SizedBox(width: 8),
+ if (showRadioButton)
ComwellRadioButton(
selected: isSelected ?? false,
onTap: () {
- // if (isSelected) {
- // cubit.removeUpgrade(roomUpgrade);
- // } else {
- // cubit.addSelected(roomUpgrade);
- // }
+ onTap?.call(roomUpgrade);
}),
- ],
- ),
- ],
- ),
- ],
- ),
- Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- if (isPopular!) TagWidget(text: roomUpgrade.tags.first.toUpperCase()),
- const SizedBox(height: 8),
- SizedBox(
- width: 250,
- child: Text(
- roomUpgrade.description,
- style: theme.textTheme.bodySmall?.copyWith(
- color: colorHeadlineText,
- ),
- maxLines: 2,
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ if (isPopular!)
+ TagWidget(text: roomUpgrade.tags.first.toUpperCase()),
+ const SizedBox(height: 8),
+ SizedBox(
+ width: 250,
+ child: Text(
+ roomUpgrade.description,
+ style: theme.textTheme.bodySmall?.copyWith(
+ color: colorHeadlineText,
),
+ maxLines: 2,
),
- ],
- ),
- ],
- ),
- );
-
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
}
}
diff --git a/comwell_key_app/lib/up_sales/cubit/up_sales_cubit.dart b/comwell_key_app/lib/up_sales/cubit/up_sales_cubit.dart
index 637f3e7c..fc73e9e3 100644
--- a/comwell_key_app/lib/up_sales/cubit/up_sales_cubit.dart
+++ b/comwell_key_app/lib/up_sales/cubit/up_sales_cubit.dart
@@ -31,6 +31,7 @@ class UpSalesCubit extends Cubit<UpSalesState> {
error: null));
try {
upSales = await upSaleRepository.getMockUpSales();
+ print("upSales: ${upSales.length}");
emit(state.loaded(upSales: upSales));
} catch (e) {
diff --git a/comwell_key_app/lib/up_sales/up_sales_catalog.dart b/comwell_key_app/lib/up_sales/up_sales_catalog.dart
index b6b28f29..65a7ace7 100644
--- a/comwell_key_app/lib/up_sales/up_sales_catalog.dart
+++ b/comwell_key_app/lib/up_sales/up_sales_catalog.dart
@@ -59,7 +59,18 @@ class UpSalesCatalog extends StatelessWidget {
style: theme.textTheme.headlineMedium),
),
const SizedBox(height: 8),
- ServiceCatalog(upSales: cubit.upSales),
+ ServiceCatalog(
+ upSales: cubit.upSales,
+ selectedUpSales: cubit.state.selectedUpSales,
+ onTap: (roomUpgrade) {
+ final isSelected =
+ cubit.state.selectedUpSales.contains(roomUpgrade);
+ if (isSelected) {
+ cubit.removeUpgrade(roomUpgrade);
+ } else {
+ cubit.addSelected(roomUpgrade);
+ }
+ }),
const SizedBox(height: 24),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
@@ -96,89 +107,4 @@ class UpSalesCatalog extends StatelessWidget {
);
});
}
-
- Widget _buildServicesCatalog(BuildContext context, UpSalesCubit cubit) {
- final theme = Theme.of(context);
- final services = cubit.upSales
- .where((roomUpgrade) => roomUpgrade.type == UpgradeType.service)
- .toList();
-
-
- if (services.isEmpty) {
- return Text('no_services_available'.tr(), style: theme.textTheme.headlineMedium);
- }
-
-
-
- return SizedBox(
- height: 180,
- child: ListView.builder(
- scrollDirection: Axis.horizontal,
- itemCount: services.length,
- itemBuilder: (context, index) {
- final isSelected = cubit.state.selectedUpSales.contains(services.elementAt(index));
- final isPopular = services.elementAt(index).tags.contains('popular');
- return UpSalesServicesWidget(width: 328, roomUpgrade: services.elementAt(index), isSelected: isSelected, isPopular: isPopular);
- },
- ),
- );
- }
-
- Widget _buildRoomUpgradeCatalog(BuildContext context, UpSalesCubit cubit) {
- final theme = Theme.of(context);
- final roomUpSales = cubit.upSales
- .where((roomUpgrade) => roomUpgrade.type == UpgradeType.room)
- .toList();
-
- if (roomUpSales.isEmpty) {
- return Text('no_room_upgrades_available'.tr(), style: theme.textTheme.headlineMedium);
- }
-
- return SizedBox(
- height: 289,
- child: ListView.builder(
- scrollDirection: Axis.horizontal,
- itemCount: roomUpSales.length,
- itemBuilder: (context, index) {
- return UpSalesUpgradesWidget(
- width: 328,
- height: 268,
- roomUpgrade: roomUpSales.elementAt(index),
- isSelected: cubit.state.selected,
- routeName: AppRoutes.roomUpgrade.name,
- showCounter: false,
- );
- },
- ),
- );
- }
-
- Widget _buildOtherUpSalesCatalog(BuildContext context, UpSalesCubit cubit) {
- final theme = Theme.of(context);
- final otherUpSales = cubit.upSales
- .where((roomUpgrade) => roomUpgrade.type == UpgradeType.other)
- .toList();
-
- if (otherUpSales.isEmpty) {
- return Text('no_room_upgrades_available'.tr(), style: theme.textTheme.headlineMedium);
- }
-
- return SizedBox(
- height: 289,
- child: ListView.builder(
- scrollDirection: Axis.horizontal,
- itemCount: otherUpSales.length,
- itemBuilder: (context, index) {
- return UpSalesUpgradesWidget(
- width: 328,
- height: 268,
- roomUpgrade: otherUpSales.elementAt(index),
- isSelected: cubit.state.selected,
- routeName: AppRoutes.otherUpgrade.name,
- showCounter: true,
- );
- },
- ),
- );
- }
}