6177214e-ce7c-49e3-99de-ff9721b26f63 — Commit 93fb3bb4

AuthorMikkel Thygesen<mth@dwarf.dk>
Date2025-01-31 09:53:30 +0100
553: impl restaurant page

Changed files

comwell_key_app/assets/icons/ic_send.svg           |   3 +
 comwell_key_app/assets/images/restaurant_cover.png | Bin 0 -> 247402 bytes
 comwell_key_app/assets/translations/da-DK.json     |   7 +-
 comwell_key_app/assets/translations/en-US.json     |   7 +-
 .../components/contact_hotel_button.dart           |  52 ++++++++++++++
 .../components/hotel_information_menu.dart         |   5 +-
 .../components/restaurant_page.dart                |  78 +++++++++++++++++++--
 .../repository/hotel_information_repository.dart   |  14 ++--
 .../pregistration/bloc/preregistration_cubit.dart  |  33 +++++----
 .../lib/pregistration/components/add_card.dart     |  28 +++++---
 .../pregistration/components/information_card.dart |   7 +-
 comwell_key_app/lib/routing/app_router.dart        |   4 +-
 comwell_key_app/lib/services/api.dart              |  14 +++-
 13 files changed, 205 insertions(+), 47 deletions(-)

Diff

diff --git a/comwell_key_app/assets/icons/ic_send.svg b/comwell_key_app/assets/icons/ic_send.svg
new file mode 100644
index 00000000..17ce30e6
--- /dev/null
+++ b/comwell_key_app/assets/icons/ic_send.svg
@@ -0,0 +1,3 @@
+<svg width="19" height="18" viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M18.59 8.33263L2.08998 0.0826337C1.82582 -0.0494782 1.50871 -0.014244 1.27998 0.172634C1.06188 0.355431 0.966012 0.645924 1.03248 0.922634L3.25248 9.00013L1.00248 17.0551C0.94047 17.2849 0.991168 17.5304 1.1391 17.7168C1.28704 17.9032 1.51466 18.0084 1.75248 18.0001C1.86989 17.9994 1.98549 17.9712 2.08998 17.9176L18.59 9.66763C18.8405 9.53931 18.998 9.28157 18.998 9.00013C18.998 8.7187 18.8405 8.46096 18.59 8.33263ZM2.91498 15.8326L4.57248 9.75013H11.5025V8.25013H4.57248L2.91498 2.16763L16.5725 9.00013L2.91498 15.8326Z" fill="black"/>
+</svg>
diff --git a/comwell_key_app/assets/images/restaurant_cover.png b/comwell_key_app/assets/images/restaurant_cover.png
new file mode 100644
index 00000000..956e90d0
Binary files /dev/null and b/comwell_key_app/assets/images/restaurant_cover.png differ
diff --git a/comwell_key_app/assets/translations/da-DK.json b/comwell_key_app/assets/translations/da-DK.json
index 6d3a4e32..b1a9dca3 100644
--- a/comwell_key_app/assets/translations/da-DK.json
+++ b/comwell_key_app/assets/translations/da-DK.json
@@ -140,5 +140,10 @@
"housekeeping_page_service_cleaning_subtitle": "Der bliver gjort rent mellem 11 og 14",
"housekeeping_page_supplies": "Forsyninger",
"home_page_housekeeping_button_title": "Bestil housekeeping",
- "home_page_housekeeping_button_subtitle": "Ønsker du ekstra rengøring eller opfyldning på værelset, kan du altid bestille det her - uden omkostninger"
+ "home_page_housekeeping_button_subtitle": "Ønsker du ekstra rengøring eller opfyldning på værelset, kan du altid bestille det her - uden omkostninger",
+ "restaurant_page_practical_information": "Praktisk information",
+ "restaurant_page_address": "Adresse",
+ "restaurant_page_opening_hours": "Åbningstider",
+ "restaurant_page_book_table": "Book bord",
+ "restaurant_page_send_email": "Skriv en email"
}
\ No newline at end of file
diff --git a/comwell_key_app/assets/translations/en-US.json b/comwell_key_app/assets/translations/en-US.json
index 3bbd74a4..a936846b 100644
--- a/comwell_key_app/assets/translations/en-US.json
+++ b/comwell_key_app/assets/translations/en-US.json
@@ -141,5 +141,10 @@
"hotel_information_page_menu_parking_title": "Parking",
"hotel_information_page_menu_other_info_title": "More information",
"hotel_information_page_menu_other_info_subtitle": "Find more information",
- "hotel_information_page_spa_button": "Book spa"
+ "hotel_information_page_spa_button": "Book spa",
+ "restaurant_page_practical_information": "Practical information",
+ "restaurant_page_address": "Addrese",
+ "restaurant_page_opening_hours": "Opening hours",
+ "restaurant_page_book_table": "Book table",
+ "restaurant_page_send_email": "Write an email"
}
\ No newline at end of file
diff --git a/comwell_key_app/lib/hotel_information/components/contact_hotel_button.dart b/comwell_key_app/lib/hotel_information/components/contact_hotel_button.dart
new file mode 100644
index 00000000..4d760477
--- /dev/null
+++ b/comwell_key_app/lib/hotel_information/components/contact_hotel_button.dart
@@ -0,0 +1,52 @@
+import 'package:comwell_key_app/themes/light_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+
+class ContactHotelButton extends StatelessWidget {
+ final String title;
+ final String subtitle;
+ final String iconPath;
+ final Function onClick;
+
+ const ContactHotelButton({
+ super.key,
+ required this.title,
+ required this.subtitle,
+ required this.iconPath,
+ required this.onClick,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return InkWell(
+ onTap: () => onClick(),
+ borderRadius: BorderRadius.circular(10),
+ child: Ink(
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(10),
+ border: Border.all(color: colorDivider),
+ ),
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Column(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(title),
+ Text(
+ subtitle,
+ style: Theme.of(context).textTheme.bodySmall,
+ ),
+ ],
+ ),
+ SvgPicture.asset(iconPath)
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/comwell_key_app/lib/hotel_information/components/hotel_information_menu.dart b/comwell_key_app/lib/hotel_information/components/hotel_information_menu.dart
index ebc51765..cb491bfd 100644
--- a/comwell_key_app/lib/hotel_information/components/hotel_information_menu.dart
+++ b/comwell_key_app/lib/hotel_information/components/hotel_information_menu.dart
@@ -1,6 +1,3 @@
-import 'package:comwell_key_app/hotel_information/models/parking_info.dart';
-import 'package:comwell_key_app/hotel_information/models/restaurant.dart';
-import 'package:comwell_key_app/hotel_information/models/spa.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -44,7 +41,7 @@ class HotelInformationMenu extends StatelessWidget {
title: facility.title,
subtitle: facility.subtitle,
onClick: () {
- context.pushNamed("${AppRoutes.hotelInformation.name}/${facility.type}");
+ context.pushNamed("${AppRoutes.hotelInformation.name}/${facility.type}", extra: facility);
},
),
);
diff --git a/comwell_key_app/lib/hotel_information/components/restaurant_page.dart b/comwell_key_app/lib/hotel_information/components/restaurant_page.dart
index 7f2e538f..05baff89 100644
--- a/comwell_key_app/lib/hotel_information/components/restaurant_page.dart
+++ b/comwell_key_app/lib/hotel_information/components/restaurant_page.dart
@@ -1,16 +1,80 @@
+import 'package:comwell_key_app/hotel_information/components/contact_hotel_button.dart';
+import 'package:comwell_key_app/hotel_information/models/restaurant.dart';
+import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
class RestaurantPage extends StatelessWidget {
- const RestaurantPage({super.key});
+ final Restaurant restaurant;
+
+ const RestaurantPage({super.key, required this.restaurant});
@override
Widget build(BuildContext context) {
- return const Scaffold(
- body: Center(
- child: Column(
- children: [Text("Restaurant page")],
- ),
- ),
+ return ListView(
+ children: [
+ Image.asset(restaurant.imageUrl, fit: BoxFit.fitWidth),
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ const SizedBox(height: 26),
+ Text(
+ restaurant.name,
+ style: Theme.of(context).textTheme.headlineLarge,
+ ),
+ const SizedBox(
+ height: 20,
+ ),
+ Text(
+ restaurant.description,
+ style: Theme.of(context).textTheme.bodySmall,
+ ),
+ const SizedBox(height: 40),
+ Text(
+ "restaurant_page_practical_information".tr(),
+ style: Theme.of(context).textTheme.headlineLarge,
+ ),
+ const SizedBox(height: 20),
+ Text(
+ "restaurant_page_address".tr(),
+ style: Theme.of(context).textTheme.headlineMedium,
+ ),
+ Text(
+ restaurant.address,
+ style: Theme.of(context).textTheme.bodySmall,
+ ),
+ const SizedBox(height: 20),
+ Text(
+ "restaurant_page_opening_hours".tr(),
+ style: Theme.of(context).textTheme.headlineMedium,
+ ),
+ Text(
+ restaurant.openingHours,
+ style: Theme.of(context).textTheme.bodySmall,
+ ),
+ const SizedBox(height: 40),
+ Text(
+ "restaurant_page_book_table".tr(),
+ style: Theme.of(context).textTheme.headlineMedium,
+ ),
+ const SizedBox(height: 20),
+ ContactHotelButton(
+ title: "call_us".tr(),
+ subtitle: restaurant.phoneNumber,
+ iconPath: "assets/icons/ic_telephone.svg",
+ onClick: () {}),
+ const SizedBox(height: 6),
+ ContactHotelButton(
+ title: "restaurant_page_send_email".tr(),
+ subtitle: restaurant.email,
+ iconPath: "assets/icons/ic_send.svg",
+ onClick: () {}),
+ const SizedBox(height: 100)
+ ],
+ ),
+ )
+ ],
);
}
}
diff --git a/comwell_key_app/lib/hotel_information/repository/hotel_information_repository.dart b/comwell_key_app/lib/hotel_information/repository/hotel_information_repository.dart
index 7ad14b6a..673a88d1 100644
--- a/comwell_key_app/lib/hotel_information/repository/hotel_information_repository.dart
+++ b/comwell_key_app/lib/hotel_information/repository/hotel_information_repository.dart
@@ -17,19 +17,19 @@ class HotelInformationRepository {
image: 'assets/images/current_room.png',
facilities: [
Restaurant(
- name: 'Restaurant 1',
- subtitle: "Visit",
- description: 'Description 1',
- imageUrl: 'assets/images/restaurant1.jpg',
- address: 'Address 1',
- openingHours: 'Opening Hours 1',
+ name: 'Restaurant Borupgaard',
+ subtitle: "Læs om vores restaurant",
+ description: 'Restaurant Linden på Comwell Borupgaard får du en udsøgt gourmetoplevelse, der er fyldt med både smag og styrke. Restauranten byder på ren idyl og hygge, samt en intim atmosfære med service i særklasse.',
+ imageUrl: 'assets/images/restaurant_cover.png',
+ address: 'Nørrevej 80, 3070 Snekkersten',
+ openingHours: 'Restaurant Linden er åben alle dage kl. 12.00-14.00 og 18.00-22.30 (køkkenet lukket kl. 21.30)',
phoneNumber: '+4528424242',
email: 'email@comwell.com'),
Restaurant(
name: 'Restaurant 2',
subtitle: "Visit",
description: 'Description 1',
- imageUrl: 'assets/images/restaurant1.jpg',
+ imageUrl: 'assets/images/restaurant_cover.png',
address: 'Address 2',
openingHours: 'Opening Hours 2',
phoneNumber: '+4528424242',
diff --git a/comwell_key_app/lib/pregistration/bloc/preregistration_cubit.dart b/comwell_key_app/lib/pregistration/bloc/preregistration_cubit.dart
index 2876a9f4..ab75f65b 100644
--- a/comwell_key_app/lib/pregistration/bloc/preregistration_cubit.dart
+++ b/comwell_key_app/lib/pregistration/bloc/preregistration_cubit.dart
@@ -5,6 +5,7 @@ import 'package:comwell_key_app/pregistration/pregistration_repository.dart';
import 'package:comwell_key_app/pregistration/preregistration_flow.dart';
import 'package:comwell_key_app/services/adyen/adyen_amount.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/tracking/comwell_tracking.dart';
import 'package:comwell_key_app/tracking/models/analytics_event_item.dart';
import 'package:easy_localization/easy_localization.dart';
@@ -17,6 +18,7 @@ class PreregistrationCubit extends Cubit<PreregistrationState> {
final _profileSettingsRepository = locator<ProfileSettingsRepository>();
final _preregistrationRepository = locator<PreregistrationRepository>();
final _tracking = locator<ComwellTracking>();
+ final _api = Api();
final pageController = PageController();
final addressTextController = TextEditingController();
@@ -57,7 +59,7 @@ class PreregistrationCubit extends Cubit<PreregistrationState> {
}
}
- void onAddCardClicked() {}
+ void onAddCardClicked() async {}
void onInformationContinueClicked() {
if (isAddressValid && isPostalCodeValid && isCityValid && isCountryValid) {
@@ -245,28 +247,35 @@ class PreregistrationCubit extends Cubit<PreregistrationState> {
emit(state.copyWith(termsAndConditionsAccepted: toggle));
}
- Checkout advancedCheckout(AdyenAmount amount) {
- return AdvancedCheckout(
- onSubmit: (data, [extra]) async {
- return _preregistrationRepository.onSubmit(amount, data, extra);
- },
- onAdditionalDetails: _preregistrationRepository.onAdditionalDetails,
- );
+ Future<SessionCheckout> advancedCheckout(AdyenAmount amount) async {
+ final response = await _api.createAdyenSession();
+ final id = response["Id"] as String;
+ final sessionData = response["SessionData"] as String;
+ final config = DropInConfiguration(
+ environment: Environment.test,
+ clientKey: "test_BY456IM6H5DRHEVXE7CPJEPGKMUCBRYO",
+ shopperLocale: "da-DK",
+ cardConfiguration: const CardConfiguration(showStorePaymentField: true),
+ countryCode: "DK");
+
+ print("qqq countryCode=${config.countryCode}");
+ return AdyenCheckout.session
+ .create(sessionId: id, sessionData: sessionData, configuration: config);
}
Future<void> onPaymentResult(PaymentResult result) async {
switch (result) {
case PaymentAdvancedFinished():
- print("Payment advanced finished");
+ print("qqq Payment advanced finished");
break;
case PaymentSessionFinished():
- print("Payment session finished");
+ print("qqq Payment session finished");
break;
case PaymentCancelledByUser():
- print("Session cancelled");
+ print("qqq Session cancelled");
break;
case PaymentError():
- print("Session error ${result.reason}");
+ print("qqq Session error ${result.reason}");
break;
}
}
diff --git a/comwell_key_app/lib/pregistration/components/add_card.dart b/comwell_key_app/lib/pregistration/components/add_card.dart
index 2e315a00..d02afce4 100644
--- a/comwell_key_app/lib/pregistration/components/add_card.dart
+++ b/comwell_key_app/lib/pregistration/components/add_card.dart
@@ -6,6 +6,7 @@ import 'package:comwell_key_app/pregistration/models/add_card_payment_method.dar
import 'package:comwell_key_app/services/adyen/adyen_amount.dart';
import 'package:comwell_key_app/themes/light_theme.dart';
import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
@@ -21,6 +22,7 @@ class AddCard extends StatelessWidget {
final cubit = context.read<PreregistrationCubit>();
final paymentMethod =
_extractPaymentMethod(cubit.state.availablePaymentMethods);
+ cubit.onAddCardClicked();
final config = CardComponentConfiguration(
environment: Environment.test,
clientKey: dotenv.env['ADYEN_CLIENT_KEY']!,
@@ -41,16 +43,22 @@ class AddCard extends StatelessWidget {
isScrollControlled: true,
context: context,
builder: (BuildContext context) {
- return SafeArea(
- child: Padding(
- padding: MediaQuery.of(context).viewInsets,
- child: AdyenCardComponent(
- configuration: config,
- paymentMethod: paymentMethodConfig.toJson(),
- checkout: cubit.advancedCheckout(amount),
- onPaymentResult: cubit.onPaymentResult,
- ),
- ));
+ return FutureBuilder(
+ future: cubit.advancedCheckout(amount),
+ builder: (context, snapshot) {
+ if(snapshot.hasError && kDebugMode) print("qqq error=${snapshot.error}");
+ if (!snapshot.hasData) return const CircularProgressIndicator();
+ return SafeArea(
+ child: Padding(
+ padding: MediaQuery.of(context).viewInsets,
+ child: AdyenCardComponent(
+ configuration: config,
+ paymentMethod: paymentMethodConfig.toJson(),
+ checkout: snapshot.data!,
+ onPaymentResult: cubit.onPaymentResult,
+ ),
+ ));
+ });
},
);
cubit.fetchPaymentMethods();
diff --git a/comwell_key_app/lib/pregistration/components/information_card.dart b/comwell_key_app/lib/pregistration/components/information_card.dart
index cfbccf08..3cfbde80 100644
--- a/comwell_key_app/lib/pregistration/components/information_card.dart
+++ b/comwell_key_app/lib/pregistration/components/information_card.dart
@@ -1,3 +1,4 @@
+import 'package:comwell_key_app/themes/dark_theme.dart';
import 'package:flutter/material.dart';
class InformationCard extends StatelessWidget {
@@ -16,9 +17,9 @@ class InformationCard extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(12),
- decoration: const BoxDecoration(
- color: Color(0xFFF9F6F2),
- borderRadius: BorderRadius.all(Radius.circular(10))),
+ decoration: BoxDecoration(
+ color: sandColor[20],
+ borderRadius: const BorderRadius.all(Radius.circular(10))),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
diff --git a/comwell_key_app/lib/routing/app_router.dart b/comwell_key_app/lib/routing/app_router.dart
index 907bc2c0..fca0a4a1 100644
--- a/comwell_key_app/lib/routing/app_router.dart
+++ b/comwell_key_app/lib/routing/app_router.dart
@@ -29,6 +29,7 @@ import 'package:go_router/go_router.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
+import '../hotel_information/models/restaurant.dart';
import '../hotel_information/repository/hotel_information_repository.dart';
import '../utils/locator.dart';
@@ -102,7 +103,8 @@ GoRouter goRouter(AuthenticationBloc authBloc) {
path: "/${AppRoutes.hotelInformation.name}/${AppRoutes.restaurant.name}",
name: "${AppRoutes.hotelInformation.name}/${AppRoutes.restaurant.name}",
builder: (context, state) {
- return const RestaurantPage();
+ final restaurant = state.extra as Restaurant;
+ return RestaurantPage(restaurant: restaurant);
}),
]),
GoRoute(
diff --git a/comwell_key_app/lib/services/api.dart b/comwell_key_app/lib/services/api.dart
index 95bcbeca..ce00a44d 100644
--- a/comwell_key_app/lib/services/api.dart
+++ b/comwell_key_app/lib/services/api.dart
@@ -31,9 +31,21 @@ class Api {
Future<Response<PaymentMethods>> getPaymentMethods() async {
return await dio.get('/paymentMethods');
}
+
+ Future<dynamic> createAdyenSession() async {
+ final body = {
+ "currency": "string",
+ "amount": 0,
+ "returnUrl": "string",
+ "countryCode": "string"
+ };
+ final json = jsonEncode(body);
+ final response = await dio.post<dynamic>("/Payment/v1/CreateAdyenSession", data: json);
+ return response.data;
+ }
Future<Json> postPaymentsDetails(Json body) async {
- final response = await dio.post("/payment/details", data: jsonEncode(body));
+ final response = await dio.post<dynamic>("/payment/details", data: jsonEncode(body));
return response.data as Json;
}