6177214e-ce7c-49e3-99de-ff9721b26f63 — Commit 2659bcb1

AuthorEdmir Suljic<esu@dwarf.dk>
Date2025-06-13 14:08:14 +0200
Mid commit

Changed files

comwell_key_app/assets/translations/da-DK.json     |   4 +-
 comwell_key_app/assets/translations/en-US.json     |   5 +-
 .../up_sales/models/dto/room_facility_dto.g.dart   |   2 +
 comwell_key_app/lib/themes/light_theme.dart        |   2 -
 .../components/facilities_bottom_sheet.dart        | 117 +++++++++
 .../up_sales/components/facility_icon_text.dart    |  20 ++
 .../components/up_sales_bottom_button.dart         |  63 +++++
 .../up_sales/components/up_sales_bottom_sheet.dart |  63 -----
 .../lib/up_sales/mappers/room_facility_mapper.dart |   5 +-
 .../lib/up_sales/models/dto/room_facility_dto.dart |   4 +-
 .../lib/up_sales/models/room_facility.dart         |  18 +-
 .../lib/up_sales/models/room_upgrade.dart          |   4 +-
 .../lib/up_sales/pages/room_upgrade_page.dart      | 229 ++++++------------
 .../lib/up_sales/up_sale_repository.dart           | 261 ++++++++++++++++-----
 comwell_key_app/lib/up_sales/up_sales_catalog.dart |  10 +-
 15 files changed, 516 insertions(+), 291 deletions(-)

Diff

diff --git a/comwell_key_app/assets/translations/da-DK.json b/comwell_key_app/assets/translations/da-DK.json
index 082cdb65..ae4159e7 100644
--- a/comwell_key_app/assets/translations/da-DK.json
+++ b/comwell_key_app/assets/translations/da-DK.json
@@ -228,6 +228,7 @@
"tos_accept_link": "regler og betingelser for Comwell Club",
"newsletter_accept": "Ja tak, jeg vil gerne opdateres på aktuelle medlemstilbud, Comwell Club overraskelser og andre anbefalinger tilpasset mig. Jeg kan til enhver tid afmelde mig igen.",
"read_more": "Læs mere",
+ "read_less": "Læs mindre",
"comwell_club_inactive": "Inaktiv",
"points": "Point",
"my_balance": "Min balance",
@@ -274,5 +275,6 @@
"open_maps_error_title": "Kan ikke åbne kort",
"open_maps_error_subtitle": "Ingen kortprogram er tilgængeligt.",
"apple_maps": "Apple Kort",
- "google_maps": "Google Kort"
+ "google_maps": "Google Kort",
+ "add_to_booking": "Tilføj til booking"
}
\ 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 99dc0b71..73a33f99 100644
--- a/comwell_key_app/assets/translations/en-US.json
+++ b/comwell_key_app/assets/translations/en-US.json
@@ -227,6 +227,7 @@
"tos_accept_link": "terms and conditions for Comwell Club",
"newsletter_accept": "Yes, I would like to receive updates on current member offers, Comwell Club surprises and other recommendations tailored to me. I can unsubscribe at any time.",
"read_more": "Read more",
+ "read_less": "Read less",
"comwell_club_inactive": "Inactive",
"points": "Points",
"my_balance": "My balance",
@@ -273,5 +274,7 @@
"open_maps_error_title": "Cannot open maps",
"open_maps_error_subtitle": "No maps application is available.",
"apple_maps": "Apple Maps",
- "google_maps": "Google Maps"
+ "google_maps": "Google Maps",
+ "add_to_booking": "Add to booking"
+
}
diff --git a/comwell_key_app/lib/.generated/up_sales/models/dto/room_facility_dto.g.dart b/comwell_key_app/lib/.generated/up_sales/models/dto/room_facility_dto.g.dart
index 8f4cb7fc..b31829b2 100644
--- a/comwell_key_app/lib/.generated/up_sales/models/dto/room_facility_dto.g.dart
+++ b/comwell_key_app/lib/.generated/up_sales/models/dto/room_facility_dto.g.dart
@@ -9,10 +9,12 @@ part of '../../../../up_sales/models/dto/room_facility_dto.dart';
RoomFacilityDTO _$RoomFacilityDTOFromJson(Map json) => RoomFacilityDTO(
name: json['name'] as String,
icon: json['icon'] as String,
+ facilityType: json['facilityType'] as String,
);
Map<String, dynamic> _$RoomFacilityDTOToJson(RoomFacilityDTO instance) =>
<String, dynamic>{
'name': instance.name,
'icon': instance.icon,
+ 'facilityType': instance.facilityType,
};
diff --git a/comwell_key_app/lib/themes/light_theme.dart b/comwell_key_app/lib/themes/light_theme.dart
index 6a2edf58..0fce1cd0 100644
--- a/comwell_key_app/lib/themes/light_theme.dart
+++ b/comwell_key_app/lib/themes/light_theme.dart
@@ -42,7 +42,6 @@ ThemeData lightTheme = ThemeData(
surfaceTint: colorHeadlineText),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
- elevation: 0,
backgroundColor: sandColor[80],
minimumSize: const Size(100, 52),
textStyle: const TextStyle(
@@ -72,7 +71,6 @@ const colorShadow = Color(0xFF000000);
const colorDivider = Color(0xFFE0E0E0);
const disabledButtonColor = Color(0xFFF0F0F0);
final colorHeadlineText = colorPrimaryText.withValues(alpha: 0.65);
-
const colorBlack = MaterialColor(0xFF000000, {
75: Color(0xB3000000),
65: Color(0xA6000000),
diff --git a/comwell_key_app/lib/up_sales/components/facilities_bottom_sheet.dart b/comwell_key_app/lib/up_sales/components/facilities_bottom_sheet.dart
new file mode 100644
index 00000000..4d51d284
--- /dev/null
+++ b/comwell_key_app/lib/up_sales/components/facilities_bottom_sheet.dart
@@ -0,0 +1,117 @@
+import 'package:comwell_key_app/common/const.dart';
+import 'package:comwell_key_app/themes/light_theme.dart';
+import 'package:comwell_key_app/up_sales/components/facility_icon_text.dart';
+import 'package:comwell_key_app/up_sales/models/room_facility.dart';
+import 'package:comwell_key_app/up_sales/components/tags.dart';
+import 'package:flutter/material.dart';
+
+class FacilitiesBottomSheet extends StatelessWidget {
+ final List<RoomFacility> facilities;
+ const FacilitiesBottomSheet({required this.facilities});
+
+ @override
+ Widget build(BuildContext context) {
+ final height = MediaQuery.of(context).size.height;
+ final theme = Theme.of(context);
+ // Group facilities for display (mocked for now)
+ final Map<String, List<RoomFacility>> grouped = {
+ 'SENGETYPER':
+ facilities.where((f) => f.facilityType == FacilityType.bed).toList(),
+ 'ELEKTRONIK': facilities
+ .where((f) => f.facilityType == FacilityType.electronics)
+ .toList(),
+ 'BADEVÆRELSE': facilities
+ .where((f) => f.facilityType == FacilityType.bathroom)
+ .toList(),
+ 'BUSINESS': facilities
+ .where((f) => f.facilityType == FacilityType.business)
+ .toList(),
+ 'SERVICE': facilities
+ .where((f) => f.facilityType == FacilityType.service)
+ .toList(),
+ 'VÆRELSESFACILITETER':
+ facilities.where((f) => f.facilityType == FacilityType.room).toList(),
+ };
+ print("grouped ${grouped}");
+ return DraggableScrollableSheet(
+ initialChildSize: (height - kComwellAppBarHeight) / height,
+ expand: false,
+ minChildSize: 0.0,
+ maxChildSize: (height - kComwellAppBarHeight) / height,
+ snap: true,
+ builder: (context, scrollController) => Container(
+ padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
+ decoration: const BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
+ ),
+ child: ListView(
+ controller: scrollController,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text('Faciliteter',
+ style: theme.textTheme.headlineMedium
+ ?.copyWith(fontWeight: FontWeight.bold)),
+ IconButton(
+ icon: const Icon(
+ Icons.close,
+ size: 24,
+ ),
+ style: IconButton.styleFrom(
+ backgroundColor: sandColor[40],
+ ),
+ onPressed: () => Navigator.of(context).pop(),
+ ),
+ ],
+ ),
+ const SizedBox(height: 12),
+ ...grouped.entries.map((entry) => Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(entry.key,
+ style: theme.textTheme.bodySmall?.copyWith(
+ fontWeight: FontWeight.bold,
+ color: colorHeadlineText)),
+ const SizedBox(height: 8),
+ Wrap(
+ direction: entry.key == 'SENGETYPER'
+ ? Axis.horizontal
+ : Axis.vertical,
+ spacing: 16,
+ runSpacing: 8,
+ children: entry.key == 'SENGETYPER'
+ ? entry.value
+ .map((f) => Container(
+ width: 175,
+ height: 56,
+ decoration: BoxDecoration(
+ border: Border.all(
+ color: colorDivider,
+ ),
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: Center(
+ child: FacilityIconText(facility: f)),
+ ))
+ .toList()
+ : entry.value
+ .map((f) => FacilityIconText(facility: f))
+ .toList(),
+ ),
+ const SizedBox(height: 16),
+ if (entry.key != 'SENGETYPER')
+ const Divider(
+ color: colorDivider,
+ height: 0,
+ ),
+ const SizedBox(height: 24),
+ ],
+ )),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/comwell_key_app/lib/up_sales/components/facility_icon_text.dart b/comwell_key_app/lib/up_sales/components/facility_icon_text.dart
new file mode 100644
index 00000000..459021ed
--- /dev/null
+++ b/comwell_key_app/lib/up_sales/components/facility_icon_text.dart
@@ -0,0 +1,20 @@
+import 'package:comwell_key_app/up_sales/models/room_facility.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+
+class FacilityIconText extends StatelessWidget {
+ final RoomFacility facility;
+ const FacilityIconText({super.key, required this.facility});
+
+ @override
+ Widget build(BuildContext context) {
+ return Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ SvgPicture.asset(facility.icon, width: 20, height: 20),
+ const SizedBox(width: 4),
+ Text(facility.name, style: Theme.of(context).textTheme.bodySmall),
+ ],
+ );
+ }
+}
diff --git a/comwell_key_app/lib/up_sales/components/up_sales_bottom_button.dart b/comwell_key_app/lib/up_sales/components/up_sales_bottom_button.dart
new file mode 100644
index 00000000..9c6c606f
--- /dev/null
+++ b/comwell_key_app/lib/up_sales/components/up_sales_bottom_button.dart
@@ -0,0 +1,63 @@
+import 'package:comwell_key_app/themes/light_theme.dart';
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
+
+class UpSalesBottomButton extends StatelessWidget {
+ final List<Widget> children;
+ final VoidCallback? onContinue;
+
+ const UpSalesBottomButton({
+ super.key,
+ this.onContinue,
+ required this.children,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ final theme = Theme.of(context);
+ return Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const Divider(
+ color: colorDivider,
+ height: 0,
+ ),
+ Row(
+ children: [
+ Expanded(
+ child: Container(
+ color: Colors.white,
+ child: Padding(
+ padding: const EdgeInsets.only(
+ left: 16.0,
+ right: 16.0,
+ top: 16.0,
+ bottom: 40,
+ ),
+ child: ElevatedButton(
+ onPressed: onContinue,
+ style: ButtonStyle(
+ elevation: WidgetStateProperty.all(0),
+ backgroundColor: WidgetStateProperty.resolveWith((states) {
+
+ return sandColor[80];
+ }),
+ foregroundColor: const WidgetStatePropertyAll(Colors.white),
+ ),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(vertical: 16.0),
+ child: Row(
+ mainAxisAlignment: children.length > 1 ? MainAxisAlignment.spaceBetween : MainAxisAlignment.center,
+ children: children,
+ )
+ ),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ],
+ );
+ }
+}
\ No newline at end of file
diff --git a/comwell_key_app/lib/up_sales/components/up_sales_bottom_sheet.dart b/comwell_key_app/lib/up_sales/components/up_sales_bottom_sheet.dart
deleted file mode 100644
index 216a783e..00000000
--- a/comwell_key_app/lib/up_sales/components/up_sales_bottom_sheet.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-import 'package:comwell_key_app/themes/light_theme.dart';
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/material.dart';
-
-class UpSalesBottomSheet extends StatelessWidget {
- final VoidCallback? onContinue;
-
- const UpSalesBottomSheet({
- super.key,
- this.onContinue,
- });
-
- @override
- Widget build(BuildContext context) {
- final theme = Theme.of(context);
- return Column(
- mainAxisSize: MainAxisSize.min,
- children: [
- const Divider(
- color: colorDivider,
- height: 0,
- ),
- Row(
- children: [
- Expanded(
- child: Container(
- color: Colors.white,
- child: Padding(
- padding: const EdgeInsets.only(
- left: 16.0,
- right: 16.0,
- top: 16.0,
- bottom: 40,
- ),
- child: ElevatedButton(
- onPressed: onContinue,
- style: ButtonStyle(
- elevation: WidgetStateProperty.all(0),
- backgroundColor: WidgetStateProperty.resolveWith((states) {
-
- return sandColor[80];
- }),
- foregroundColor: const WidgetStatePropertyAll(Colors.white),
- ),
- child: Padding(
- padding: const EdgeInsets.symmetric(vertical: 16.0),
- child: Text(
- "continue_without_up_sales".tr(),
- style: theme.textTheme.headlineSmall?.copyWith(
- color: Colors.white,
- ),
- ),
- ),
- ),
- ),
- ),
- ),
- ],
- ),
- ],
- );
- }
-}
\ No newline at end of file
diff --git a/comwell_key_app/lib/up_sales/mappers/room_facility_mapper.dart b/comwell_key_app/lib/up_sales/mappers/room_facility_mapper.dart
index b39aa222..bcb2fdd9 100644
--- a/comwell_key_app/lib/up_sales/mappers/room_facility_mapper.dart
+++ b/comwell_key_app/lib/up_sales/mappers/room_facility_mapper.dart
@@ -3,11 +3,12 @@ import 'package:comwell_key_app/up_sales/models/room_facility.dart';
extension RoomFacilityDTOMapper on RoomFacilityDTO {
RoomFacility toRoomFacility() {
- return RoomFacility(name: name, icon: icon);
+ return RoomFacility(name: name, icon: icon, facilityType: FacilityType.fromString(facilityType));
}
}
extension ListRoomFacilityMapper on Iterable<RoomFacilityDTO> {
Iterable<RoomFacility> toRoomFacilities() =>
map((dto) => dto.toRoomFacility());
-}
\ No newline at end of file
+}
+
diff --git a/comwell_key_app/lib/up_sales/models/dto/room_facility_dto.dart b/comwell_key_app/lib/up_sales/models/dto/room_facility_dto.dart
index 917927f0..a743407c 100644
--- a/comwell_key_app/lib/up_sales/models/dto/room_facility_dto.dart
+++ b/comwell_key_app/lib/up_sales/models/dto/room_facility_dto.dart
@@ -7,8 +7,10 @@ part '../../../.generated/up_sales/models/dto/room_facility_dto.g.dart';
class RoomFacilityDTO {
final String name;
final String icon;
+ final String facilityType;
- RoomFacilityDTO({required this.name, required this.icon});
+
+ RoomFacilityDTO({required this.name, required this.icon, required this.facilityType});
Json toJson() => _$RoomFacilityDTOToJson(this);
diff --git a/comwell_key_app/lib/up_sales/models/room_facility.dart b/comwell_key_app/lib/up_sales/models/room_facility.dart
index 156fa5a2..a3ecef3b 100644
--- a/comwell_key_app/lib/up_sales/models/room_facility.dart
+++ b/comwell_key_app/lib/up_sales/models/room_facility.dart
@@ -1,12 +1,26 @@
class RoomFacility {
final String name;
final String icon;
-
- RoomFacility({required this.name, required this.icon});
+ final FacilityType facilityType;
+ RoomFacility({required this.name, required this.icon, required this.facilityType});
@override
String toString() {
return 'RoomFacility(name: $name, icon: $icon)';
}
+
+}
+
+enum FacilityType {
+ bed,
+ electronics,
+ bathroom,
+ business,
+ service,
+ room;
+
+ static FacilityType fromString(String value) {
+ return FacilityType.values.firstWhere((e) => e.name == value.toLowerCase());
+ }
}
\ No newline at end of file
diff --git a/comwell_key_app/lib/up_sales/models/room_upgrade.dart b/comwell_key_app/lib/up_sales/models/room_upgrade.dart
index 888a5935..a3b5a047 100644
--- a/comwell_key_app/lib/up_sales/models/room_upgrade.dart
+++ b/comwell_key_app/lib/up_sales/models/room_upgrade.dart
@@ -43,12 +43,12 @@ class RoomUpgrade {
@override
String toString() {
- return "RoomUpgrade(name: $name, price: $price, images: $images, description: $description, id: $id, tags: $tags, facilities: $facilities)";
+ return "RoomUpgrade(name: $name, price: $price, images: $images, description: $description, id: $id, tags: $tags, facilities: $facilities, type: $type)";
}
@override
List<Object?> get props =>
- [name, price, images, description, id, tags, facilities];
+ [name, price, images, description, id, tags, facilities, type];
}
enum UpgradeType {
diff --git a/comwell_key_app/lib/up_sales/pages/room_upgrade_page.dart b/comwell_key_app/lib/up_sales/pages/room_upgrade_page.dart
index b290172d..82eca889 100644
--- a/comwell_key_app/lib/up_sales/pages/room_upgrade_page.dart
+++ b/comwell_key_app/lib/up_sales/pages/room_upgrade_page.dart
@@ -1,50 +1,51 @@
import 'package:comwell_key_app/common/components/comwell_app_bar.dart';
+import 'package:comwell_key_app/common/const.dart';
+import 'package:comwell_key_app/themes/light_theme.dart';
+import 'package:comwell_key_app/up_sales/components/facilities_bottom_sheet.dart';
+import 'package:comwell_key_app/up_sales/components/facility_icon_text.dart';
+import 'package:comwell_key_app/up_sales/components/up_sales_bottom_button.dart';
+import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:comwell_key_app/up_sales/models/room_upgrade.dart';
import 'package:comwell_key_app/up_sales/models/room_facility.dart';
import 'package:comwell_key_app/up_sales/components/tags.dart';
import 'package:flutter_svg/svg.dart';
-class RoomUpgradePage extends StatelessWidget {
+class RoomUpgradePage extends StatefulWidget {
final RoomUpgrade roomUpgrade;
const RoomUpgradePage({super.key, required this.roomUpgrade});
+ @override
+ State<RoomUpgradePage> createState() => _RoomUpgradePageState();
+}
+
+class _RoomUpgradePageState extends State<RoomUpgradePage> {
+ bool _isExpanded = false;
+
List<RoomFacility> get allFacilities => [
- ...roomUpgrade.facilities,
+ ...widget.roomUpgrade.facilities,
// Optionally add more facilities if needed, or fetch from a global list
];
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
+ final height = MediaQuery.of(context).size.height;
+
return Scaffold(
+ extendBodyBehindAppBar: true,
appBar: const ComwellAppBar(),
backgroundColor: const Color(0xFFF2F2F2),
body: Column(
children: [
- // Image and back button
- Stack(
- children: [
- SizedBox(
- width: double.infinity,
- height: 260,
- child: Image.asset(
- roomUpgrade.images.first,
- fit: BoxFit.cover,
- ),
- ),
- Positioned(
- top: 16,
- left: 16,
- child: CircleAvatar(
- backgroundColor: Colors.white,
- child: IconButton(
- icon: const Icon(Icons.arrow_back),
- onPressed: () => Navigator.of(context).pop(),
- ),
- ),
- ),
- ],
+ //TODO: Change to ImageWidget when we have the image url
+ SizedBox(
+ width: double.infinity,
+ height: height * 0.5,
+ child: Image.asset(
+ widget.roomUpgrade.images.first,
+ fit: BoxFit.cover,
+ ),
),
Expanded(
child: Container(
@@ -57,56 +58,68 @@ class RoomUpgradePage extends StatelessWidget {
),
),
child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
+ padding:
+ const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
- roomUpgrade.name,
- style: theme.textTheme.headlineMedium?.copyWith(fontWeight: FontWeight.bold),
+ widget.roomUpgrade.name,
+ style: theme.textTheme.headlineLarge,
),
const SizedBox(width: 12),
- if (roomUpgrade.tags.isNotEmpty)
- TagWidget(text: '${roomUpgrade.tags.first} M2', textColor: const Color(0xFFD1B48C)),
+ if (widget.roomUpgrade.tags.isNotEmpty)
+ TagWidget(
+ text: '${widget.roomUpgrade.tags.first} M2',
+ textColor: sandColor),
],
),
const SizedBox(height: 12),
Text(
- roomUpgrade.description,
- style: theme.textTheme.bodyMedium,
- maxLines: 3,
- overflow: TextOverflow.ellipsis,
+ widget.roomUpgrade.description,
+ style: theme.textTheme.bodySmall,
+ maxLines: _isExpanded ? null : 3,
+ overflow: _isExpanded ? null : TextOverflow.ellipsis,
),
const SizedBox(height: 4),
GestureDetector(
- onTap: () {},
+ onTap: () {
+ setState(() {
+ _isExpanded = !_isExpanded;
+ });
+ },
child: Text(
- 'Læs mere',
- style: theme.textTheme.bodyMedium?.copyWith(
- color: const Color(0xFFD1B48C),
+ _isExpanded ? 'read_less'.tr() : 'read_more'.tr(),
+ style: theme.textTheme.bodySmall?.copyWith(
+ color: sandColor,
decoration: TextDecoration.underline,
+ decorationColor: sandColor,
),
),
),
- const SizedBox(height: 16),
+ const SizedBox(height: 24),
// Facilities row
Wrap(
spacing: 16,
runSpacing: 8,
children: [
- ...roomUpgrade.facilities.map((f) => _FacilityIconText(facility: f)),
+ ...widget.roomUpgrade.facilities
+ .map((f) => FacilityIconText(facility: f)),
GestureDetector(
onTap: () => _showFacilitiesSheet(context),
child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 4.0),
+ padding:
+ const EdgeInsets.symmetric(horizontal: 4.0),
child: Text(
'Se alle faciliteter',
- style: theme.textTheme.bodyMedium?.copyWith(
- color: const Color(0xFFD1B48C),
+ style: theme.textTheme.bodySmall?.copyWith(
+ color: sandColor,
decoration: TextDecoration.underline,
+ decorationColor: sandColor,
),
),
),
@@ -121,44 +134,18 @@ class RoomUpgradePage extends StatelessWidget {
),
),
// Booking button
- Container(
- color: const Color(0xFFF2F2F2),
- padding: const EdgeInsets.all(16),
- child: Row(
- children: [
- Expanded(
- child: ElevatedButton(
- style: ElevatedButton.styleFrom(
- backgroundColor: const Color(0xFFD1B48C),
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(32),
- ),
- padding: const EdgeInsets.symmetric(vertical: 18),
- ),
- onPressed: () {},
- child: const Text(
- 'Tilføj til booking',
- style: TextStyle(fontSize: 18, color: Colors.white),
- ),
- ),
- ),
- const SizedBox(width: 12),
- Container(
- padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 16),
- decoration: BoxDecoration(
- color: const Color(0xFFD1B48C),
- borderRadius: BorderRadius.circular(32),
- ),
- child: Text(
- '+${roomUpgrade.price} kr.',
- style: const TextStyle(fontSize: 18, color: Colors.white),
- ),
- ),
- ],
- ),
- ),
],
),
+ bottomSheet: UpSalesBottomButton(onContinue: () {}, children: [
+ Text(
+ "add_to_booking".tr(),
+ style: theme.textTheme.headlineSmall?.copyWith(color: Colors.white),
+ ),
+ Text(
+ "+${widget.roomUpgrade.price} kr.",
+ style: theme.textTheme.headlineSmall?.copyWith(color: Colors.white),
+ ),
+ ]),
);
}
@@ -169,89 +156,7 @@ class RoomUpgradePage extends StatelessWidget {
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
),
- builder: (context) => _FacilitiesBottomSheet(facilities: allFacilities),
- );
- }
-}
-
-class _FacilityIconText extends StatelessWidget {
- final RoomFacility facility;
- const _FacilityIconText({required this.facility});
-
- @override
- Widget build(BuildContext context) {
- return Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- SvgPicture.asset(facility.icon, width: 20, height: 20),
- const SizedBox(width: 4),
- Text(facility.name, style: Theme.of(context).textTheme.bodyMedium),
- ],
+ builder: (context) => FacilitiesBottomSheet(facilities: allFacilities),
);
}
}
-
-class _FacilitiesBottomSheet extends StatelessWidget {
- final List<RoomFacility> facilities;
- const _FacilitiesBottomSheet({required this.facilities});
-
- @override
- Widget build(BuildContext context) {
- final theme = Theme.of(context);
- // Group facilities for display (mocked for now)
- final Map<String, List<RoomFacility>> grouped = {
- 'SENGETYPER': facilities.where((f) => f.name.contains('seng')).toList(),
- 'ELEKTRONIK': facilities.where((f) => f.name == 'TV' || f.name == 'Gratis WiFi').toList(),
- 'BADEVÆRELSE': facilities.where((f) => f.name == 'Hårtørrer' || f.name == 'Badekar').toList(),
- 'BUSINESS': facilities.where((f) => f.name == 'Arbejdsplads').toList(),
- 'SERVICE': facilities.where((f) => f.name == 'Roomservice').toList(),
- 'VÆRELSESFACILITETER': facilities.where((f) => [
- 'Strygejern & -bræt', 'Terrasse', 'Te-køkken', 'Stue', 'Minibar'
- ].contains(f.name)).toList(),
- };
- return DraggableScrollableSheet(
- expand: false,
- initialChildSize: 0.7,
- minChildSize: 0.4,
- maxChildSize: 0.95,
- builder: (context, scrollController) => Container(
- padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
- decoration: const BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
- ),
- child: ListView(
- controller: scrollController,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text('Faciliteter', style: theme.textTheme.headlineMedium?.copyWith(fontWeight: FontWeight.bold)),
- IconButton(
- icon: const Icon(Icons.close),
- onPressed: () => Navigator.of(context).pop(),
- ),
- ],
- ),
- const SizedBox(height: 12),
- ...grouped.entries.map((entry) => Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(entry.key, style: theme.textTheme.bodySmall?.copyWith(fontWeight: FontWeight.bold, color: Colors.black54)),
- const SizedBox(height: 8),
- Wrap(
- spacing: 16,
- runSpacing: 8,
- children: entry.value
- .map((f) => _FacilityIconText(facility: f))
- .toList(),
- ),
- const SizedBox(height: 16),
- ],
- )),
- ],
- ),
- ),
- );
- }
-}
\ No newline at end of file
diff --git a/comwell_key_app/lib/up_sales/up_sale_repository.dart b/comwell_key_app/lib/up_sales/up_sale_repository.dart
index 5039f08f..2595d8db 100644
--- a/comwell_key_app/lib/up_sales/up_sale_repository.dart
+++ b/comwell_key_app/lib/up_sales/up_sale_repository.dart
@@ -26,103 +26,256 @@ final List<RoomUpgradeDTO> mockRoomUpgrades = [
name: 'Standard Double Room',
price: '1200',
images: ['assets/images/welcome_image.jpeg'],
- description: 'A cozy room with a double bed, perfect for couples or solo travelers seeking comfort and convenience.',
+ description:
+ 'A cozy room with a double bed, perfect for couples or solo travelers seeking comfort and convenience. A cozy room with a double bed, perfect for couples or solo travelers seeking comfort and convenience. A cozy room with a double bed, perfect for couples or solo travelers seeking comfort and convenience.',
id: '1',
tags: ['20'],
type: 'room',
facilities: [
- RoomFacilityDTO(name: 'TV', icon: 'assets/icons/ic_tv.svg'),
- RoomFacilityDTO(name: 'Gratis WiFi', icon: 'assets/icons/ic_wifi.svg'),
- RoomFacilityDTO(name: 'Hårtørrer', icon: 'assets/icons/ic_hairdryer.svg'),
- RoomFacilityDTO(name: 'Arbejdsplads', icon: 'assets/icons/ic_desk.svg'),
- RoomFacilityDTO(name: 'Roomservice', icon: 'assets/icons/ic_service_bowl.svg'),
- RoomFacilityDTO(name: 'Strygejern & -bræt', icon: 'assets/icons/ic_iron.svg'),
- RoomFacilityDTO(name: 'Minibar', icon: 'assets/icons/ic_minibar.svg'),
+ RoomFacilityDTO(
+ name: '1x enkelseng',
+ icon: 'assets/icons/ic_single_bed.svg',
+ facilityType: 'Bed'),
+ RoomFacilityDTO(
+ name: '1x dobbelseng',
+ icon: 'assets/icons/ic_double_bed.svg',
+ facilityType: 'Bed'),
+ RoomFacilityDTO(
+ name: 'TV',
+ icon: 'assets/icons/ic_tv.svg',
+ facilityType: 'Electronics'),
+ RoomFacilityDTO(
+ name: 'Gratis WiFi',
+ icon: 'assets/icons/ic_wifi.svg',
+ facilityType: 'Electronics'),
+ RoomFacilityDTO(
+ name: 'Hårtørrer',
+ icon: 'assets/icons/ic_hairdryer.svg',
+ facilityType: 'Bathroom'),
+ RoomFacilityDTO(
+ name: 'Arbejdsplads',
+ icon: 'assets/icons/ic_desk.svg',
+ facilityType: 'Business'),
+ RoomFacilityDTO(
+ name: 'Roomservice',
+ icon: 'assets/icons/ic_service_bowl.svg',
+ facilityType: 'Service'),
+ RoomFacilityDTO(
+ name: 'Strygejern & -bræt',
+ icon: 'assets/icons/ic_iron.svg',
+ facilityType: 'Room'),
+ RoomFacilityDTO(
+ name: 'Minibar',
+ icon: 'assets/icons/ic_minibar.svg',
+ facilityType: 'Room'),
],
),
RoomUpgradeDTO(
name: 'Junior Suite',
price: '1800',
images: ['assets/images/no_current_bookings_background.jpeg'],
- description: 'Spacious Junior Suite with a separate living area, ideal for guests who appreciate extra space and luxury.',
+ description:
+ 'Spacious Junior Suite with a separate living area, ideal for guests who appreciate extra space and luxury. Spacious Junior Suite with a separate living area, ideal for guests who appreciate extra space and luxury. Spacious Junior Suite with a separate living area, ideal for guests who appreciate extra space and luxury.',
id: '2',
tags: ['35'],
type: 'room',
facilities: [
- RoomFacilityDTO(name: 'TV', icon: 'assets/icons/ic_tv'),
- RoomFacilityDTO(name: 'Gratis WiFi', icon: 'assets/icons/ic_wifi'),
- RoomFacilityDTO(name: 'Hårtørrer', icon: 'assets/icons/ic_hairdryer'),
- RoomFacilityDTO(name: 'Badekar', icon: 'assets/icons/ic_bathtub'),
- RoomFacilityDTO(name: 'Arbejdsplads', icon: 'assets/icons/ic_desk'),
- RoomFacilityDTO(name: 'Roomservice', icon: 'assets/icons/ic_service_bowl'),
- RoomFacilityDTO(name: 'Strygejern & -bræt', icon: 'assets/icons/ic_iron'),
- RoomFacilityDTO(name: 'Terrasse', icon: 'assets/icons/ic_terrace'),
- RoomFacilityDTO(name: 'Te-køkken', icon: 'assets/icons/kettle'),
- RoomFacilityDTO(name: 'Stue', icon: 'assets/icons/ic_livingroom'),
- RoomFacilityDTO(name: 'Minibar', icon: 'assets/icons/ic_minibar'),
+ RoomFacilityDTO(
+ name: '1x enkelseng',
+ icon: 'assets/icons/ic_single_bed.svg',
+ facilityType: 'Bed'),
+ RoomFacilityDTO(
+ name: '2x dobbelseng',
+ icon: 'assets/icons/ic_double_bed.svg',
+ facilityType: 'Bed'),
+ RoomFacilityDTO(
+ name: 'TV',
+ icon: 'assets/icons/ic_tv.svg',
+ facilityType: 'Electronics'),
+ RoomFacilityDTO(
+ name: 'Gratis WiFi',
+ icon: 'assets/icons/ic_wifi.svg',
+ facilityType: 'Electronics'),
+ RoomFacilityDTO(
+ name: 'Hårtørrer',
+ icon: 'assets/icons/ic_hairdryer.svg',
+ facilityType: 'Bathroom'),
+ RoomFacilityDTO(
+ name: 'Badekar',
+ icon: 'assets/icons/ic_bathtub.svg',
+ facilityType: 'Bathroom'),
+ RoomFacilityDTO(
+ name: 'Arbejdsplads',
+ icon: 'assets/icons/ic_desk.svg',
+ facilityType: 'Business'),
+ RoomFacilityDTO(
+ name: 'Roomservice',
+ icon: 'assets/icons/ic_service_bowl.svg',
+ facilityType: 'Service'),
+ RoomFacilityDTO(
+ name: 'Strygejern & -bræt',
+ icon: 'assets/icons/ic_iron.svg',
+ facilityType: 'Room'),
+ RoomFacilityDTO(
+ name: 'Terrasse',
+ icon: 'assets/icons/ic_balcony.svg',
+ facilityType: 'Room'),
+ RoomFacilityDTO(
+ name: 'Te-køkken',
+ icon: 'assets/icons/ic_kettle.svg',
+ facilityType: 'Room'),
+ RoomFacilityDTO(
+ name: 'Stue',
+ icon: 'assets/icons/ic_leather_chair.svg',
+ facilityType: 'Room'),
+ RoomFacilityDTO(
+ name: 'Minibar',
+ icon: 'assets/icons/ic_minibar.svg',
+ facilityType: 'Room'),
],
),
RoomUpgradeDTO(
name: 'Suite',
price: '2500',
images: ['assets/images/current_room.png'],
- description: 'Our most luxurious suite, featuring a large living room, private terrace, and premium amenities for a memorable stay.',
+ description:
+ 'Our most luxurious suite, featuring a large living room, private terrace, and premium amenities for a memorable stay. Our most luxurious suite, featuring a large living room, private terrace, and premium amenities for a memorable stay. Our most luxurious suite, featuring a large living room, private terrace, and premium amenities for a memorable stay.',
id: '3',
tags: ['50'],
type: 'room',
facilities: [
- RoomFacilityDTO(name: 'TV', icon: 'assets/icons/ic_tv.svg'),
- RoomFacilityDTO(name: 'Gratis WiFi', icon: 'assets/icons/ic_wifi.svg'),
- RoomFacilityDTO(name: 'Hårtørrer', icon: 'assets/icons/ic_hairdryer.svg'),
- RoomFacilityDTO(name: 'Badekar', icon: 'assets/icons/ic_bathtub.svg'),
- RoomFacilityDTO(name: 'Arbejdsplads', icon: 'assets/icons/ic_desk.svg'),
- RoomFacilityDTO(name: 'Roomservice', icon: 'assets/icons/ic_service_bowl.svg'),
- RoomFacilityDTO(name: 'Strygejern & -bræt', icon: 'assets/icons/ic_iron.svg'),
- RoomFacilityDTO(name: 'Terrasse', icon: 'assets/icons/ic_terrace.svg'),
- RoomFacilityDTO(name: 'Te-køkken', icon: 'assets/icons/ic_kitchenette.svg'),
- RoomFacilityDTO(name: 'Stue', icon: 'assets/icons/ic_livingroom.svg'),
- RoomFacilityDTO(name: 'Minibar', icon: 'assets/icons/ic_minibar.svg'),
+ RoomFacilityDTO(
+ name: '1x enkelseng',
+ icon: 'assets/icons/ic_single_bed.svg',
+ facilityType: 'Bed'),
+ RoomFacilityDTO(
+ name: 'TV',
+ icon: 'assets/icons/ic_tv.svg',
+ facilityType: 'Electronics'),
+ RoomFacilityDTO(
+ name: 'Gratis WiFi',
+ icon: 'assets/icons/ic_wifi.svg',
+ facilityType: 'Electronics'),
+ RoomFacilityDTO(
+ name: 'Hårtørrer',
+ icon: 'assets/icons/ic_hairdryer.svg',
+ facilityType: 'Bathroom'),
+ RoomFacilityDTO(
+ name: 'Badekar',
+ icon: 'assets/icons/ic_bathtub.svg',
+ facilityType: 'Bathroom'),
+ RoomFacilityDTO(
+ name: 'Arbejdsplads',
+ icon: 'assets/icons/ic_desk.svg',
+ facilityType: 'Business'),
+ RoomFacilityDTO(
+ name: 'Roomservice',
+ icon: 'assets/icons/ic_service_bowl.svg',
+ facilityType: 'Service'),
+ RoomFacilityDTO(
+ name: 'Strygejern & -bræt',
+ icon: 'assets/icons/ic_iron.svg',
+ facilityType: 'Room'),
+ RoomFacilityDTO(
+ name: 'Terrasse',
+ icon: 'assets/icons/ic_balcony.svg',
+ facilityType: 'Room'),
+ RoomFacilityDTO(
+ name: 'Te-køkken',
+ icon: 'assets/icons/ic_kettle.svg',
+ facilityType: 'Room'),
+ RoomFacilityDTO(
+ name: 'Stue',
+ icon: 'assets/icons/ic_leather_chair.svg',
+ facilityType: 'Room'),
+ RoomFacilityDTO(
+ name: 'Minibar',
+ icon: 'assets/icons/ic_minibar.svg',
+ facilityType: 'Room'),
],
),
RoomUpgradeDTO(
name: 'Standard Double Plus Room',
price: '1400',
images: ['assets/images/login_screen_background.png'],
- description: 'An upgraded double room with extra amenities and a modern touch, perfect for a relaxing stay.',
+ description:
+ 'An upgraded double room with extra amenities and a modern touch, perfect for a relaxing stay. An upgraded double room with extra amenities and a modern touch, perfect for a relaxing stay. An upgraded double room with extra amenities and a modern touch, perfect for a relaxing stay.',
id: '4',
tags: ['25'],
type: 'room',
facilities: [
- RoomFacilityDTO(name: 'TV', icon: 'assets/icons/ic_tv.svg'),
- RoomFacilityDTO(name: 'Gratis WiFi', icon: 'assets/icons/ic_wifi.svg'),
- RoomFacilityDTO(name: 'Hårtørrer', icon: 'assets/icons/ic_hairdryer.svg'),
- RoomFacilityDTO(name: 'Badekar', icon: 'assets/icons/ic_bathtub.svg'),
- RoomFacilityDTO(name: 'Arbejdsplads', icon: 'assets/icons/ic_desk.svg'),
- RoomFacilityDTO(name: 'Roomservice', icon: 'assets/icons/ic_service_bowl.svg'),
+ RoomFacilityDTO(
+ name: '2x dobbelseng',
+ icon: 'assets/icons/ic_double_bed.svg',
+ facilityType: 'Bed'),
+ RoomFacilityDTO(
+ name: 'TV',
+ icon: 'assets/icons/ic_tv.svg',
+ facilityType: 'Electronics'),
+ RoomFacilityDTO(
+ name: 'Gratis WiFi',
+ icon: 'assets/icons/ic_wifi.svg',
+ facilityType: 'Electronics'),
+ RoomFacilityDTO(
+ name: 'Hårtørrer',
+ icon: 'assets/icons/ic_hairdryer.svg',
+ facilityType: 'Bathroom'),
+ RoomFacilityDTO(
+ name: 'Arbejdsplads',
+ icon: 'assets/icons/ic_desk.svg',
+ facilityType: 'Business'),
+ RoomFacilityDTO(
+ name: 'Roomservice',
+ icon: 'assets/icons/ic_service_bowl.svg',
+ facilityType: 'Service'),
],
),
RoomUpgradeDTO(
name: 'Standard Twin Plus Room',
price: '1450',
images: ['assets/images/login_screen_background.png'],
- description: 'A spacious twin room with two single beds and modern facilities, ideal for friends or colleagues traveling together.',
+ description:
+ 'A spacious twin room with two single beds and modern facilities, ideal for friends or colleagues traveling together. A spacious twin room with two single beds and modern facilities, ideal for friends or colleagues traveling together. A spacious twin room with two single beds and modern facilities, ideal for friends or colleagues traveling together.',
id: '5',
tags: ['27'],
type: 'room',
facilities: [
- RoomFacilityDTO(name: 'TV', icon: 'assets/icons/ic_tv.svg'),
- RoomFacilityDTO(name: 'Gratis WiFi', icon: 'assets/icons/ic_wifi.svg'),
- RoomFacilityDTO(name: 'Hårtørrer', icon: 'assets/icons/ic_hairdryer.svg'),
- RoomFacilityDTO(name: 'Arbejdsplads', icon: 'assets/icons/ic_desk.svg'),
- RoomFacilityDTO(name: 'Strygejern & -bræt', icon: 'assets/icons/ic_iron.svg'),
- RoomFacilityDTO(name: 'Minibar', icon: 'assets/icons/ic_minibar.svg'),
+ RoomFacilityDTO(
+ name: '2x dobbelseng',
+ icon: 'assets/icons/ic_double_bed.svg',
+ facilityType: 'Bed'),
+ RoomFacilityDTO(
+ name: 'TV',
+ icon: 'assets/icons/ic_tv.svg',
+ facilityType: 'Electronics'),
+ RoomFacilityDTO(
+ name: 'Gratis WiFi',
+ icon: 'assets/icons/ic_wifi.svg',
+ facilityType: 'Electronics'),
+ RoomFacilityDTO(
+ name: 'Hårtørrer',
+ icon: 'assets/icons/ic_hairdryer.svg',
+ facilityType: 'Bathroom'),
+ RoomFacilityDTO(
+ name: 'Arbejdsplads',
+ icon: 'assets/icons/ic_desk.svg',
+ facilityType: 'Business'),
+ RoomFacilityDTO(
+ name: 'Strygejern & -bræt',
+ icon: 'assets/icons/ic_iron.svg',
+ facilityType: 'Room'),
+ RoomFacilityDTO(
+ name: 'Minibar',
+ icon: 'assets/icons/ic_minibar.svg',
+ facilityType: 'Room'),
],
),
RoomUpgradeDTO(
name: 'Bottle of Champagne',
price: '450',
images: ['assets/images/catalog_image.png'],
- description: 'Celebrate your stay with a bottle of premium champagne and a selection of fine chocolates delivered to your room.',
+ description:
+ 'Celebrate your stay with a bottle of premium champagne and a selection of fine chocolates delivered to your room.',
id: '6',
tags: [],
type: 'other',
@@ -132,7 +285,8 @@ final List<RoomUpgradeDTO> mockRoomUpgrades = [
name: 'Luxury Flower Arrangement',
price: '350',
images: ['assets/images/login_screen_background.png'],
- description: 'A beautiful bouquet of fresh seasonal flowers to brighten up your room and create a welcoming atmosphere.',
+ description:
+ 'A beautiful bouquet of fresh seasonal flowers to brighten up your room and create a welcoming atmosphere.',
id: '7',
tags: [],
type: 'other',
@@ -142,7 +296,8 @@ final List<RoomUpgradeDTO> mockRoomUpgrades = [
name: 'Romantic Evening Package',
price: '750',
images: ['assets/images/catalog_image.png'],
- description: 'Create a romantic atmosphere with rose petals, candles, champagne, and a special dessert for two.',
+ description:
+ 'Create a romantic atmosphere with rose petals, candles, champagne, and a special dessert for two.',
id: '8',
tags: [],
type: 'other',
@@ -152,7 +307,8 @@ final List<RoomUpgradeDTO> mockRoomUpgrades = [
name: 'Breakfast in Bed',
price: '250',
images: ['assets/images/login_screen_background.png'],
- description: 'Start your day in luxury with a full breakfast served in the comfort of your room.',
+ description:
+ 'Start your day in luxury with a full breakfast served in the comfort of your room.',
id: '9',
tags: [],
type: 'other',
@@ -162,12 +318,11 @@ final List<RoomUpgradeDTO> mockRoomUpgrades = [
name: 'Wellness Package',
price: '600',
images: ['assets/images/login_screen_background.png'],
- description: 'Indulge in a wellness experience with a selection of premium spa products, bath salts, and aromatherapy items.',
+ description:
+ 'Indulge in a wellness experience with a selection of premium spa products, bath salts, and aromatherapy items.',
id: '10',
tags: [],
type: 'other',
facilities: [],
),
];
-
-
diff --git a/comwell_key_app/lib/up_sales/up_sales_catalog.dart b/comwell_key_app/lib/up_sales/up_sales_catalog.dart
index e5f515ba..1721a1b4 100644
--- a/comwell_key_app/lib/up_sales/up_sales_catalog.dart
+++ b/comwell_key_app/lib/up_sales/up_sales_catalog.dart
@@ -1,5 +1,5 @@
import 'package:comwell_key_app/common/components/comwell_app_bar.dart';
-import 'package:comwell_key_app/up_sales/components/up_sales_bottom_sheet.dart';
+import 'package:comwell_key_app/up_sales/components/up_sales_bottom_button.dart';
import 'package:comwell_key_app/up_sales/components/up_sales_services_widget.dart';
import 'package:comwell_key_app/up_sales/components/up_sales_upgrades_widget.dart';
import 'package:comwell_key_app/up_sales/cubit/up_sales_cubit.dart';
@@ -69,7 +69,13 @@ class UpSalesCatalog extends StatelessWidget {
),
),
),
- bottomSheet: UpSalesBottomSheet(onContinue: cubit.onContinue),
+ bottomSheet: UpSalesBottomButton(onContinue: cubit.onContinue, children: [
+ Text("continue_without_up_sales".tr(),
+ style: theme.textTheme.headlineSmall?.copyWith(
+ color: Colors.white
+ ),
+ ),
+ ]),
);
});
}