6177214e-ce7c-49e3-99de-ff9721b26f63 — Commit 63c3670d

AuthorEdmir Suljic<esu@dwarf.dk>
Date2025-06-17 10:20:56 +0200
Mid fix

Changed files

comwell_key_app/lib/routing/app_router.dart        |   9 +-
 .../up_sales/components/comwell_radio_button.dart  |   6 +-
 .../components/facilities_bottom_sheet.dart        |   2 +-
 .../lib/up_sales/components/item_counter.dart      | 103 ++++-----
 .../components/up_sales_bottom_button.dart         |  68 +++---
 .../components/up_sales_services_widget.dart       |   2 +-
 .../components/up_sales_upgrades_widget.dart       |  36 +++-
 .../lib/up_sales/components/upgrades_counter.dart  |  24 +++
 .../lib/up_sales/cubit/up_sales_cubit.dart         |  49 ++++-
 .../lib/up_sales/cubit/up_sales_state.dart         |  45 ++--
 .../lib/up_sales/mappers/room_upgrade_mapper.dart  |   5 +-
 .../lib/up_sales/pages/other_upgrade_page.dart     | 112 +++++++---
 .../lib/up_sales/pages/room_upgrade_page.dart      | 230 +++++++++++----------
 .../lib/up_sales/up_sale_repository.dart           |   2 +-
 comwell_key_app/lib/up_sales/up_sales_catalog.dart |  34 ++-
 15 files changed, 441 insertions(+), 286 deletions(-)

Diff

diff --git a/comwell_key_app/lib/routing/app_router.dart b/comwell_key_app/lib/routing/app_router.dart
index 019a1391..edf105ab 100644
--- a/comwell_key_app/lib/routing/app_router.dart
+++ b/comwell_key_app/lib/routing/app_router.dart
@@ -398,17 +398,22 @@ GoRouter goRouter() {
name: AppRoutes.roomUpgrade.name,
builder: (context, state) {
final roomUpgrade = state.extra as RoomUpgrade;
- return RoomUpgradePage(roomUpgrade: roomUpgrade);
+ return BlocProvider(
+ create: (context) =>
+ UpSalesCubit(upSaleRepository: locator<UpSaleRepository>()),
+ child: RoomUpgradePage(roomUpgrade: roomUpgrade),
+ );
},
),
GoRoute(
path: "/${AppRoutes.otherUpgrade.name}",
name: AppRoutes.otherUpgrade.name,
builder: (context, state) {
+ final roomUpgrade = state.extra as RoomUpgrade;
return BlocProvider(
create: (context) =>
UpSalesCubit(upSaleRepository: locator<UpSaleRepository>()),
- child: const OtherUpgradePage(),
+ child: OtherUpgradePage(roomUpgrade: roomUpgrade),
);
}),
/* GoRoute(
diff --git a/comwell_key_app/lib/up_sales/components/comwell_radio_button.dart b/comwell_key_app/lib/up_sales/components/comwell_radio_button.dart
index a56b5730..fbd99f7c 100644
--- a/comwell_key_app/lib/up_sales/components/comwell_radio_button.dart
+++ b/comwell_key_app/lib/up_sales/components/comwell_radio_button.dart
@@ -8,7 +8,7 @@ class ComwellRadioButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return GestureDetector(
+ return InkWell(
onTap: onTap,
child: Container(
width: 24,
@@ -20,8 +20,8 @@ class ComwellRadioButton extends StatelessWidget {
child: selected
? Center(
child: Container(
- width: 21,
- height: 21,
+ width: 16,
+ height: 16,
decoration: const BoxDecoration(
color: sandColor,
shape: BoxShape.circle,
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
index 2a77287e..fe4dc938 100644
--- a/comwell_key_app/lib/up_sales/components/facilities_bottom_sheet.dart
+++ b/comwell_key_app/lib/up_sales/components/facilities_bottom_sheet.dart
@@ -84,7 +84,7 @@ class FacilitiesBottomSheet extends StatelessWidget {
borderRadius: BorderRadius.circular(8),
),
child: Center(
- child: FacilityIconText(facility: f)),
+ child: FacilityIconText(facility: f, showDivider: false)),
))
.toList()
: entry.value
diff --git a/comwell_key_app/lib/up_sales/components/item_counter.dart b/comwell_key_app/lib/up_sales/components/item_counter.dart
index a31206cd..6eb99b03 100644
--- a/comwell_key_app/lib/up_sales/components/item_counter.dart
+++ b/comwell_key_app/lib/up_sales/components/item_counter.dart
@@ -4,63 +4,68 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class ItemCounter extends StatelessWidget {
- const ItemCounter({super.key});
+ final int quantity;
+ final Function(int) onQuantityChanged;
+
+ const ItemCounter({super.key, required this.quantity, required this.onQuantityChanged});
@override
Widget build(BuildContext context) {
-
-
- return BlocBuilder<UpSalesCubit, UpSalesState>(
- builder: (context, state) {
- final theme = Theme.of(context);
- final cubit = context.read<UpSalesCubit>();
- return Expanded(
- child: Container(
- width: double.infinity,
- color: Colors.white,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ return BlocBuilder<UpSalesCubit, UpSalesState>(builder: (context, state) {
+ final theme = Theme.of(context);
+ final cubit = context.read<UpSalesCubit>();
+ return Container(
+ color: Colors.white,
+ child: Padding(
+ padding: const EdgeInsets.only(
+ left: 16.0,
+ right: 16.0,
+ top: 16.0,
+ bottom: 40,
+ ),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
children: [
- Row(
- children: [
- // Minus button
- InkWell(
- onTap: cubit.decrement,
- borderRadius: BorderRadius.circular(24),
- child: Container(
- width: 44,
- height: 44,
- decoration: const BoxDecoration(
- color: Colors.black,
- shape: BoxShape.circle,
- ),
- child: const Icon(Icons.remove, color: Colors.white),
- ),
+ InkWell(
+ onTap: cubit.decrement,
+ borderRadius: BorderRadius.circular(24),
+ child: Container(
+ width: 44,
+ height: 44,
+ decoration: const BoxDecoration(
+ color: Colors.black,
+ shape: BoxShape.circle,
),
- const SizedBox(width: 16),
- Text('${cubit.state.quantity}', style: theme.textTheme.headlineSmall),
- const SizedBox(width: 16),
- // Plus button
- InkWell(
- onTap: cubit.increment,
- borderRadius: BorderRadius.circular(24),
- child: Container(
- width: 44,
- height: 44,
- decoration: const BoxDecoration(
- color: Colors.black,
- shape: BoxShape.circle,
- ),
- child: const Icon(Icons.add, color: Colors.white),
- ),
+ child: const Icon(Icons.remove, color: Colors.white),
+ ),
+ ),
+ const SizedBox(width: 16),
+ Text('${cubit.state.quantity}',
+ style: theme.textTheme.headlineMedium),
+ const SizedBox(width: 16),
+ // Plus button
+ InkWell(
+ onTap: cubit.increment,
+ borderRadius: BorderRadius.circular(24),
+ child: Container(
+ width: 44,
+ height: 44,
+ decoration: const BoxDecoration(
+ color: Colors.black,
+ shape: BoxShape.circle,
),
- ],
+ child: const Icon(Icons.add, color: Colors.white),
+ ),
),
],
),
+ ],
),
- );
- }
- );
+ ),
+ );
+ });
}
-}
\ No newline at end of file
+}
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
index 9c6c606f..392eb4a9 100644
--- 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
@@ -15,49 +15,35 @@ class UpSalesBottomButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
- return Column(
- mainAxisSize: MainAxisSize.min,
- children: [
- const Divider(
- color: colorDivider,
- height: 0,
+ return Container(
+ color: Colors.white,
+ child: Padding(
+ padding: const EdgeInsets.only(
+ left: 16.0,
+ right: 16.0,
+ top: 16.0,
+ bottom: 40,
),
- 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,
- )
- ),
- ),
- ),
- ),
- ),
- ],
+ 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_services_widget.dart b/comwell_key_app/lib/up_sales/components/up_sales_services_widget.dart
index 2cfb70a2..d7187bbf 100644
--- a/comwell_key_app/lib/up_sales/components/up_sales_services_widget.dart
+++ b/comwell_key_app/lib/up_sales/components/up_sales_services_widget.dart
@@ -58,7 +58,7 @@ class UpSalesServicesWidget extends StatelessWidget {
style: theme.textTheme.headlineMedium,
),
const SizedBox(width: 8),
- // ComwellRadioButton(selected: cubit.state.selected, onTap: cubit.toggleSelected),
+ ComwellRadioButton(selected: cubit.state.selected, onTap: () {}),
],
),
],
diff --git a/comwell_key_app/lib/up_sales/components/up_sales_upgrades_widget.dart b/comwell_key_app/lib/up_sales/components/up_sales_upgrades_widget.dart
index fc43779f..54d1220f 100644
--- a/comwell_key_app/lib/up_sales/components/up_sales_upgrades_widget.dart
+++ b/comwell_key_app/lib/up_sales/components/up_sales_upgrades_widget.dart
@@ -1,5 +1,6 @@
import 'package:comwell_key_app/routing/app_routes.dart';
import 'package:comwell_key_app/up_sales/components/comwell_radio_button.dart';
+import 'package:comwell_key_app/up_sales/components/upgrades_counter.dart';
import 'package:comwell_key_app/up_sales/cubit/up_sales_cubit.dart';
import 'package:comwell_key_app/up_sales/cubit/up_sales_state.dart';
import 'package:comwell_key_app/up_sales/models/room_upgrade.dart';
@@ -16,19 +17,27 @@ class UpSalesUpgradesWidget extends StatelessWidget {
final RoomUpgrade roomUpgrade;
final bool isSelected;
final String routeName;
+ final bool showCounter;
const UpSalesUpgradesWidget(
{super.key,
this.width = 328,
this.height = 268,
required this.roomUpgrade,
this.isSelected = false,
- required this.routeName});
+ required this.routeName,
+ this.showCounter = false});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
+ final cubit = context.read<UpSalesCubit>();
return BlocBuilder<UpSalesCubit, UpSalesState>(builder: (context, state) {
- final cubit = context.read<UpSalesCubit>();
+ final isSelected = state.selectedUpSales.contains(roomUpgrade);
+ final quantity = state.selectedUpSales
+ .where((element) => element.id == roomUpgrade.id)
+ .length;
+
+ print("quantity ${quantity}");
return Container(
width: width,
height: height,
@@ -93,7 +102,7 @@ class UpSalesUpgradesWidget extends StatelessWidget {
roomUpgrade.name,
style: theme.textTheme.headlineMedium,
maxLines: 1,
- overflow: TextOverflow.ellipsis,
+ overflow: TextOverflow.visible,
),
),
Row(
@@ -104,18 +113,27 @@ class UpSalesUpgradesWidget extends StatelessWidget {
style: theme.textTheme.headlineMedium,
),
const SizedBox(width: 8),
- ComwellRadioButton(
- selected: isSelected,
- onTap: () => cubit.toggleSelected(),
- ),
+ showCounter
+ ? UpgradesCounter(quantity: quantity)
+ : ComwellRadioButton(
+ selected: isSelected,
+ onTap: () => cubit
+ .toggleSelected(roomUpgrade.id),
+ ),
],
),
],
),
const SizedBox(height: 8),
GestureDetector(
- onTap: () {
- context.pushNamed(routeName, extra: roomUpgrade);
+ onTap: () async {
+ final roomUpgradeResponse = await context.pushNamed(routeName, extra: roomUpgrade);
+ if (roomUpgradeResponse is RoomUpgrade) {
+ print("response ${roomUpgradeResponse.id}");
+ cubit.addSelected(roomUpgradeResponse);
+ } else if (roomUpgradeResponse is int) {
+ cubit.addOtherUpgradeWithQuantity(roomUpgrade, roomUpgradeResponse);
+ }
},
child: Text(
'read_more_up_sales'.tr(),
diff --git a/comwell_key_app/lib/up_sales/components/upgrades_counter.dart b/comwell_key_app/lib/up_sales/components/upgrades_counter.dart
new file mode 100644
index 00000000..63c6e91d
--- /dev/null
+++ b/comwell_key_app/lib/up_sales/components/upgrades_counter.dart
@@ -0,0 +1,24 @@
+import 'package:comwell_key_app/themes/light_theme.dart';
+import 'package:flutter/material.dart';
+
+class UpgradesCounter extends StatelessWidget {
+ final int quantity;
+ const UpgradesCounter({super.key, required this.quantity});
+
+ @override
+ Widget build(BuildContext context) {
+ final theme = Theme.of(context);
+ return Container(
+ width: 24,
+ height: 24,
+ decoration: BoxDecoration(
+ color: quantity > 1 ? Colors.black : Colors.transparent ,
+ shape: BoxShape.circle,
+ border: Border.all(color: colorDivider, width: 1.5),
+ ),
+ child: quantity > 1 ? Center(
+ child: Text(quantity.toString(), style: theme.textTheme.headlineSmall?.copyWith(color: Colors.white, fontSize: 11)),
+ ) : const SizedBox.shrink(),
+ );
+ }
+}
\ No newline at end of file
diff --git a/comwell_key_app/lib/up_sales/cubit/up_sales_cubit.dart b/comwell_key_app/lib/up_sales/cubit/up_sales_cubit.dart
index 60fa9ee8..0583baf8 100644
--- a/comwell_key_app/lib/up_sales/cubit/up_sales_cubit.dart
+++ b/comwell_key_app/lib/up_sales/cubit/up_sales_cubit.dart
@@ -6,33 +6,45 @@ import 'package:comwell_key_app/up_sales/up_sale_repository.dart';
class UpSalesCubit extends Cubit<UpSalesState> {
final UpSaleRepository upSaleRepository;
- Iterable<RoomUpgrade> upSales = [];
+ List<RoomUpgrade> upSales = [];
+ List<RoomUpgrade> selectedUpSales = [];
UpSalesCubit({required this.upSaleRepository})
: super(UpSalesState.initial());
- void toggleSelected() {
- emit(state.copyWith(selected: !state.selected));
+ void toggleSelected(String index) {
+ emit(state.copyWith(
+ selected: !state.selected, quantity: state.quantity, upSales: upSales));
}
void init() async {
- emit(UpSalesState(selected: false, upSales: upSales, isLoading: true, error: null));
+ emit(UpSalesState(
+ selected: false,
+ upSales: upSales,
+ selectedUpSales: selectedUpSales,
+ isLoading: true,
+ error: null));
try {
upSales = await upSaleRepository.getMockUpSales();
- emit(UpSalesState.loaded(upSales: upSales));
+ emit(state.loaded(upSales: upSales));
} catch (e) {
- emit(UpSalesState.error(error: Error()));
+ emit(state.setupError(error: Error()));
}
}
+ void addSelected(RoomUpgrade roomUpgrade) {
+ print("roomUpgrade ${roomUpgrade.id}");
+ emit(state.addSelected(roomUpgrade: roomUpgrade));
+ print("state.selectedUpSales ${state.selectedUpSales.length}");
+ }
+
void increment() {
- print('increment ${state.quantity}');
- emit(state.copyWith(quantity: state.quantity + 4));
+ emit(state.addQuantity());
}
void decrement() {
if (state.quantity > 0) {
- emit(state.copyWith(quantity: state.quantity - 1));
+ emit(state.removeQuantity());
}
}
@@ -40,4 +52,23 @@ class UpSalesCubit extends Cubit<UpSalesState> {
emit(state.copyWith(selected: false));
}
+ void addOtherUpgradeWithQuantity(RoomUpgrade roomUpgrade, int quantity) {
+ final updatedSelectedUpSales = List<RoomUpgrade>.from(state.selectedUpSales);
+
+ for (int i = 0; i < quantity; i++) {
+ updatedSelectedUpSales.add(roomUpgrade);
+ }
+
+ print("updatedSelectedUpSales ${updatedSelectedUpSales.length}");
+ emit(state.addSelected(roomUpgrade: roomUpgrade));
+ }
+
+ void removeUpgrade(RoomUpgrade roomUpgrade) {
+ final updatedSelectedUpSales = List<RoomUpgrade>.from(state.selectedUpSales);
+ updatedSelectedUpSales.remove(roomUpgrade);
+
+ emit(state.copyWith(
+ selectedUpSales: updatedSelectedUpSales,
+ ));
+ }
}
diff --git a/comwell_key_app/lib/up_sales/cubit/up_sales_state.dart b/comwell_key_app/lib/up_sales/cubit/up_sales_state.dart
index 80cc04c0..4540003c 100644
--- a/comwell_key_app/lib/up_sales/cubit/up_sales_state.dart
+++ b/comwell_key_app/lib/up_sales/cubit/up_sales_state.dart
@@ -3,44 +3,46 @@ import 'package:equatable/equatable.dart';
class UpSalesState extends Equatable {
final bool selected;
- final Iterable<RoomUpgrade> upSales;
+ final List<RoomUpgrade> upSales;
+ final List<RoomUpgrade> selectedUpSales;
final Error? error;
final bool isLoading;
final int quantity;
- const UpSalesState({required this.selected, required this.upSales, this.error, required this.isLoading, this.quantity = 0});
+ const UpSalesState(
+ {required this.selected,
+ required this.upSales,
+ required this.selectedUpSales,
+ this.error,
+ required this.isLoading,
+ this.quantity = 0});
@override
- List<Object?> get props => [selected, upSales];
+ List<Object?> get props => [selected, upSales, selectedUpSales, quantity];
UpSalesState.initial()
: selected = false,
upSales = [],
+ selectedUpSales = [],
error = null,
isLoading = false,
quantity = 0;
- UpSalesState.error({required this.error})
- : selected = false,
- upSales = [],
- isLoading = false,
- quantity = 0;
+ UpSalesState setupError({required Error error}) => copyWith(isLoading: false, error: error);
- UpSalesState.loading()
- : selected = false,
- upSales = [],
- error = null,
- isLoading = true,
- quantity = 0;
+ UpSalesState loading() => copyWith(isLoading: true);
- const UpSalesState.loaded({required this.upSales})
- : selected = false,
- error = null,
- isLoading = false,
- quantity = 0;
+ UpSalesState loaded({required List<RoomUpgrade> upSales}) => copyWith(isLoading: false, upSales: upSales);
+
+ UpSalesState addSelected({required RoomUpgrade roomUpgrade}) => copyWith(selectedUpSales: [...selectedUpSales, roomUpgrade]);
+
+ UpSalesState addQuantity() => copyWith(quantity: quantity + 1);
+
+ UpSalesState removeQuantity() => copyWith(quantity: quantity - 1);
UpSalesState copyWith({
bool? selected,
- Iterable<RoomUpgrade>? upSales,
+ List<RoomUpgrade>? upSales,
+ List<RoomUpgrade>? selectedUpSales,
bool? isLoading,
Error? error,
int? quantity,
@@ -48,9 +50,10 @@ class UpSalesState extends Equatable {
return UpSalesState(
selected: selected ?? this.selected,
upSales: upSales ?? this.upSales,
+ selectedUpSales: selectedUpSales ?? this.selectedUpSales,
isLoading: isLoading ?? this.isLoading,
error: error ?? this.error,
quantity: quantity ?? this.quantity,
);
}
-}
\ No newline at end of file
+}
diff --git a/comwell_key_app/lib/up_sales/mappers/room_upgrade_mapper.dart b/comwell_key_app/lib/up_sales/mappers/room_upgrade_mapper.dart
index 801c9cdc..90520963 100644
--- a/comwell_key_app/lib/up_sales/mappers/room_upgrade_mapper.dart
+++ b/comwell_key_app/lib/up_sales/mappers/room_upgrade_mapper.dart
@@ -19,7 +19,6 @@ extension RoomUpgradeDTOMapper on RoomUpgradeDTO {
}
-extension ListRoomUpgradeMapper on Iterable<RoomUpgradeDTO> {
- Iterable<RoomUpgrade> toRoomUpgrades() =>
- map((dto) => dto.toRoomUpgrade());
+extension ListRoomUpgradeMapper on List<RoomUpgradeDTO> {
+ List<RoomUpgrade> toRoomUpgrades() => map((dto) => dto.toRoomUpgrade()).toList();
}
diff --git a/comwell_key_app/lib/up_sales/pages/other_upgrade_page.dart b/comwell_key_app/lib/up_sales/pages/other_upgrade_page.dart
index 8d3f3d1c..1296bb60 100644
--- a/comwell_key_app/lib/up_sales/pages/other_upgrade_page.dart
+++ b/comwell_key_app/lib/up_sales/pages/other_upgrade_page.dart
@@ -1,23 +1,32 @@
import 'package:comwell_key_app/common/components/comwell_app_bar.dart';
import 'package:comwell_key_app/up_sales/components/item_counter.dart';
+import 'package:comwell_key_app/up_sales/cubit/up_sales_cubit.dart';
+import 'package:comwell_key_app/up_sales/models/room_upgrade.dart';
+import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import '../../themes/light_theme.dart';
import '../components/up_sales_bottom_button.dart';
class OtherUpgradePage extends StatefulWidget {
- const OtherUpgradePage({super.key});
+ final RoomUpgrade roomUpgrade;
+ const OtherUpgradePage({super.key, required this.roomUpgrade});
@override
State<OtherUpgradePage> createState() => _OtherUpgradePageState();
}
class _OtherUpgradePageState extends State<OtherUpgradePage> {
- int quantity = 2;
+ int _quantity = 1;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
+ final width = MediaQuery.of(context).size.width;
+ final height = MediaQuery.of(context).size.height;
+ final cubit = context.read<UpSalesCubit>();
+
return Scaffold(
backgroundColor: Colors.white,
appBar: const ComwellAppBar(),
@@ -25,17 +34,35 @@ class _OtherUpgradePageState extends State<OtherUpgradePage> {
body: Column(
children: [
// Image
- Container(
- width: double.infinity,
- height: 320,
- decoration: BoxDecoration(
- image: DecorationImage(
- image: NetworkImage('https://images.unsplash.com/photo-1504674900247-0877df9cc836'),
- fit: BoxFit.cover,
+ Stack(
+ children: [
+ ClipRRect(
+ borderRadius: const BorderRadius.only(
+ topLeft: Radius.circular(10),
+ topRight: Radius.circular(10),
+ ),
+ child: Image.asset(
+ widget.roomUpgrade.images.first,
+ height: height * 0.5,
+ width: double.infinity,
+ fit: BoxFit.cover,
+ ),
),
- ),
+ Container(
+ decoration: const BoxDecoration(
+ borderRadius: BorderRadius.all(Radius.circular(12)),
+ gradient: LinearGradient(
+ begin: Alignment.topCenter,
+ end: Alignment.bottomCenter,
+ colors: [
+ Colors.black26,
+ Colors.black54,
+ ],
+ ),
+ ),
+ ),
+ ],
),
- // Card
Container(
width: double.infinity,
color: Colors.white,
@@ -46,35 +73,58 @@ class _OtherUpgradePageState extends State<OtherUpgradePage> {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
- Text('En flaske bobler', style: theme.textTheme.headlineSmall),
- Text('495 kr.', style: theme.textTheme.headlineSmall),
+ Text(widget.roomUpgrade.name,
+ style: theme.textTheme.headlineLarge),
+ Text('${widget.roomUpgrade.price} kr.',
+ style: theme.textTheme.headlineLarge),
],
),
const SizedBox(height: 12),
- Text(
- 'Nyd en flaske cava i værelset ved ankomst.\nServeret kølet med et sæt glas.',
- style: theme.textTheme.bodyMedium,
+ Container(
+ width: width * 0.8,
+ child: Text(
+ widget.roomUpgrade.description,
+ style: theme.textTheme.bodySmall
+ ?.copyWith(color: colorHeadlineText),
+ ),
),
],
),
),
],
),
- bottomNavigationBar: Container(
- color: Colors.white,
- padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 16),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- const ItemCounter(),
- Expanded(
- child: UpSalesBottomButton(onContinue: () {}, children: [
- Text('Tilføj til booking', style: theme.textTheme.headlineSmall),
- ]),
- ),
- ],
- ),
+ bottomNavigationBar: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ const Divider(color: colorDivider),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ ItemCounter(
+ quantity: _quantity,
+ onQuantityChanged: (newQuantity) {
+ setState(() {
+ _quantity = newQuantity;
+ });
+ },
+ ),
+ Expanded(
+ flex: 2,
+ child: UpSalesBottomButton(
+ onContinue: () {
+ cubit.addOtherUpgradeWithQuantity(widget.roomUpgrade, _quantity);
+ Navigator.pop(context, widget.roomUpgrade);
+ },
+ children: [Text('add_to_booking'.tr())],
+ ),
+ ),
+ ],
+ ),
+ ],
),
);
}
-}
\ No newline at end of file
+}
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 59ef7f69..72f095a7 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
@@ -6,6 +6,7 @@ import 'package:comwell_key_app/up_sales/components/facility_icon_text.dart';
import 'package:comwell_key_app/up_sales/components/room_image_carousel.dart';
import 'package:comwell_key_app/up_sales/components/up_sales_bottom_button.dart';
import 'package:comwell_key_app/up_sales/cubit/up_sales_cubit.dart';
+import 'package:comwell_key_app/up_sales/cubit/up_sales_state.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:comwell_key_app/up_sales/models/room_upgrade.dart';
@@ -25,130 +26,143 @@ class RoomUpgradePage extends StatefulWidget {
class _RoomUpgradePageState extends State<RoomUpgradePage> {
bool _isExpanded = false;
-
List<RoomFacility> get allFacilities => [
...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);
-
- return Scaffold(
- extendBodyBehindAppBar: true,
- appBar: const ComwellAppBar(),
- backgroundColor: Colors.white,
- body: SingleChildScrollView(
- physics: const AlwaysScrollableScrollPhysics(),
- child: ConstrainedBox(
- constraints: BoxConstraints(
- minHeight: MediaQuery.of(context).size.height - kComwellAppBarHeight - 80, // 80 is approximate height of bottom button
- ),
- child: Column(
- children: [
- RoomImageCarousel(images: widget.roomUpgrade.images.toList()),
- Container(
- width: double.infinity,
- decoration: const BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.only(
- topLeft: Radius.circular(24),
- topRight: Radius.circular(24),
- ),
- ),
- child: Padding(
- padding:
- const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- mainAxisSize: MainAxisSize.min,
+ final cubit = context.read<UpSalesCubit>();
+
+ return BlocBuilder<UpSalesCubit, UpSalesState>(
+ builder: (context, state) {
+ return Scaffold(
+ extendBodyBehindAppBar: true,
+ appBar: const ComwellAppBar(),
+ backgroundColor: Colors.white,
+ body: SingleChildScrollView(
+ physics: const AlwaysScrollableScrollPhysics(),
+ child: ConstrainedBox(
+ constraints: BoxConstraints(
+ minHeight: MediaQuery.of(context).size.height -
+ kComwellAppBarHeight -
+ 80, // 80 is approximate height of bottom button
+ ),
+ child: Column(
+ children: [
+ RoomImageCarousel(images: widget.roomUpgrade.images.toList()),
+ Container(
+ width: double.infinity,
+ decoration: const BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(24),
+ topRight: Radius.circular(24),
+ ),
+ ),
+ child: Padding(
+ padding:
+ const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Text(
- widget.roomUpgrade.name,
- style: theme.textTheme.headlineLarge,
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Text(
+ widget.roomUpgrade.name,
+ style: theme.textTheme.headlineLarge,
+ ),
+ const SizedBox(width: 12),
+ if (widget.roomUpgrade.tags.isNotEmpty)
+ TagWidget(
+ text: '${widget.roomUpgrade.tags.first} M2',
+ textColor: sandColor),
+ ],
),
- const SizedBox(width: 12),
- if (widget.roomUpgrade.tags.isNotEmpty)
- TagWidget(
- text: '${widget.roomUpgrade.tags.first} M2',
- textColor: sandColor),
- ],
- ),
- const SizedBox(height: 12),
- Text(
- widget.roomUpgrade.description,
- style: theme.textTheme.bodySmall,
- maxLines: _isExpanded ? null : 3,
- overflow: _isExpanded ? null : TextOverflow.ellipsis,
- ),
- const SizedBox(height: 4),
- GestureDetector(
- onTap: () {
- setState(() {
- _isExpanded = !_isExpanded;
- });
- },
- child: Text(
- _isExpanded ? 'read_less'.tr() : 'read_more'.tr(),
- style: theme.textTheme.bodySmall?.copyWith(
- color: sandColor,
- decoration: TextDecoration.underline,
- decorationColor: sandColor,
+ const SizedBox(height: 12),
+ Text(
+ widget.roomUpgrade.description,
+ style: theme.textTheme.bodySmall,
+ maxLines: _isExpanded ? null : 3,
+ overflow: _isExpanded ? null : TextOverflow.ellipsis,
),
- ),
- ),
- const SizedBox(height: 24),
- // Facilities row
- Wrap(
- spacing: 8,
- runSpacing: 8,
- children: [
- ...widget.roomUpgrade.facilities
- .map((f) => FacilityIconText(facility: f, showDivider: true)),
+ const SizedBox(height: 4),
GestureDetector(
- onTap: () => _showFacilitiesSheet(context),
- child: Padding(
- padding:
- const EdgeInsets.symmetric(horizontal: 4.0),
- child: Text(
- 'see_all_facilities'.tr(),
- style: theme.textTheme.bodySmall?.copyWith(
- color: sandColor,
- decoration: TextDecoration.underline,
- decorationColor: sandColor,
- ),
+ onTap: () {
+ setState(() {
+ _isExpanded = !_isExpanded;
+ });
+ },
+ child: Text(
+ _isExpanded ? 'read_less'.tr() : 'read_more'.tr(),
+ style: theme.textTheme.bodySmall?.copyWith(
+ color: sandColor,
+ decoration: TextDecoration.underline,
+ decorationColor: sandColor,
),
),
),
+ const SizedBox(height: 24),
+ // Facilities row
+ Wrap(
+ spacing: 8,
+ runSpacing: 8,
+ children: [
+ ...widget.roomUpgrade.facilities.map((f) =>
+ FacilityIconText(facility: f, showDivider: true)),
+ GestureDetector(
+ onTap: () => _showFacilitiesSheet(context),
+ child: Padding(
+ padding:
+ const EdgeInsets.symmetric(horizontal: 4.0),
+ child: Text(
+ 'see_all_facilities'.tr(),
+ style: theme.textTheme.bodySmall?.copyWith(
+ color: sandColor,
+ decoration: TextDecoration.underline,
+ decorationColor: sandColor,
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ const SizedBox(height: 32),
],
),
- const SizedBox(height: 32),
- ],
+ ),
),
- ),
+ // Booking button
+ ],
),
- // Booking button
+ ),
+ ),
+ bottomNavigationBar: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const Divider(color: colorDivider),
+ UpSalesBottomButton(onContinue: () {
+ Navigator.pop(context, widget.roomUpgrade);
+ }, 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),
+ ),
+ ]),
],
),
- ),
- ),
- bottomNavigationBar: 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),
- ),
- ]),
+ );
+ }
);
}
@@ -161,11 +175,11 @@ class _RoomUpgradePageState extends State<RoomUpgradePage> {
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
),
- builder: (context) {
- return ConstrainedBox(
- constraints: BoxConstraints(
- maxHeight: height - kComwellAppBarHeight,
- ),
+ builder: (context) {
+ return ConstrainedBox(
+ constraints: BoxConstraints(
+ maxHeight: height - kComwellAppBarHeight,
+ ),
child: FacilitiesBottomSheet(facilities: allFacilities),
);
},
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 65862e7e..cb30b7bd 100644
--- a/comwell_key_app/lib/up_sales/up_sale_repository.dart
+++ b/comwell_key_app/lib/up_sales/up_sale_repository.dart
@@ -15,7 +15,7 @@ class UpSaleRepository {
return response;
}
- Future<Iterable<RoomUpgrade>> getMockUpSales() async {
+ Future<List<RoomUpgrade>> getMockUpSales() async {
return mockRoomUpgrades.toRoomUpgrades();
}
}
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 e3a7dc11..2c5de1d4 100644
--- a/comwell_key_app/lib/up_sales/up_sales_catalog.dart
+++ b/comwell_key_app/lib/up_sales/up_sales_catalog.dart
@@ -19,6 +19,19 @@ class UpSalesCatalog extends StatelessWidget {
final theme = Theme.of(context);
return BlocBuilder<UpSalesCubit, UpSalesState>(builder: (context, state) {
final cubit = context.read<UpSalesCubit>();
+
+ print("state.selectedUpSales ${state.selectedUpSales.length}");
+
+ if (state.isLoading) {
+ return const Scaffold(
+ appBar: ComwellAppBar(),
+ backgroundColor: Colors.white,
+ body: Center(
+ child: CircularProgressIndicator(),
+ ),
+ );
+ }
+
return Scaffold(
appBar: const ComwellAppBar(),
backgroundColor: Colors.white,
@@ -26,7 +39,7 @@ class UpSalesCatalog extends StatelessWidget {
child: Padding(
padding: const EdgeInsets.only(
top: 24,
- bottom: 100, // Add padding to account for bottom sheet
+ bottom: 100,
left: 0,
right: 0,
),
@@ -67,12 +80,17 @@ class UpSalesCatalog extends StatelessWidget {
),
),
),
- bottomSheet: UpSalesBottomButton(onContinue: cubit.onContinue, children: [
- Text("continue_without_up_sales".tr(),
- style: theme.textTheme.headlineSmall?.copyWith(
- color: Colors.white
- ),
- ),
+ bottomNavigationBar: Column(mainAxisSize: MainAxisSize.min, children: [
+ const Divider(color: colorDivider),
+ UpSalesBottomButton(onContinue: cubit.onContinue, children: [
+ Text(
+ cubit.state.selectedUpSales.isEmpty
+ ? "continue_without_up_sales".tr()
+ : "generic_continue".tr(),
+ style:
+ theme.textTheme.headlineSmall?.copyWith(color: Colors.white),
+ ),
+ ]),
]),
);
});
@@ -108,6 +126,7 @@ class UpSalesCatalog extends StatelessWidget {
roomUpgrade: roomUpSales.elementAt(index),
isSelected: cubit.state.selected,
routeName: AppRoutes.roomUpgrade.name,
+ showCounter: false,
);
},
),
@@ -131,6 +150,7 @@ class UpSalesCatalog extends StatelessWidget {
roomUpgrade: otherUpSales.elementAt(index),
isSelected: cubit.state.selected,
routeName: AppRoutes.otherUpgrade.name,
+ showCounter: true,
);
},
),