6177214e-ce7c-49e3-99de-ff9721b26f63 — Commit 9b895ae5

AuthorEdmir Suljic<esu@dwarf.dk>
Date2025-05-07 13:00:37 +0200
1625: Started on hooking up check in to endpoint

Changed files

.../models/add_card_payment_method.g.dart          |  29 +++
 .../models/add_card_payment_method.g.dart          |  29 ---
 .../lib/check_in/bloc/check_in_cubit.dart          |  12 ++
 comwell_key_app/lib/check_in/check_in_page.dart    |   5 +-
 .../lib/check_out/bloc/check_out_cubit.dart        |   2 +-
 .../payment_cards/bloc/payment_cards_cubit.dart    |   2 +-
 .../lib/payment_cards/components/add_card.dart     |   2 +-
 .../models/add_card_payment_method.dart            |  21 ++
 .../lib/payment_cards/payment_cards_page.dart      | 103 +++++----
 .../pregistration/bloc/preregistration_cubit.dart  | 218 -------------------
 .../pregistration/bloc/preregistration_state.dart  |  60 ------
 .../pregistration/components/card_item.dart        |  66 ------
 .../components/clickable_card_item.dart            |  31 ---
 .../pregistration/components/information_card.dart |  39 ----
 .../models/add_card_payment_method.dart            |  21 --
 .../pages/prereg_confirmation_page.dart            |  92 ---------
 .../pages/prereg_information_page.dart             |  82 --------
 .../pregistration/pregistration_repository.dart    | 121 -----------
 .../pregistration/preregistration_flow.dart        | 127 ------------
 .../pregistration/bloc/preregistration_cubit.dart  | 230 +++++++++++++++++++++
 .../pregistration/bloc/preregistration_state.dart  |  60 ++++++
 .../lib/pregistration/components/card_item.dart    |  66 ++++++
 .../components/clickable_card_item.dart            |  31 +++
 .../pregistration/components/information_card.dart |  39 ++++
 .../pages/prereg_confirmation_page.dart            |  92 +++++++++
 .../pages/prereg_information_page.dart             |  82 ++++++++
 .../pregistration/pregistration_repository.dart    | 131 ++++++++++++
 .../lib/pregistration/preregistration_flow.dart    | 124 +++++++++++
 comwell_key_app/lib/routing/app_router.dart        |   5 +-
 .../lib/routing/go_router_observer.dart            |  21 +-
 comwell_key_app/lib/services/api.dart              |  13 +-
 .../lib/tracking/trackers/firebase_tracker.dart    |   1 +
 comwell_key_app/lib/utils/locator.dart             |   2 +-
 33 files changed, 1001 insertions(+), 958 deletions(-)

Diff

diff --git a/comwell_key_app/lib/.generated/payment_cards/models/add_card_payment_method.g.dart b/comwell_key_app/lib/.generated/payment_cards/models/add_card_payment_method.g.dart
new file mode 100644
index 00000000..0075fefc
--- /dev/null
+++ b/comwell_key_app/lib/.generated/payment_cards/models/add_card_payment_method.g.dart
@@ -0,0 +1,29 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of '../../../payment_cards/models/add_card_payment_method.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+AddCardPaymentMethod _$AddCardPaymentMethodFromJson(Map json) =>
+ AddCardPaymentMethod(
+ brands: (json['brands'] as List<dynamic>)
+ .map((e) => $enumDecode(_$CardTypeEnumMap, e)),
+ name: json['name'] as String,
+ type: json['type'] as String,
+ );
+
+Map<String, dynamic> _$AddCardPaymentMethodToJson(
+ AddCardPaymentMethod instance) =>
+ <String, dynamic>{
+ 'brands': instance.brands.map((e) => _$CardTypeEnumMap[e]!).toList(),
+ 'name': instance.name,
+ 'type': instance.type,
+ };
+
+const _$CardTypeEnumMap = {
+ CardType.visa: 'visa',
+ CardType.mc: 'mc',
+ CardType.amex: 'amex',
+};
diff --git a/comwell_key_app/lib/.generated/payment_cards/pregistration/models/add_card_payment_method.g.dart b/comwell_key_app/lib/.generated/payment_cards/pregistration/models/add_card_payment_method.g.dart
deleted file mode 100644
index f9009f6b..00000000
--- a/comwell_key_app/lib/.generated/payment_cards/pregistration/models/add_card_payment_method.g.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of '../../../../payment_cards/pregistration/models/add_card_payment_method.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-AddCardPaymentMethod _$AddCardPaymentMethodFromJson(Map json) =>
- AddCardPaymentMethod(
- brands: (json['brands'] as List<dynamic>)
- .map((e) => $enumDecode(_$CardTypeEnumMap, e)),
- name: json['name'] as String,
- type: json['type'] as String,
- );
-
-Map<String, dynamic> _$AddCardPaymentMethodToJson(
- AddCardPaymentMethod instance) =>
- <String, dynamic>{
- 'brands': instance.brands.map((e) => _$CardTypeEnumMap[e]!).toList(),
- 'name': instance.name,
- 'type': instance.type,
- };
-
-const _$CardTypeEnumMap = {
- CardType.visa: 'visa',
- CardType.mc: 'mc',
- CardType.amex: 'amex',
-};
diff --git a/comwell_key_app/lib/check_in/bloc/check_in_cubit.dart b/comwell_key_app/lib/check_in/bloc/check_in_cubit.dart
index d4b4a28e..0c2dc92c 100644
--- a/comwell_key_app/lib/check_in/bloc/check_in_cubit.dart
+++ b/comwell_key_app/lib/check_in/bloc/check_in_cubit.dart
@@ -29,6 +29,18 @@ class CheckInCubit extends Cubit<CheckInState> {
}
}
+ Future<void> onDonePressed() async {
+ emit(state.checkInStatusLoading());
+ try {
+ await _checkInRepository.checkIn(booking.confirmationId);
+ // emit(state.checkInStatusDone());
+ } catch (err, st) {
+ if (kDebugMode) print("qqq err=$err, $st");
+ emit(state.checkInStatusError(Exception(err.toString())));
+ }
+ //emit(state.checkInStatusDone());
+ }
+
Future<void> tryGetKeys({int attempt = 0}) async {
try {
await _checkInRepository.getKeys(booking.id);
diff --git a/comwell_key_app/lib/check_in/check_in_page.dart b/comwell_key_app/lib/check_in/check_in_page.dart
index 472bf50f..3681eb5a 100644
--- a/comwell_key_app/lib/check_in/check_in_page.dart
+++ b/comwell_key_app/lib/check_in/check_in_page.dart
@@ -106,7 +106,9 @@ class _CheckInPageState extends State<CheckInPage>
@override
Widget build(BuildContext context) {
final mq = MediaQuery.of(context);
- return BlocConsumer<CheckInCubit, CheckInState>(listener: (context, state) {
+ final cubit = context.read<CheckInCubit>();
+
+ return BlocConsumer<CheckInCubit, CheckInState>(listener: (context, state) {
switch (state.checkInStatus) {
case CheckInStatusInitial _:
playLoading();
@@ -201,6 +203,7 @@ class _CheckInPageState extends State<CheckInPage>
padding: const EdgeInsets.all(16.0),
child: ElevatedButton(
onPressed: () {
+ cubit.onDonePressed();
context.pop();
},
style: const ButtonStyle(
diff --git a/comwell_key_app/lib/check_out/bloc/check_out_cubit.dart b/comwell_key_app/lib/check_out/bloc/check_out_cubit.dart
index 5b66a771..7db31fec 100644
--- a/comwell_key_app/lib/check_out/bloc/check_out_cubit.dart
+++ b/comwell_key_app/lib/check_out/bloc/check_out_cubit.dart
@@ -6,7 +6,7 @@ import 'package:comwell_key_app/check_out/models/checkout_processing_state.dart'
import 'package:comwell_key_app/check_out/models/payment_method.dart';
import 'package:comwell_key_app/check_out/pages/check_out_page.dart';
import 'package:comwell_key_app/overview/models/booking.dart';
-import 'package:comwell_key_app/payment_cards/pregistration/pregistration_repository.dart';
+import 'package:comwell_key_app/pregistration/pregistration_repository.dart';
import 'package:comwell_key_app/profile/profile_repository.dart';
import 'package:comwell_key_app/profile_settings/repostiory/profile_settings_repository.dart';
import 'package:comwell_key_app/services/adyen/adyen_amount.dart';
diff --git a/comwell_key_app/lib/payment_cards/bloc/payment_cards_cubit.dart b/comwell_key_app/lib/payment_cards/bloc/payment_cards_cubit.dart
index c3e85d25..de9c985b 100644
--- a/comwell_key_app/lib/payment_cards/bloc/payment_cards_cubit.dart
+++ b/comwell_key_app/lib/payment_cards/bloc/payment_cards_cubit.dart
@@ -4,7 +4,7 @@ import 'package:comwell_key_app/check_out/models/payment_configurations.dart';
import 'package:comwell_key_app/overview/repository/overview_repository.dart';
import 'package:comwell_key_app/payment_cards/bloc/payment_cards_state.dart';
import 'package:comwell_key_app/payment_cards/payment_cards_repository.dart';
-import 'package:comwell_key_app/payment_cards/pregistration/pregistration_repository.dart';
+import 'package:comwell_key_app/pregistration/pregistration_repository.dart';
import 'package:comwell_key_app/profile/profile_repository.dart';
import 'package:comwell_key_app/services/adyen/payment_event_handler.dart';
import 'package:comwell_key_app/services/api.dart';
diff --git a/comwell_key_app/lib/payment_cards/components/add_card.dart b/comwell_key_app/lib/payment_cards/components/add_card.dart
index 25af292c..2e5326df 100644
--- a/comwell_key_app/lib/payment_cards/components/add_card.dart
+++ b/comwell_key_app/lib/payment_cards/components/add_card.dart
@@ -1,6 +1,6 @@
import 'package:adyen_checkout/adyen_checkout.dart';
import 'package:comwell_key_app/payment_cards/bloc/payment_cards_cubit.dart';
-import 'package:comwell_key_app/payment_cards/pregistration/models/add_card_payment_method.dart';
+import 'package:comwell_key_app/payment_cards/models/add_card_payment_method.dart';
import 'package:comwell_key_app/themes/light_theme.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
diff --git a/comwell_key_app/lib/payment_cards/models/add_card_payment_method.dart b/comwell_key_app/lib/payment_cards/models/add_card_payment_method.dart
new file mode 100644
index 00000000..e4a9fe62
--- /dev/null
+++ b/comwell_key_app/lib/payment_cards/models/add_card_payment_method.dart
@@ -0,0 +1,21 @@
+import 'package:comwell_key_app/utils/json.dart';
+import 'package:json_annotation/json_annotation.dart';
+
+part '../../.generated/payment_cards/models/add_card_payment_method.g.dart';
+
+enum CardType { visa, mc, amex }
+
+@JsonSerializable()
+class AddCardPaymentMethod {
+ final Iterable<CardType> brands;
+ final String name;
+ final String type;
+
+ AddCardPaymentMethod({
+ required this.brands,
+ required this.name,
+ required this.type,
+ });
+
+ Json toJson() => _$AddCardPaymentMethodToJson(this);
+}
diff --git a/comwell_key_app/lib/payment_cards/payment_cards_page.dart b/comwell_key_app/lib/payment_cards/payment_cards_page.dart
index 9fdecec1..d196c90a 100644
--- a/comwell_key_app/lib/payment_cards/payment_cards_page.dart
+++ b/comwell_key_app/lib/payment_cards/payment_cards_page.dart
@@ -3,7 +3,7 @@ import 'package:comwell_key_app/payment_cards/bloc/payment_cards_state.dart';
import 'package:comwell_key_app/payment_cards/components/add_card.dart';
import 'package:comwell_key_app/payment_cards/components/edit_card_dialog.dart';
import 'package:comwell_key_app/payment_cards/components/remove_card_button.dart';
-import 'package:comwell_key_app/payment_cards/pregistration/components/card_item.dart';
+import 'package:comwell_key_app/pregistration/components/card_item.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -20,64 +20,59 @@ class PaymentCardsPage extends StatelessWidget {
builder: (context, state) {
final cubit = context.read<PaymentCardsCubit>();
final cards = cubit.state.cards;
- return Scaffold(
- appBar: const ComwellAppBar(shouldShowProfileButton: false),
- body: Builder(builder: (context) {
- if (cubit.state.isLoading) {
- return const Center(child: CircularProgressIndicator());
- }
- if (cubit.state.hasError) {
- return const Center(child: Text('Error fetching cards'));
- }
- return Center(
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 16.0),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- const SizedBox(height: 40),
- Text(
- "payment_cards_title".tr(),
- style: Theme.of(context).textTheme.headlineLarge,
+ if (cubit.state.isLoading) {
+ return const Center(child: CircularProgressIndicator());
+ }
+ if (cubit.state.hasError) {
+ return const Center(child: Text('Error fetching cards'));
+ }
+ return Center(
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ const SizedBox(height: 40),
+ Text(
+ "payment_cards_title".tr(),
+ style: Theme.of(context).textTheme.headlineLarge,
+ ),
+ const SizedBox(height: 40),
+ Text("payment_cards_my_cards".tr(),
+ style: Theme.of(context).textTheme.headlineMedium),
+ const SizedBox(height: 20),
+ ...cards.map(
+ (card) => Container(
+ decoration: BoxDecoration(
+ border: Border.all(color: colorDivider),
),
- const SizedBox(height: 40),
- Text("payment_cards_my_cards".tr(),
- style: Theme.of(context).textTheme.headlineMedium),
- const SizedBox(height: 20),
- ...cards.map(
- (card) => Container(
- decoration: BoxDecoration(
- border: Border.all(color: colorDivider),
- ),
- padding: const EdgeInsets.all(12),
- child: CardItem(
- paymentMethod: card,
- onClick: () {
- showModalBottomSheet<void>(
- context: context,
- builder: (context) {
- return Padding(
- padding: const EdgeInsets.all(16.0),
- child: EditCardDialog(
- storedPaymentMethod: card,
- onRemoveCard: () {
- cubit.onRemoveCard(card.id);
- },
- ),
- );
- },
+ padding: const EdgeInsets.all(12),
+ child: CardItem(
+ paymentMethod: card,
+ onClick: () {
+ showModalBottomSheet<void>(
+ context: context,
+ builder: (context) {
+ return Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: EditCardDialog(
+ storedPaymentMethod: card,
+ onRemoveCard: () {
+ cubit.onRemoveCard(card.id);
+ },
+ ),
);
},
- ),
- ),
+ );
+ },
),
- const SizedBox(height: 12),
- const AddCard()
- ],
+ ),
),
- ),
- );
- }),
+ const SizedBox(height: 12),
+ const AddCard()
+ ],
+ ),
+ ),
);
});
}
diff --git a/comwell_key_app/lib/payment_cards/pregistration/bloc/preregistration_cubit.dart b/comwell_key_app/lib/payment_cards/pregistration/bloc/preregistration_cubit.dart
deleted file mode 100644
index f8f36d2b..00000000
--- a/comwell_key_app/lib/payment_cards/pregistration/bloc/preregistration_cubit.dart
+++ /dev/null
@@ -1,218 +0,0 @@
-import 'package:adyen_checkout/src/common/model/payment_result.dart';
-import 'package:bloc/bloc.dart';
-import 'package:comwell_key_app/payment_cards/pregistration/bloc/preregistration_state.dart';
-import 'package:comwell_key_app/payment_cards/pregistration/preregistration_flow.dart';
-import 'package:comwell_key_app/profile/profile_repository.dart';
-import 'package:comwell_key_app/profile_settings/repostiory/profile_settings_repository.dart';
-import 'package:comwell_key_app/tracking/comwell_tracking.dart';
-import 'package:comwell_key_app/tracking/models/analytics_event_item.dart';
-import 'package:comwell_key_app/utils/locator.dart';
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/cupertino.dart';
-
-class PreregistrationCubit extends Cubit<PreregistrationState> {
- final _profileRepository = locator<ProfileRepository>();
- final _tracking = locator<ComwellTracking>();
-
- final pageController = PageController();
- final addressTextController = TextEditingController();
- final postalCodeTextController = TextEditingController();
- final cityTextController = TextEditingController();
- final countryTextController = TextEditingController();
-
- PreregistrationPage get currentPage =>
- PreregistrationPage.fromIndex(pageController.page?.toInt() ?? 0);
- bool _isAnimating = false;
-
- PreregistrationCubit() : super(const PreregistrationState(loading: false)) {
- _tracking.trackScreenView(
- "Pre-registration - Betalingskort",
- "/pre-registration/betalingskort",
- );
- }
-
- void init() async {
- emit(state.copyWith(loading: true, error: null));
- try {
- final user = await _profileRepository.fetchProfileSettings();
- if (user != null) {
- addressTextController.text = user.address?.street ?? "";
- postalCodeTextController.text = user.address?.zipCode ?? "";
- cityTextController.text = user.address?.city ?? "";
- countryTextController.text = user.address?.country ?? "";
- } else {
- emit(state.copyWith(
- loading: false, error: Exception("Der skete en fejl")));
- }
- } on Exception catch (e) {
- emit(state.copyWith(error: e));
- }
- }
-
- void onInformationContinueClicked() {
- if (isAddressValid && isPostalCodeValid && isCityValid && isCountryValid) {
- _navigateNextPage();
- } else {
- emit(state.copyWith(missingInformation: true));
- }
- }
-
- void onContinueClicked() {
- if (_isAnimating) return;
- switch (currentPage) {
- case PreregistrationPage.information:
- onInformationContinueClicked();
- break;
- case PreregistrationPage.confirmation:
- _onConfirmPressed();
- break;
- }
- }
-
- void addToCart() {
- final analyticsEventItem = AnalyticsEventItem(
- hotelName: "Comwell",
- currency: "DKK",
- value: 500,
- placement: "placement",
- items: ["items"],
- itemId: "itemId",
- itemName: "itemName",
- price: 200,
- quantity: 200);
- _tracking.trackAddToCart(analyticsEventItem);
- }
-
- void removeToCard() {
- final analyticsEventItem = AnalyticsEventItem(
- hotelName: "Comwell",
- currency: "DKK",
- value: 500,
- placement: "placement",
- items: ["items"],
- itemId: "itemId",
- itemName: "itemName",
- price: 200,
- quantity: 200);
- _tracking.trackRemoveFromCart(analyticsEventItem);
- }
-
- void _onConfirmPressed() async {
- final analyticsEventItem = AnalyticsEventItem(
- hotelName: "Comwell",
- currency: "DKK",
- value: 500,
- placement: "placement",
- items: ["items"],
- itemId: "itemId",
- itemName: "itemName",
- price: 200,
- quantity: 200);
- _tracking.trackBeginCheckout(analyticsEventItem);
- emit(state.copyWith(loading: true));
- Future.delayed(const Duration(seconds: 3), () {
- emit(state.copyWith(loading: false));
- });
- }
-
- void onEditProfileClicked() {
- // Not implemented
- }
-
- void onEditAddressClicked() {
- _navigateTo(PreregistrationPage.information);
- }
-
- void onEditExtrasClicked() {
- // Not implemented
- }
-
- bool onBackClicked() {
- if (_isAnimating) return true;
- final hasPage = pageController.page != null;
- if (hasPage && pageController.page! >= 1.0) {
- _navigatePreviousPage();
- return true;
- }
- return false;
- }
-
- void _navigateTo(PreregistrationPage page) async {
- if (_isAnimating) return;
- _isAnimating = true;
- await pageController.animateToPage(page.index,
- duration: const Duration(milliseconds: 500),
- curve: Curves.fastOutSlowIn);
- emit(state.copyWith(forceUpdate: true));
- _isAnimating = false;
- }
-
- void _navigateNextPage() async {
- if (_isAnimating) return;
- _isAnimating = true;
- await pageController.nextPage(
- duration: const Duration(milliseconds: 500),
- curve: Curves.fastOutSlowIn);
- emit(state.copyWith(forceUpdate: true));
- _isAnimating = false;
- }
-
- void _navigatePreviousPage() async {
- if (_isAnimating) return;
- _isAnimating = true;
- await pageController.previousPage(
- duration: const Duration(milliseconds: 500),
- curve: Curves.fastOutSlowIn);
- emit(state.copyWith(forceUpdate: true));
- _isAnimating = false;
- }
-
- @override
- Future<void> close() {
- addressTextController.dispose();
- postalCodeTextController.dispose();
- cityTextController.dispose();
- countryTextController.dispose();
- pageController.dispose();
- return super.close();
- }
-
- bool get isAddressValid => addressTextController.text.isNotEmpty;
-
- bool get isPostalCodeValid =>
- postalCodeTextController.text.isNotEmpty &&
- postalCodeTextController.text.length <= 4;
-
- bool get isCityValid => cityTextController.text.isNotEmpty;
-
- bool get isCountryValid => countryTextController.text.isNotEmpty;
-
- bool get canContinue {
- int page = pageController.page?.ceil() ?? 0;
- final preregPage = PreregistrationPage.fromIndex(page);
- switch (preregPage) {
- case PreregistrationPage.information:
- return isAddressValid &&
- isPostalCodeValid &&
- isCityValid &&
- isCityValid;
- case PreregistrationPage.confirmation:
- return true;
- }
- }
-
- String get buttonText {
- int page = pageController.page?.ceil() ?? 0;
- final preregPage = PreregistrationPage.fromIndex(page);
- switch (preregPage) {
- case PreregistrationPage.information:
- return "generic_continue".tr();
- case PreregistrationPage.confirmation:
- return "generic_confirm".tr();
- }
- }
-
- void onTermsAndConditionsToggled(bool toggle) {
- emit(state.copyWith(termsAndConditionsAccepted: toggle));
- }
-}
diff --git a/comwell_key_app/lib/payment_cards/pregistration/bloc/preregistration_state.dart b/comwell_key_app/lib/payment_cards/pregistration/bloc/preregistration_state.dart
deleted file mode 100644
index a07663b4..00000000
--- a/comwell_key_app/lib/payment_cards/pregistration/bloc/preregistration_state.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-import 'package:equatable/equatable.dart';
-
-import '../../../profile_settings/model/user.dart';
-
-class PreregistrationState extends Equatable {
- final bool forceUpdate;
- final bool loading;
- final User? user;
- final Exception? error;
- final bool missingInformation;
- final int numOfExtras;
- final int extrasTotalPrice;
- final bool termsAndConditionsAccepted;
-
- const PreregistrationState({
- required this.loading,
- this.missingInformation = false,
- this.numOfExtras = 0,
- this.extrasTotalPrice = 0,
- this.termsAndConditionsAccepted = false,
- this.forceUpdate = false,
- this.user,
- this.error,
- });
-
- @override
- List<Object?> get props => [
- loading,
- user,
- error,
- missingInformation,
- numOfExtras,
- extrasTotalPrice,
- termsAndConditionsAccepted,
- forceUpdate,
- ];
-
- PreregistrationState copyWith({
- bool? loading,
- User? user,
- Exception? error,
- bool? missingInformation,
- int? numOfExtras,
- int? extrasTotalPrice,
- String? buttonTextStringId,
- bool? termsAndConditionsAccepted,
- bool forceUpdate = false,
- }) {
- return PreregistrationState(
- forceUpdate: forceUpdate ? !this.forceUpdate : this.forceUpdate,
- loading: loading ?? this.loading,
- missingInformation: missingInformation ?? this.missingInformation,
- user: user ?? this.user,
- numOfExtras: numOfExtras ?? this.numOfExtras,
- termsAndConditionsAccepted:
- termsAndConditionsAccepted ?? this.termsAndConditionsAccepted,
- extrasTotalPrice: extrasTotalPrice ?? this.extrasTotalPrice,
- error: error);
- }
-}
diff --git a/comwell_key_app/lib/payment_cards/pregistration/components/card_item.dart b/comwell_key_app/lib/payment_cards/pregistration/components/card_item.dart
deleted file mode 100644
index 1e45fa8f..00000000
--- a/comwell_key_app/lib/payment_cards/pregistration/components/card_item.dart
+++ /dev/null
@@ -1,66 +0,0 @@
-import 'package:comwell_key_app/common/components/payment_card_image.dart';
-import 'package:comwell_key_app/overview/models/payment_details.dart';
-import 'package:comwell_key_app/services/adyen/stored_payment_method.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_svg/flutter_svg.dart';
-
-class CardItem extends StatelessWidget {
- final StoredPaymentMethod paymentMethod;
- final bool isSelected;
- final VoidCallback? onClick;
-
- const CardItem({
- super.key,
- required this.paymentMethod,
- this.onClick,
- this.isSelected = false,
- });
-
- @override
- Widget build(BuildContext context) {
- return InkWell(
- onTap: onClick,
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- PaymentCardImage(cardType: CardType.fromString(paymentMethod.brand)),
- const SizedBox(width: 12),
- Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- paymentMethod.holderName,
- style: Theme.of(context).textTheme.bodySmall,
- ),
- Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- ..."**** **** **** ".characters.map((char) {
- if (char == '*') {
- return Padding(
- padding: const EdgeInsets.symmetric(horizontal: 1.0),
- child: Container(
- width: 5,
- height: 5,
- decoration: const BoxDecoration(
- shape: BoxShape.circle, color: Colors.black),
- ),
- );
- }
- return const SizedBox(width: 8);
- }),
- Text(
- paymentMethod.lastFour,
- style: Theme.of(context).textTheme.bodyMedium,
- )
- ],
- ),
- ],
- ),
- const Expanded(child: SizedBox()),
- if (isSelected) SvgPicture.asset("assets/icons/ic_checkmark.svg")
- ],
- ),
- );
- }
-}
diff --git a/comwell_key_app/lib/payment_cards/pregistration/components/clickable_card_item.dart b/comwell_key_app/lib/payment_cards/pregistration/components/clickable_card_item.dart
deleted file mode 100644
index 4c148ccc..00000000
--- a/comwell_key_app/lib/payment_cards/pregistration/components/clickable_card_item.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-import 'package:comwell_key_app/payment_cards/pregistration/components/card_item.dart';
-import 'package:comwell_key_app/services/adyen/stored_payment_method.dart';
-import 'package:comwell_key_app/themes/light_theme.dart';
-import 'package:flutter/material.dart';
-
-class ClickableCardItem extends StatelessWidget {
- final StoredPaymentMethod paymentMethod;
- final VoidCallback onClick;
- final bool isSelected;
-
- const ClickableCardItem({
- super.key,
- required this.paymentMethod,
- required this.onClick,
- this.isSelected = false,
- });
-
- @override
- Widget build(BuildContext context) {
- return InkWell(
- onTap: onClick,
- child: Container(
- decoration: BoxDecoration(
- border: Border.all(color: colorDivider),
- ),
- padding: const EdgeInsets.all(12),
- child: CardItem(paymentMethod: paymentMethod, isSelected: isSelected),
- ),
- );
- }
-}
diff --git a/comwell_key_app/lib/payment_cards/pregistration/components/information_card.dart b/comwell_key_app/lib/payment_cards/pregistration/components/information_card.dart
deleted file mode 100644
index 3cfbde80..00000000
--- a/comwell_key_app/lib/payment_cards/pregistration/components/information_card.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-import 'package:comwell_key_app/themes/dark_theme.dart';
-import 'package:flutter/material.dart';
-
-class InformationCard extends StatelessWidget {
- final String title;
- final VoidCallback onEditClick;
- final Widget child;
-
- const InformationCard({
- super.key,
- required this.title,
- required this.onEditClick,
- required this.child,
- });
-
- @override
- Widget build(BuildContext context) {
- return Container(
- padding: const EdgeInsets.all(12),
- decoration: BoxDecoration(
- color: sandColor[20],
- borderRadius: const BorderRadius.all(Radius.circular(10))),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(title),
- TextButton(onPressed: onEditClick, child: const Text("Rediger"))
- ],
- ),
- const SizedBox(height: 40),
- child
- ],
- ),
- );
- }
-}
diff --git a/comwell_key_app/lib/payment_cards/pregistration/models/add_card_payment_method.dart b/comwell_key_app/lib/payment_cards/pregistration/models/add_card_payment_method.dart
deleted file mode 100644
index 504f5c6d..00000000
--- a/comwell_key_app/lib/payment_cards/pregistration/models/add_card_payment_method.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-import 'package:comwell_key_app/utils/json.dart';
-import 'package:json_annotation/json_annotation.dart';
-
-part '../../../.generated/payment_cards/pregistration/models/add_card_payment_method.g.dart';
-
-enum CardType { visa, mc, amex }
-
-@JsonSerializable()
-class AddCardPaymentMethod {
- final Iterable<CardType> brands;
- final String name;
- final String type;
-
- AddCardPaymentMethod({
- required this.brands,
- required this.name,
- required this.type,
- });
-
- Json toJson() => _$AddCardPaymentMethodToJson(this);
-}
diff --git a/comwell_key_app/lib/payment_cards/pregistration/pages/prereg_confirmation_page.dart b/comwell_key_app/lib/payment_cards/pregistration/pages/prereg_confirmation_page.dart
deleted file mode 100644
index 8ef4a978..00000000
--- a/comwell_key_app/lib/payment_cards/pregistration/pages/prereg_confirmation_page.dart
+++ /dev/null
@@ -1,92 +0,0 @@
-import 'package:comwell_key_app/payment_cards/pregistration/bloc/preregistration_cubit.dart';
-import 'package:comwell_key_app/payment_cards/pregistration/components/information_card.dart';
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-
-class PreregConfirmationPage extends StatelessWidget {
- const PreregConfirmationPage({super.key});
-
- @override
- Widget build(BuildContext context) {
- final cubit = context.read<PreregistrationCubit>();
- final state = cubit.state;
- final user = state.user!;
-
- String extrasTitleText;
- if (state.numOfExtras == 1) {
- extrasTitleText =
- "preregistration_confirmation_extras_card_title_singular".tr();
- } else {
- extrasTitleText = "preregistration_confirmation_extras_card_title_plural"
- .tr(args: [state.numOfExtras.toString()]);
- }
-
- return ListView(
- children: [
- const SizedBox(height: 40),
- Text("preregistration_confirmation_title".tr(),
- style: Theme.of(context).textTheme.headlineLarge),
- const SizedBox(height: 40),
- InformationCard(
- title: "preregistration_confirmation_profile_card_title".tr(),
- onEditClick: cubit.onEditProfileClicked,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- "${user.firstName} ${user.lastName}",
- style: Theme.of(context).textTheme.bodyMedium,
- ),
- Text(
- user.email,
- style: Theme.of(context).textTheme.bodyMedium,
- ),
- Text(
- "${user.addressCountry} ${user.phoneNumber}",
- style: Theme.of(context).textTheme.bodyMedium,
- ),
- ],
- ),
- ),
- const SizedBox(height: 12),
- InformationCard(
- title: "preregistration_confirmation_address_card_title".tr(),
- onEditClick: cubit.onEditAddressClicked,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- user.address?.street ?? "",
- style: Theme.of(context).textTheme.bodyMedium,
- ),
- Text(
- "${user.address?.zipCode}, ${user.address?.city}, ${user.address?.country}",
- style: Theme.of(context).textTheme.bodyMedium,
- ),
- ],
- ),
- ),
- const SizedBox(height: 12),
- InformationCard(
- title: extrasTitleText,
- onEditClick: cubit.onEditExtrasClicked,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- "${state.extrasTotalPrice} kr.",
- style: Theme.of(context).textTheme.bodySmall,
- ),
- Text(
- "preregistration_confirmation_extras_card_subtitle".tr(),
- style: Theme.of(context).textTheme.bodyMedium,
- ),
- ],
- ),
- ),
- const SizedBox(height: 40),
- ],
- );
- }
-}
diff --git a/comwell_key_app/lib/payment_cards/pregistration/pages/prereg_information_page.dart b/comwell_key_app/lib/payment_cards/pregistration/pages/prereg_information_page.dart
deleted file mode 100644
index 58cacc4c..00000000
--- a/comwell_key_app/lib/payment_cards/pregistration/pages/prereg_information_page.dart
+++ /dev/null
@@ -1,82 +0,0 @@
-import 'package:comwell_key_app/common/components/comwell_text_field.dart';
-import 'package:comwell_key_app/payment_cards/pregistration/bloc/preregistration_cubit.dart';
-import 'package:comwell_key_app/payment_cards/pregistration/bloc/preregistration_state.dart';
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-
-class PreregInformationPage extends StatelessWidget {
- const PreregInformationPage({super.key});
-
- @override
- Widget build(BuildContext context) {
- return BlocBuilder<PreregistrationCubit, PreregistrationState>(
- builder: (context, state) {
- final cubit = context.read<PreregistrationCubit>();
- final state = cubit.state;
- if (state.loading) {
- return const Center(child: CircularProgressIndicator());
- }
- if (state.error != null) {
- return const Center(child: Text("Error"));
- }
- final addressErrorMessage =
- !cubit.isAddressValid && state.missingInformation
- ? "generic_information_required".tr()
- : null;
- final postalCodeErrorMessage =
- !cubit.isPostalCodeValid && state.missingInformation
- ? "generic_information_required".tr()
- : null;
- final cityErrorMessage = !cubit.isCityValid && state.missingInformation
- ? "generic_information_required".tr()
- : null;
- final countryErrorMessage =
- !cubit.isCountryValid && state.missingInformation
- ? "generic_information_required".tr()
- : null;
- return ListView(
- key: const PageStorageKey("information_form"),
- children: [
- const SizedBox(height: 40),
- Text("preregistration_address_title".tr(),
- style: Theme.of(context).textTheme.headlineLarge),
- const SizedBox(height: 18),
- Text("preregistration_address_subtitle".tr(),
- style: Theme.of(context).textTheme.bodySmall),
- const SizedBox(height: 40),
- ComwellTextField(
- key: const Key("address"),
- fieldName: "preregistration_address_label_address".tr(),
- initialValue: "",
- readOnly: false,
- errorMessage: addressErrorMessage,
- controller: cubit.addressTextController),
- const SizedBox(height: 12),
- ComwellTextField(
- fieldName: "preregistration_address_label_postal_code".tr(),
- initialValue: "",
- textInputType: TextInputType.number,
- errorMessage: postalCodeErrorMessage,
- readOnly: false,
- controller: cubit.postalCodeTextController),
- const SizedBox(height: 12),
- ComwellTextField(
- fieldName: "preregistration_address_label_city".tr(),
- initialValue: "",
- readOnly: false,
- errorMessage: cityErrorMessage,
- controller: cubit.cityTextController),
- const SizedBox(height: 12),
- ComwellTextField(
- fieldName: "preregistration_address_label_country".tr(),
- initialValue: "",
- errorMessage: countryErrorMessage,
- readOnly: false,
- controller: cubit.countryTextController),
- const SizedBox(height: 100),
- ],
- );
- });
- }
-}
diff --git a/comwell_key_app/lib/payment_cards/pregistration/pregistration_repository.dart b/comwell_key_app/lib/payment_cards/pregistration/pregistration_repository.dart
deleted file mode 100644
index 48c8af10..00000000
--- a/comwell_key_app/lib/payment_cards/pregistration/pregistration_repository.dart
+++ /dev/null
@@ -1,121 +0,0 @@
-import 'package:adyen_checkout/adyen_checkout.dart';
-import 'package:comwell_key_app/check_out/models/payment_configurations.dart';
-import 'package:comwell_key_app/profile_settings/repostiory/profile_settings_repository.dart';
-import 'package:comwell_key_app/services/adyen/stored_payment_method.dart';
-import 'package:comwell_key_app/services/api.dart';
-import 'package:comwell_key_app/utils/locator.dart';
-
-class PreregistrationRepository {
- final Api _api = Api();
- final ProfileSettingsRepository profileSettingsRepository =
- locator<ProfileSettingsRepository>();
-
- PreregistrationRepository();
-
- Future<PaymentConfigurations> sessionCheckout(
- Amount amount,
- String hotelCode,
- ) async {
- final response = await _api.createAdyenSession(amount, hotelCode);
- final clientKey = response["clientKey"] as String;
- final sessionResponse = response["sessionResponse"];
- final id = sessionResponse["id"] as String;
- final sessionData = sessionResponse["sessionData"] as String;
- final session = await AdyenCheckout.session.create(
- sessionId: id,
- sessionData: sessionData,
- configuration: dropInConfiguration(amount, clientKey));
- return PaymentConfigurations(
- sessionCheckout: session,
- googlePayConfiguration: _getGooglePayComponentConfig(clientKey),
- dropInConfiguration: dropInConfiguration(amount, clientKey),
- cardComponentConfiguration:
- cardComponentConfiguration(amount, clientKey),
- applePayConfiguration:
- _applePayComponentConfiguration(clientKey, amount));
- }
-
- CardComponentConfiguration cardComponentConfiguration(
- Amount amount,
- String clientKey,
- ) {
- return CardComponentConfiguration(
- environment: Environment.test,
- amount: amount,
- cardConfiguration: const CardConfiguration(showStorePaymentField: true),
- clientKey: clientKey,
- countryCode: "DK",
- );
- }
-
- DropInConfiguration dropInConfiguration(Amount amount, String clientKey) {
- // TODO: missing endpoint to retrieve client key
- return DropInConfiguration(
- environment: Environment.test,
- clientKey: clientKey,
- countryCode: "DK",
- skipListWhenSinglePaymentMethod: true,
- googlePayConfiguration: _googlePayConfiguration,
- applePayConfiguration: _getApplePlayConfig(amount),
- cardConfiguration: const CardConfiguration(showStorePaymentField: true),
- paymentMethodNames: {
- "scheme": "Credit card",
- },
- );
- }
-
- GooglePayConfiguration get _googlePayConfiguration =>
- const GooglePayConfiguration(
- googlePayEnvironment: GooglePayEnvironment.test,
- );
-
- GooglePayComponentConfiguration _getGooglePayComponentConfig(
- String clientKey,
- ) {
- return GooglePayComponentConfiguration(
- environment: Environment.test,
- countryCode: "DK",
- clientKey: clientKey,
- googlePayConfiguration: _googlePayConfiguration,
- );
- }
-
- ApplePayComponentConfiguration _applePayComponentConfiguration(
- String clientKey,
- Amount amount,
- ) {
- return ApplePayComponentConfiguration(
- environment: Environment.test,
- countryCode: "DK",
- clientKey: clientKey,
- applePayConfiguration: _getApplePlayConfig(amount),
- );
- }
-
- ApplePayConfiguration _getApplePlayConfig(Amount amount) {
- return ApplePayConfiguration(
- merchantId: "merchant.ComwellHotelsECOM",
- merchantName: "Comwell",
- allowOnboarding: true,
- allowShippingContactEditing: true,
- applePaySummaryItems: [
- ApplePaySummaryItem(
- label: "Total",
- amount: Amount(value: amount.value, currency: amount.currency),
- type: ApplePaySummaryItemType.definite)
- ]);
- }
-
- static final Iterable<StoredPaymentMethod> mockStoredPaymentData = [
- 1,
- 2,
- 3,
- 4
- ].map((i) => StoredPaymentMethod(
- expiryMonth: "12",
- expiryYear: "2035",
- holderName: "holder name",
- id: "id $i",
- lastFour: "$i$i$i$i",
- brand: "visa"));
-}
diff --git a/comwell_key_app/lib/payment_cards/pregistration/preregistration_flow.dart b/comwell_key_app/lib/payment_cards/pregistration/preregistration_flow.dart
deleted file mode 100644
index f7e2a51c..00000000
--- a/comwell_key_app/lib/payment_cards/pregistration/preregistration_flow.dart
+++ /dev/null
@@ -1,127 +0,0 @@
-import 'package:comwell_key_app/payment_cards/pregistration/bloc/preregistration_state.dart';
-import 'package:comwell_key_app/payment_cards/pregistration/bloc/preregistration_cubit.dart';
-import 'package:comwell_key_app/payment_cards/pregistration/pages/prereg_confirmation_page.dart';
-import 'package:comwell_key_app/payment_cards/pregistration/pages/prereg_information_page.dart';
-import 'package:comwell_key_app/themes/dark_theme.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:go_router/go_router.dart';
-
-enum PreregistrationPage {
- information,
- confirmation;
-
- static PreregistrationPage fromIndex(int index) {
- return PreregistrationPage.values[index];
- }
-
- static Iterable<Widget> getPages(Key key) {
- return PreregistrationPage.values.map((page) {
- switch (page) {
- case PreregistrationPage.information:
- return PreregInformationPage(key: key);
- case PreregistrationPage.confirmation:
- return PreregConfirmationPage(key: key);
- }
- });
- }
-}
-
-class PreregistrationFlow extends StatefulWidget {
- const PreregistrationFlow({super.key});
-
- @override
- State<PreregistrationFlow> createState() => _PreregistrationFlowState();
-}
-
-class _PreregistrationFlowState extends State<PreregistrationFlow> {
- @override
- Widget build(BuildContext context) {
- return BlocProvider(
- create: (context) => PreregistrationCubit()..init(),
- child: BlocConsumer<PreregistrationCubit, PreregistrationState>(
- listener: (context, state) {},
- builder: (context, state) {
- final cubit = context.read<PreregistrationCubit>();
- return Scaffold(
- backgroundColor: colorBackground,
- appBar: AppBar(
- backgroundColor: colorSecondary,
- shape: const RoundedRectangleBorder(
- borderRadius:
- BorderRadius.vertical(bottom: Radius.circular(24))),
- toolbarOpacity: 1.0,
- leading: BackButton(
- color: Colors.black,
- onPressed: () {
- if (!cubit.onBackClicked()) {
- context.pop();
- }
- },
- ),
- ),
- bottomNavigationBar: Builder(builder: (context) {
- if (state.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.all(16.0),
- child: ElevatedButton(
- onPressed: cubit.canContinue
- ? cubit.onContinueClicked
- : 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(cubit.buttonText),
- ),
- ),
- ),
- ),
- ],
- ),
- ],
- );
- }),
- 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/bloc/preregistration_cubit.dart b/comwell_key_app/lib/pregistration/bloc/preregistration_cubit.dart
new file mode 100644
index 00000000..5a3ad94b
--- /dev/null
+++ b/comwell_key_app/lib/pregistration/bloc/preregistration_cubit.dart
@@ -0,0 +1,230 @@
+import 'package:adyen_checkout/src/common/model/payment_result.dart';
+import 'package:bloc/bloc.dart';
+import 'package:comwell_key_app/booking_details/bloc/booking_details_bloc.dart';
+import 'package:comwell_key_app/overview/models/booking.dart';
+import 'package:comwell_key_app/pregistration/bloc/preregistration_state.dart';
+import 'package:comwell_key_app/pregistration/pregistration_repository.dart';
+import 'package:comwell_key_app/pregistration/preregistration_flow.dart';
+import 'package:comwell_key_app/profile/profile_repository.dart';
+import 'package:comwell_key_app/profile_settings/repostiory/profile_settings_repository.dart';
+import 'package:comwell_key_app/tracking/comwell_tracking.dart';
+import 'package:comwell_key_app/tracking/models/analytics_event_item.dart';
+import 'package:comwell_key_app/utils/locator.dart';
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/cupertino.dart';
+
+class PreregistrationCubit extends Cubit<PreregistrationState> {
+ final _profileRepository = locator<ProfileRepository>();
+ final _tracking = locator<ComwellTracking>();
+ final _preregistrationRepository = locator<PreregistrationRepository>();
+ // final _bookingDetailsBloc = locator<BookingDetailsBloc>();
+ final Booking booking;
+
+ final pageController = PageController();
+ final addressTextController = TextEditingController();
+ final postalCodeTextController = TextEditingController();
+ final cityTextController = TextEditingController();
+ final countryTextController = TextEditingController();
+
+ PreregistrationPage get currentPage =>
+ PreregistrationPage.fromIndex(pageController.page?.toInt() ?? 0);
+ bool _isAnimating = false;
+
+ PreregistrationCubit({required this.booking})
+ : super(const PreregistrationState(loading: false)) {
+ _tracking.trackScreenView(
+ "Pre-registration - Betalingskort",
+ "/pre-registration/betalingskort",
+ );
+ }
+
+ void init() async {
+ emit(state.copyWith(loading: true, error: null));
+ try {
+ final user = await _profileRepository.fetchProfileSettings();
+ addressTextController.text = user.address.street;
+ postalCodeTextController.text = user.address.zipCode;
+ cityTextController.text = user.address.city;
+ countryTextController.text = user.address.country;
+ emit(state.copyWith(loading: false, error: null, user: user));
+ } on Exception catch (e) {
+ emit(state.copyWith(error: e));
+ }
+ }
+
+ void onInformationContinueClicked() {
+ if (isAddressValid && isCityValid && isCountryValid) {
+ _navigateNextPage();
+ } else {
+ emit(state.copyWith(missingInformation: true));
+ }
+ }
+
+ void onContinueClicked() {
+ if (_isAnimating) return;
+ switch (currentPage) {
+ case PreregistrationPage.information:
+ onInformationContinueClicked();
+ break;
+ // case PreregistrationPage.payment:
+ // _onConfirmPressed();
+ // break;
+ case PreregistrationPage.confirmation:
+ _onConfirmPressed();
+ break;
+ }
+ }
+
+ void addToCart() {
+ final analyticsEventItem = AnalyticsEventItem(
+ hotelName: "Comwell",
+ currency: "DKK",
+ value: 500,
+ placement: "placement",
+ items: ["items"],
+ itemId: "itemId",
+ itemName: "itemName",
+ price: 200,
+ quantity: 200);
+ _tracking.trackAddToCart(analyticsEventItem);
+ }
+
+ void removeToCard() {
+ final analyticsEventItem = AnalyticsEventItem(
+ hotelName: "Comwell",
+ currency: "DKK",
+ value: 500,
+ placement: "placement",
+ items: ["items"],
+ itemId: "itemId",
+ itemName: "itemName",
+ price: 200,
+ quantity: 200);
+ _tracking.trackRemoveFromCart(analyticsEventItem);
+ }
+
+ void _onConfirmPressed() async {
+ // final analyticsEventItem = AnalyticsEventItem(
+ // hotelName: "Comwell",
+ // currency: "DKK",
+ // value: 500,
+ // placement: "placement",
+ // items: ["items"],
+ // itemId: "itemId",
+ // itemName: "itemName",
+ // price: 200,
+ // quantity: 200);
+ // _tracking.trackBeginCheckout(analyticsEventItem);
+
+ final confirmationId = booking.confirmationId;
+ print("confirmationId=$confirmationId");
+ final response =
+ await _preregistrationRepository.createPreregistration(confirmationId);
+ print("response=$response");
+ emit(state.copyWith(loading: true));
+ Future.delayed(const Duration(seconds: 3), () {
+ emit(state.copyWith(loading: false));
+ });
+ }
+
+ void onEditProfileClicked() {
+ // Not implemented
+ }
+
+ void onEditAddressClicked() {
+ _navigateTo(PreregistrationPage.information);
+ }
+
+ void onEditExtrasClicked() {
+ // Not implemented
+ }
+
+ bool onBackClicked() {
+ if (_isAnimating) return true;
+ final hasPage = pageController.page != null;
+ if (hasPage && pageController.page! >= 1.0) {
+ _navigatePreviousPage();
+ return true;
+ }
+ return false;
+ }
+
+ void _navigateTo(PreregistrationPage page) async {
+ if (_isAnimating) return;
+ _isAnimating = true;
+ await pageController.animateToPage(page.index,
+ duration: const Duration(milliseconds: 500),
+ curve: Curves.fastOutSlowIn);
+ emit(state.copyWith(forceUpdate: true));
+ _isAnimating = false;
+ }
+
+ void _navigateNextPage() async {
+ if (_isAnimating) return;
+ _isAnimating = true;
+ await pageController.nextPage(
+ duration: const Duration(milliseconds: 500),
+ curve: Curves.fastOutSlowIn);
+ emit(state.copyWith(forceUpdate: true));
+ _isAnimating = false;
+ }
+
+ void _navigatePreviousPage() async {
+ if (_isAnimating) return;
+ _isAnimating = true;
+ await pageController.previousPage(
+ duration: const Duration(milliseconds: 500),
+ curve: Curves.fastOutSlowIn);
+ emit(state.copyWith(forceUpdate: true));
+ _isAnimating = false;
+ }
+
+ @override
+ Future<void> close() {
+ addressTextController.dispose();
+ postalCodeTextController.dispose();
+ cityTextController.dispose();
+ countryTextController.dispose();
+ pageController.dispose();
+ return super.close();
+ }
+
+ bool get isAddressValid => addressTextController.text.isNotEmpty;
+
+ bool get isPostalCodeValid =>
+ postalCodeTextController.text.isNotEmpty;
+
+ bool get isCityValid => cityTextController.text.isNotEmpty;
+
+ bool get isCountryValid => countryTextController.text.isNotEmpty;
+
+ bool get canContinue {
+ int page = pageController.page?.ceil() ?? 0;
+ final preregPage = PreregistrationPage.fromIndex(page);
+ switch (preregPage) {
+ case PreregistrationPage.information:
+ return isAddressValid && isPostalCodeValid && isCityValid && isCityValid;
+ case PreregistrationPage.confirmation:
+ return true;
+ // case PreregistrationPage.payment:
+ // return true;
+ }
+ }
+
+ String get buttonText {
+ int page = pageController.page?.ceil() ?? 0;
+ final preregPage = PreregistrationPage.fromIndex(page);
+ switch (preregPage) {
+ case PreregistrationPage.information:
+ return "generic_continue".tr();
+ case PreregistrationPage.confirmation:
+ return "generic_confirm".tr();
+ // case PreregistrationPage.payment:
+ // return "generic_confirm".tr();
+ }
+ }
+
+ void onTermsAndConditionsToggled(bool toggle) {
+ emit(state.copyWith(termsAndConditionsAccepted: toggle));
+ }
+}
diff --git a/comwell_key_app/lib/pregistration/bloc/preregistration_state.dart b/comwell_key_app/lib/pregistration/bloc/preregistration_state.dart
new file mode 100644
index 00000000..f6088e0e
--- /dev/null
+++ b/comwell_key_app/lib/pregistration/bloc/preregistration_state.dart
@@ -0,0 +1,60 @@
+import 'package:equatable/equatable.dart';
+
+import '../../profile_settings/model/user.dart';
+
+class PreregistrationState extends Equatable {
+ final bool forceUpdate;
+ final bool loading;
+ final User? user;
+ final Exception? error;
+ final bool missingInformation;
+ final int numOfExtras;
+ final int extrasTotalPrice;
+ final bool termsAndConditionsAccepted;
+
+ const PreregistrationState({
+ required this.loading,
+ this.missingInformation = false,
+ this.numOfExtras = 0,
+ this.extrasTotalPrice = 0,
+ this.termsAndConditionsAccepted = false,
+ this.forceUpdate = false,
+ this.user,
+ this.error,
+ });
+
+ @override
+ List<Object?> get props => [
+ loading,
+ user,
+ error,
+ missingInformation,
+ numOfExtras,
+ extrasTotalPrice,
+ termsAndConditionsAccepted,
+ forceUpdate,
+ ];
+
+ PreregistrationState copyWith({
+ bool? loading,
+ User? user,
+ Exception? error,
+ bool? missingInformation,
+ int? numOfExtras,
+ int? extrasTotalPrice,
+ String? buttonTextStringId,
+ bool? termsAndConditionsAccepted,
+ bool forceUpdate = false,
+ }) {
+ return PreregistrationState(
+ forceUpdate: forceUpdate ? !this.forceUpdate : this.forceUpdate,
+ loading: loading ?? this.loading,
+ missingInformation: missingInformation ?? this.missingInformation,
+ user: user ?? this.user,
+ numOfExtras: numOfExtras ?? this.numOfExtras,
+ termsAndConditionsAccepted:
+ termsAndConditionsAccepted ?? this.termsAndConditionsAccepted,
+ extrasTotalPrice: extrasTotalPrice ?? this.extrasTotalPrice,
+ error: error);
+ }
+}
diff --git a/comwell_key_app/lib/pregistration/components/card_item.dart b/comwell_key_app/lib/pregistration/components/card_item.dart
new file mode 100644
index 00000000..1e45fa8f
--- /dev/null
+++ b/comwell_key_app/lib/pregistration/components/card_item.dart
@@ -0,0 +1,66 @@
+import 'package:comwell_key_app/common/components/payment_card_image.dart';
+import 'package:comwell_key_app/overview/models/payment_details.dart';
+import 'package:comwell_key_app/services/adyen/stored_payment_method.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+
+class CardItem extends StatelessWidget {
+ final StoredPaymentMethod paymentMethod;
+ final bool isSelected;
+ final VoidCallback? onClick;
+
+ const CardItem({
+ super.key,
+ required this.paymentMethod,
+ this.onClick,
+ this.isSelected = false,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return InkWell(
+ onTap: onClick,
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ PaymentCardImage(cardType: CardType.fromString(paymentMethod.brand)),
+ const SizedBox(width: 12),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ paymentMethod.holderName,
+ style: Theme.of(context).textTheme.bodySmall,
+ ),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ ..."**** **** **** ".characters.map((char) {
+ if (char == '*') {
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 1.0),
+ child: Container(
+ width: 5,
+ height: 5,
+ decoration: const BoxDecoration(
+ shape: BoxShape.circle, color: Colors.black),
+ ),
+ );
+ }
+ return const SizedBox(width: 8);
+ }),
+ Text(
+ paymentMethod.lastFour,
+ style: Theme.of(context).textTheme.bodyMedium,
+ )
+ ],
+ ),
+ ],
+ ),
+ const Expanded(child: SizedBox()),
+ if (isSelected) SvgPicture.asset("assets/icons/ic_checkmark.svg")
+ ],
+ ),
+ );
+ }
+}
diff --git a/comwell_key_app/lib/pregistration/components/clickable_card_item.dart b/comwell_key_app/lib/pregistration/components/clickable_card_item.dart
new file mode 100644
index 00000000..6e6663ce
--- /dev/null
+++ b/comwell_key_app/lib/pregistration/components/clickable_card_item.dart
@@ -0,0 +1,31 @@
+import 'package:comwell_key_app/pregistration/components/card_item.dart';
+import 'package:comwell_key_app/services/adyen/stored_payment_method.dart';
+import 'package:comwell_key_app/themes/light_theme.dart';
+import 'package:flutter/material.dart';
+
+class ClickableCardItem extends StatelessWidget {
+ final StoredPaymentMethod paymentMethod;
+ final VoidCallback onClick;
+ final bool isSelected;
+
+ const ClickableCardItem({
+ super.key,
+ required this.paymentMethod,
+ required this.onClick,
+ this.isSelected = false,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return InkWell(
+ onTap: onClick,
+ child: Container(
+ decoration: BoxDecoration(
+ border: Border.all(color: colorDivider),
+ ),
+ padding: const EdgeInsets.all(12),
+ child: CardItem(paymentMethod: paymentMethod, isSelected: isSelected),
+ ),
+ );
+ }
+}
diff --git a/comwell_key_app/lib/pregistration/components/information_card.dart b/comwell_key_app/lib/pregistration/components/information_card.dart
new file mode 100644
index 00000000..3cfbde80
--- /dev/null
+++ b/comwell_key_app/lib/pregistration/components/information_card.dart
@@ -0,0 +1,39 @@
+import 'package:comwell_key_app/themes/dark_theme.dart';
+import 'package:flutter/material.dart';
+
+class InformationCard extends StatelessWidget {
+ final String title;
+ final VoidCallback onEditClick;
+ final Widget child;
+
+ const InformationCard({
+ super.key,
+ required this.title,
+ required this.onEditClick,
+ required this.child,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ padding: const EdgeInsets.all(12),
+ decoration: BoxDecoration(
+ color: sandColor[20],
+ borderRadius: const BorderRadius.all(Radius.circular(10))),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(title),
+ TextButton(onPressed: onEditClick, child: const Text("Rediger"))
+ ],
+ ),
+ const SizedBox(height: 40),
+ child
+ ],
+ ),
+ );
+ }
+}
diff --git a/comwell_key_app/lib/pregistration/pages/prereg_confirmation_page.dart b/comwell_key_app/lib/pregistration/pages/prereg_confirmation_page.dart
new file mode 100644
index 00000000..7128a205
--- /dev/null
+++ b/comwell_key_app/lib/pregistration/pages/prereg_confirmation_page.dart
@@ -0,0 +1,92 @@
+import 'package:comwell_key_app/pregistration/bloc/preregistration_cubit.dart';
+import 'package:comwell_key_app/pregistration/components/information_card.dart';
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+class PreregConfirmationPage extends StatelessWidget {
+ const PreregConfirmationPage({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ final cubit = context.read<PreregistrationCubit>();
+ final state = cubit.state;
+ final user = state.user!;
+
+ String extrasTitleText;
+ if (state.numOfExtras == 1) {
+ extrasTitleText =
+ "preregistration_confirmation_extras_card_title_singular".tr();
+ } else {
+ extrasTitleText = "preregistration_confirmation_extras_card_title_plural"
+ .tr(args: [state.numOfExtras.toString()]);
+ }
+
+ return ListView(
+ children: [
+ const SizedBox(height: 40),
+ Text("preregistration_confirmation_title".tr(),
+ style: Theme.of(context).textTheme.headlineLarge),
+ const SizedBox(height: 40),
+ InformationCard(
+ title: "preregistration_confirmation_profile_card_title".tr(),
+ onEditClick: cubit.onEditProfileClicked,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ "${user.firstName} ${user.lastName}",
+ style: Theme.of(context).textTheme.bodyMedium,
+ ),
+ Text(
+ user.email,
+ style: Theme.of(context).textTheme.bodyMedium,
+ ),
+ Text(
+ "${user.addressCountry} ${user.phoneNumber}",
+ style: Theme.of(context).textTheme.bodyMedium,
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(height: 12),
+ InformationCard(
+ title: "preregistration_confirmation_address_card_title".tr(),
+ onEditClick: cubit.onEditAddressClicked,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ user.address.street,
+ style: Theme.of(context).textTheme.bodyMedium,
+ ),
+ Text(
+ "${user.address.zipCode}, ${user.address.city}, ${user.address.country}",
+ style: Theme.of(context).textTheme.bodyMedium,
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(height: 12),
+ InformationCard(
+ title: extrasTitleText,
+ onEditClick: cubit.onEditExtrasClicked,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ "${state.extrasTotalPrice} kr.",
+ style: Theme.of(context).textTheme.bodySmall,
+ ),
+ Text(
+ "preregistration_confirmation_extras_card_subtitle".tr(),
+ style: Theme.of(context).textTheme.bodyMedium,
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(height: 40),
+ ],
+ );
+ }
+}
diff --git a/comwell_key_app/lib/pregistration/pages/prereg_information_page.dart b/comwell_key_app/lib/pregistration/pages/prereg_information_page.dart
new file mode 100644
index 00000000..6564dfbe
--- /dev/null
+++ b/comwell_key_app/lib/pregistration/pages/prereg_information_page.dart
@@ -0,0 +1,82 @@
+import 'package:comwell_key_app/common/components/comwell_text_field.dart';
+import 'package:comwell_key_app/pregistration/bloc/preregistration_cubit.dart';
+import 'package:comwell_key_app/pregistration/bloc/preregistration_state.dart';
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+class PreregInformationPage extends StatelessWidget {
+ const PreregInformationPage({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return BlocBuilder<PreregistrationCubit, PreregistrationState>(
+ builder: (context, state) {
+ final cubit = context.read<PreregistrationCubit>();
+ final state = cubit.state;
+ if (state.loading) {
+ return const Center(child: CircularProgressIndicator());
+ }
+ if (state.error != null) {
+ return const Center(child: Text("Error"));
+ }
+ final addressErrorMessage =
+ !cubit.isAddressValid && state.missingInformation
+ ? "generic_information_required".tr()
+ : null;
+ final postalCodeErrorMessage =
+ !cubit.isPostalCodeValid && state.missingInformation
+ ? "generic_information_required".tr()
+ : null;
+ final cityErrorMessage = !cubit.isCityValid && state.missingInformation
+ ? "generic_information_required".tr()
+ : null;
+ final countryErrorMessage =
+ !cubit.isCountryValid && state.missingInformation
+ ? "generic_information_required".tr()
+ : null;
+ return ListView(
+ key: const PageStorageKey("information_form"),
+ children: [
+ const SizedBox(height: 40),
+ Text("preregistration_address_title".tr(),
+ style: Theme.of(context).textTheme.headlineLarge),
+ const SizedBox(height: 18),
+ Text("preregistration_address_subtitle".tr(),
+ style: Theme.of(context).textTheme.bodySmall),
+ const SizedBox(height: 40),
+ ComwellTextField(
+ key: const Key("address"),
+ fieldName: "preregistration_address_label_address".tr(),
+ initialValue: "",
+ readOnly: false,
+ errorMessage: addressErrorMessage,
+ controller: cubit.addressTextController),
+ const SizedBox(height: 12),
+ ComwellTextField(
+ fieldName: "preregistration_address_label_postal_code".tr(),
+ initialValue: "",
+ textInputType: TextInputType.number,
+ errorMessage: postalCodeErrorMessage,
+ readOnly: false,
+ controller: cubit.postalCodeTextController),
+ const SizedBox(height: 12),
+ ComwellTextField(
+ fieldName: "preregistration_address_label_city".tr(),
+ initialValue: "",
+ readOnly: false,
+ errorMessage: cityErrorMessage,
+ controller: cubit.cityTextController),
+ const SizedBox(height: 12),
+ ComwellTextField(
+ fieldName: "preregistration_address_label_country".tr(),
+ initialValue: "",
+ errorMessage: countryErrorMessage,
+ readOnly: false,
+ controller: cubit.countryTextController),
+ const SizedBox(height: 100),
+ ],
+ );
+ });
+ }
+}
diff --git a/comwell_key_app/lib/pregistration/pregistration_repository.dart b/comwell_key_app/lib/pregistration/pregistration_repository.dart
new file mode 100644
index 00000000..655fdc10
--- /dev/null
+++ b/comwell_key_app/lib/pregistration/pregistration_repository.dart
@@ -0,0 +1,131 @@
+import 'package:adyen_checkout/adyen_checkout.dart';
+import 'package:comwell_key_app/check_out/models/payment_configurations.dart';
+import 'package:comwell_key_app/profile_settings/repostiory/profile_settings_repository.dart';
+import 'package:comwell_key_app/services/adyen/stored_payment_method.dart';
+import 'package:comwell_key_app/services/api.dart';
+import 'package:comwell_key_app/utils/locator.dart';
+
+class PreregistrationRepository {
+ final Api _api = Api();
+ final ProfileSettingsRepository profileSettingsRepository =
+ locator<ProfileSettingsRepository>();
+
+ PreregistrationRepository();
+
+ Future<PaymentConfigurations> sessionCheckout(
+ Amount amount,
+ String hotelCode,
+ ) async {
+ final response = await _api.createAdyenSession(amount, hotelCode);
+ final clientKey = response["clientKey"] as String;
+ final sessionResponse = response["sessionResponse"];
+ final id = sessionResponse["id"] as String;
+ final sessionData = sessionResponse["sessionData"] as String;
+ final session = await AdyenCheckout.session.create(
+ sessionId: id,
+ sessionData: sessionData,
+ configuration: dropInConfiguration(amount, clientKey));
+ return PaymentConfigurations(
+ sessionCheckout: session,
+ googlePayConfiguration: _getGooglePayComponentConfig(clientKey),
+ dropInConfiguration: dropInConfiguration(amount, clientKey),
+ cardComponentConfiguration:
+ cardComponentConfiguration(amount, clientKey),
+ applePayConfiguration:
+ _applePayComponentConfiguration(clientKey, amount));
+ }
+
+ Future<dynamic> createPreregistration(String confirmationId) async {
+ try {
+ final response = await _api.preRegistration(confirmationId);
+ return response.data!;
+ } catch (e) {
+ print("error=$e");
+ return null;
+ }
+ }
+
+ CardComponentConfiguration cardComponentConfiguration(
+ Amount amount,
+ String clientKey,
+ ) {
+ return CardComponentConfiguration(
+ environment: Environment.test,
+ amount: amount,
+ cardConfiguration: const CardConfiguration(showStorePaymentField: true),
+ clientKey: clientKey,
+ countryCode: "DK",
+ );
+ }
+
+ DropInConfiguration dropInConfiguration(Amount amount, String clientKey) {
+ // TODO: missing endpoint to retrieve client key
+ return DropInConfiguration(
+ environment: Environment.test,
+ clientKey: clientKey,
+ countryCode: "DK",
+ skipListWhenSinglePaymentMethod: true,
+ googlePayConfiguration: _googlePayConfiguration,
+ applePayConfiguration: _getApplePlayConfig(amount),
+ cardConfiguration: const CardConfiguration(showStorePaymentField: true),
+ paymentMethodNames: {
+ "scheme": "Credit card",
+ },
+ );
+ }
+
+ GooglePayConfiguration get _googlePayConfiguration =>
+ const GooglePayConfiguration(
+ googlePayEnvironment: GooglePayEnvironment.test,
+ );
+
+ GooglePayComponentConfiguration _getGooglePayComponentConfig(
+ String clientKey,
+ ) {
+ return GooglePayComponentConfiguration(
+ environment: Environment.test,
+ countryCode: "DK",
+ clientKey: clientKey,
+ googlePayConfiguration: _googlePayConfiguration,
+ );
+ }
+
+ ApplePayComponentConfiguration _applePayComponentConfiguration(
+ String clientKey,
+ Amount amount,
+ ) {
+ return ApplePayComponentConfiguration(
+ environment: Environment.test,
+ countryCode: "DK",
+ clientKey: clientKey,
+ applePayConfiguration: _getApplePlayConfig(amount),
+ );
+ }
+
+ ApplePayConfiguration _getApplePlayConfig(Amount amount) {
+ return ApplePayConfiguration(
+ merchantId: "merchant.ComwellHotelsECOM",
+ merchantName: "Comwell",
+ allowOnboarding: true,
+ allowShippingContactEditing: true,
+ applePaySummaryItems: [
+ ApplePaySummaryItem(
+ label: "Total",
+ amount: Amount(value: amount.value, currency: amount.currency),
+ type: ApplePaySummaryItemType.definite)
+ ]);
+ }
+
+ static final Iterable<StoredPaymentMethod> mockStoredPaymentData = [
+ 1,
+ 2,
+ 3,
+ 4
+ ].map((i) => StoredPaymentMethod(
+ expiryMonth: "12",
+ expiryYear: "2035",
+ holderName: "holder name",
+ id: "id $i",
+ lastFour: "$i$i$i$i",
+ brand: "visa"));
+}
diff --git a/comwell_key_app/lib/pregistration/preregistration_flow.dart b/comwell_key_app/lib/pregistration/preregistration_flow.dart
new file mode 100644
index 00000000..5a9ed24a
--- /dev/null
+++ b/comwell_key_app/lib/pregistration/preregistration_flow.dart
@@ -0,0 +1,124 @@
+import 'package:comwell_key_app/common/components/comwell_app_bar.dart';
+import 'package:comwell_key_app/overview/models/booking.dart';
+import 'package:comwell_key_app/payment_cards/bloc/payment_cards_cubit.dart';
+import 'package:comwell_key_app/payment_cards/payment_cards_page.dart';
+import 'package:comwell_key_app/pregistration/bloc/preregistration_state.dart';
+import 'package:comwell_key_app/pregistration/bloc/preregistration_cubit.dart';
+import 'package:comwell_key_app/pregistration/pages/prereg_confirmation_page.dart';
+import 'package:comwell_key_app/pregistration/pages/prereg_information_page.dart';
+import 'package:comwell_key_app/themes/dark_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:go_router/go_router.dart';
+
+enum PreregistrationPage {
+ information,
+ // payment,
+ confirmation;
+
+ static PreregistrationPage fromIndex(int index) {
+ return PreregistrationPage.values[index];
+ }
+
+ static Iterable<Widget> getPages(Key key) {
+ return PreregistrationPage.values.map((page) {
+ switch (page) {
+ case PreregistrationPage.information:
+ return PreregInformationPage(key: key);
+ // case PreregistrationPage.payment:
+ // return BlocProvider(
+ // create: (context) => PaymentCardsCubit(),
+ // child: const PaymentCardsPage());
+ case PreregistrationPage.confirmation:
+ return PreregConfirmationPage(key: key);
+ }
+ });
+ }
+}
+
+class PreregistrationFlow extends StatefulWidget {
+ final Booking booking;
+ const PreregistrationFlow({super.key, required this.booking});
+
+ @override
+ State<PreregistrationFlow> createState() => _PreregistrationFlowState();
+}
+
+class _PreregistrationFlowState extends State<PreregistrationFlow> {
+ @override
+ Widget build(BuildContext context) {
+ return BlocProvider(
+ create: (context) => PreregistrationCubit(booking: widget.booking)..init(),
+ child: BlocConsumer<PreregistrationCubit, PreregistrationState>(
+ listener: (context, state) {},
+ builder: (context, state) {
+ final cubit = context.read<PreregistrationCubit>();
+ return Scaffold(
+ backgroundColor: Colors.white,
+ appBar: const ComwellAppBar(
+ ),
+ bottomNavigationBar: Builder(builder: (context) {
+ if (state.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.all(16.0),
+ child: ElevatedButton(
+ onPressed: cubit.canContinue
+ ? cubit.onContinueClicked
+ : 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(cubit.buttonText),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ],
+ );
+ }),
+ 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/routing/app_router.dart b/comwell_key_app/lib/routing/app_router.dart
index c259cf67..6cf48225 100644
--- a/comwell_key_app/lib/routing/app_router.dart
+++ b/comwell_key_app/lib/routing/app_router.dart
@@ -30,7 +30,7 @@ import 'package:comwell_key_app/overview/cubit/overview_cubit.dart';
import 'package:comwell_key_app/overview/repository/overview_repository.dart';
import 'package:comwell_key_app/payment_cards/bloc/payment_cards_cubit.dart';
import 'package:comwell_key_app/payment_cards/payment_cards_page.dart';
-import 'package:comwell_key_app/payment_cards/pregistration/preregistration_flow.dart';
+import 'package:comwell_key_app/pregistration/preregistration_flow.dart';
import 'package:comwell_key_app/profile/cubit/profile_cubit.dart';
import 'package:comwell_key_app/profile/profile_page.dart';
import 'package:comwell_key_app/profile/profile_repository.dart';
@@ -303,7 +303,8 @@ GoRouter goRouter(AuthenticationBloc authBloc) {
path: "/${AppRoutes.preregistration.name}",
name: AppRoutes.preregistration.name,
builder: (context, state) {
- return const PreregistrationFlow();
+ final booking = state.extra as Booking;
+ return PreregistrationFlow(booking: booking);
}),
GoRoute(
path: "/${AppRoutes.houseKeeping.name}",
diff --git a/comwell_key_app/lib/routing/go_router_observer.dart b/comwell_key_app/lib/routing/go_router_observer.dart
index ae0296e0..b581c6d4 100644
--- a/comwell_key_app/lib/routing/go_router_observer.dart
+++ b/comwell_key_app/lib/routing/go_router_observer.dart
@@ -8,7 +8,8 @@ class GoRouterObserver extends NavigatorObserver {
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
debugPrint('DidPush: $route');
final routeName = route.settings.name ?? 'Unknown';
- locator<ComwellTracking>().trackScreenView('$routeName - page', getPath(routeName));
+ locator<ComwellTracking>()
+ .trackScreenView('$routeName - page', getPath(routeName));
}
@override
@@ -31,8 +32,6 @@ class GoRouterObserver extends NavigatorObserver {
}
}
-
-
String getPath(String routeName) {
switch (routeName) {
case 'overview':
@@ -53,23 +52,25 @@ String getPath(String routeName) {
return '/overview/bookingsdetails/hotelInformation/spa';
case 'parking':
return '/overview/bookingsdetails/hotelInformation/parking';
+ case 'paymentCards':
+ return '/overview/bookingsdetails/paymentCards';
case 'checkOut':
return '/overview/bookingsdetails/checkOut';
- case 'checkIn':
+ case 'checkIn':
return '/overview/bookingsdetails/checkIn';
- case 'contact':
+ case 'contact':
return '/overview/bookingsdetails/contact';
- case 'preregistration':
+ case 'preregistration':
return '/overview/bookingsdetails/preregistration';
- case 'findBooking':
+ case 'findBooking':
return '/overview/findBooking';
- case 'pastCancelledBookings':
+ case 'pastCancelledBookings':
return '/overview/pastCancelledBookings';
- case 'profileSettings':
+ case 'profileSettings':
return '/overview/profile/profileSettings';
// Add more cases as needed
default:
return 'Unknown route';
}
-}
\ No newline at end of file
+}
diff --git a/comwell_key_app/lib/services/api.dart b/comwell_key_app/lib/services/api.dart
index 98c3e254..3a2eb382 100644
--- a/comwell_key_app/lib/services/api.dart
+++ b/comwell_key_app/lib/services/api.dart
@@ -30,6 +30,7 @@ class Api {
Future<BookingsDTO> fetchAllBookingsForUser() async {
final response = await dio.get<Json>('/booking/v1/GetCurrentBookings');
+ print("response in api: $response");
return BookingsDTO.fromJson(response.data!);
}
@@ -57,7 +58,7 @@ class Api {
"x-API-key":
"AQEohmfuXNWTK0Qc+iSTnWkvouiXYIRZCJ9ZsI49DtvZ0d3gjdIA7pissxDBXVsNvuR83LVYjEgiTGAH-4HQnMZXxLZfhge7EdwYZZW0ynntChj41ziiKl6D1Glo=-.\$>;9&L_t@^g7[IR"
};
- final Map<String, dynamic> data = {
+ final Map<String, dynamic> data = {
"shopperReference": "Test reference",
"amount": {"value:": 0, "currency": "DKK"},
"countryCode": "DK",
@@ -101,6 +102,16 @@ class Api {
return response;
}
+ Future<Response<dynamic>> preRegistration(String confirmationId) async {
+ final body = {
+ "confirmationId": confirmationId,
+ };
+ final json = jsonEncode(body);
+
+ final response = await dio.post<dynamic>('/booking/v1/Preregistration', data: json);
+ return response;
+ }
+
// TODO: Remove guestId when backend is updated
Future<Response<dynamic>> getNotificationPermissions(int guestId) async {
final body = {
diff --git a/comwell_key_app/lib/tracking/trackers/firebase_tracker.dart b/comwell_key_app/lib/tracking/trackers/firebase_tracker.dart
index 8c1efab5..b87f1675 100644
--- a/comwell_key_app/lib/tracking/trackers/firebase_tracker.dart
+++ b/comwell_key_app/lib/tracking/trackers/firebase_tracker.dart
@@ -28,6 +28,7 @@ class FirebaseTracker {
}
void _track(String name, Map<String, dynamic>? parameters) async {
+ print("name=$name, parameters=$parameters");
try {
await _tracking.logEvent(
name: name,
diff --git a/comwell_key_app/lib/utils/locator.dart b/comwell_key_app/lib/utils/locator.dart
index 08489893..7c72b707 100644
--- a/comwell_key_app/lib/utils/locator.dart
+++ b/comwell_key_app/lib/utils/locator.dart
@@ -4,7 +4,7 @@ import 'package:comwell_key_app/hotel_information/repository/hotel_information_r
import 'package:comwell_key_app/key/repository/key_repository.dart';
import 'package:comwell_key_app/notifications/notifications_repository.dart';
import 'package:comwell_key_app/overview/repository/overview_repository.dart';
-import 'package:comwell_key_app/payment_cards/pregistration/pregistration_repository.dart';
+import 'package:comwell_key_app/pregistration/pregistration_repository.dart';
import 'package:comwell_key_app/profile/profile_repository.dart';
import 'package:comwell_key_app/profile_settings/repostiory/profile_settings_repository.dart';
import 'package:comwell_key_app/tracking/comwell_tracking.dart';