6177214e-ce7c-49e3-99de-ff9721b26f63 — Commit 2096d189

AuthorMikkel Thygesen<mikkelet@gmail.com>
Date2026-03-11 19:57:42 +0100
Concierge payment: Removed data from the route query params

Changed files

.../lib/_generated/data/remote/models/order.g.dart |  2 +-
 .../presentation/app/concierge_cubit.freezed.dart  | 43 ++++++++++---------
 .../receipt/bloc/receipt_state.freezed.dart        | 49 +++++++++-------------
 concierge/lib/concierge_route.dart                 | 12 +++---
 .../secure_storage/concierge_secure_storage.dart   | 10 ++---
 .../lib/data/remote/api/concierge_interceptor.dart |  1 +
 .../lib/data/remote/api/payment_interceptor.dart   |  4 +-
 concierge/lib/data/remote/models/order.dart        |  3 +-
 .../domain/repositories/property_repository.dart   | 19 +--------
 .../lib/presentation/app/concierge_cubit.dart      | 11 +----
 .../widgets/confirm_order_action_bar.dart          |  4 +-
 .../screens/payment/bloc/payment_cubit.dart        |  2 +-
 .../screens/payment/payment_screen.dart            |  2 +-
 .../product_details/product_details_screen.dart    |  2 +-
 .../screens/receipt/bloc/receipt_cubit.dart        |  6 ++-
 .../screens/receipt/bloc/receipt_state.dart        |  2 -
 .../receipt/widgets/receipt_action_bar.dart        |  5 ++-
 .../screens/receipt/widgets/receipt_card.dart      | 12 +++---
 concierge/lib/utils/context_utils.dart             | 17 ++++++++
 .../screens/payment_processing_page.dart           |  1 -
 20 files changed, 96 insertions(+), 111 deletions(-)

Diff

diff --git a/concierge/lib/_generated/data/remote/models/order.g.dart b/concierge/lib/_generated/data/remote/models/order.g.dart
index 0bcdea87..5743e8a4 100644
--- a/concierge/lib/_generated/data/remote/models/order.g.dart
+++ b/concierge/lib/_generated/data/remote/models/order.g.dart
@@ -16,7 +16,7 @@ Order _$OrderFromJson(Map json) => Order(
totalPrice: (json['total_price'] as num).toInt(),
deliveryMethod: json['delivery_method'] as String,
requestedDeliveryTime: json['requested_delivery_time'] as String,
- estimatedDeliveryTime: json['estimated_delivery_time'],
+ estimatedDeliveryTime: json['estimated_delivery_time'] as String? ?? 'ASAP',
pickupLocation: json['pickup_location'],
areaId: (json['area_id'] as num).toInt(),
locationId: (json['location_id'] as num?)?.toInt(),
diff --git a/concierge/lib/_generated/presentation/app/concierge_cubit.freezed.dart b/concierge/lib/_generated/presentation/app/concierge_cubit.freezed.dart
index 7c2973aa..7abfadf8 100644
--- a/concierge/lib/_generated/presentation/app/concierge_cubit.freezed.dart
+++ b/concierge/lib/_generated/presentation/app/concierge_cubit.freezed.dart
@@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$ConciergeState {
- Map<int, DataState> get products;
+ Map<int, DataState> get products; String get roomNumber;
/// Create a copy of ConciergeState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -25,16 +25,16 @@ $ConciergeStateCopyWith<ConciergeState> get copyWith => _$ConciergeStateCopyWith
@override
bool operator ==(Object other) {
- return identical(this, other) || (other.runtimeType == runtimeType&&other is ConciergeState&&const DeepCollectionEquality().equals(other.products, products));
+ return identical(this, other) || (other.runtimeType == runtimeType&&other is ConciergeState&&const DeepCollectionEquality().equals(other.products, products)&&(identical(other.roomNumber, roomNumber) || other.roomNumber == roomNumber));
}
@override
-int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(products));
+int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(products),roomNumber);
@override
String toString() {
- return 'ConciergeState(products: $products)';
+ return 'ConciergeState(products: $products, roomNumber: $roomNumber)';
}
@@ -45,7 +45,7 @@ abstract mixin class $ConciergeStateCopyWith<$Res> {
factory $ConciergeStateCopyWith(ConciergeState value, $Res Function(ConciergeState) _then) = _$ConciergeStateCopyWithImpl;
@useResult
$Res call({
- Map<int, DataState> products
+ Map<int, DataState> products, String roomNumber
});
@@ -62,10 +62,11 @@ class _$ConciergeStateCopyWithImpl<$Res>
/// Create a copy of ConciergeState
/// with the given fields replaced by the non-null parameter values.
-@pragma('vm:prefer-inline') @override $Res call({Object? products = null,}) {
+@pragma('vm:prefer-inline') @override $Res call({Object? products = null,Object? roomNumber = null,}) {
return _then(_self.copyWith(
products: null == products ? _self.products : products // ignore: cast_nullable_to_non_nullable
-as Map<int, DataState>,
+as Map<int, DataState>,roomNumber: null == roomNumber ? _self.roomNumber : roomNumber // ignore: cast_nullable_to_non_nullable
+as String,
));
}
@@ -150,10 +151,10 @@ return $default(_that);case _:
/// }
/// ```
-@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( Map<int, DataState> products)? $default,{required TResult orElse(),}) {final _that = this;
+@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( Map<int, DataState> products, String roomNumber)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _ConciergeState() when $default != null:
-return $default(_that.products);case _:
+return $default(_that.products,_that.roomNumber);case _:
return orElse();
}
@@ -171,10 +172,10 @@ return $default(_that.products);case _:
/// }
/// ```
-@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( Map<int, DataState> products) $default,) {final _that = this;
+@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( Map<int, DataState> products, String roomNumber) $default,) {final _that = this;
switch (_that) {
case _ConciergeState():
-return $default(_that.products);case _:
+return $default(_that.products,_that.roomNumber);case _:
throw StateError('Unexpected subclass');
}
@@ -191,10 +192,10 @@ return $default(_that.products);case _:
/// }
/// ```
-@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( Map<int, DataState> products)? $default,) {final _that = this;
+@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( Map<int, DataState> products, String roomNumber)? $default,) {final _that = this;
switch (_that) {
case _ConciergeState() when $default != null:
-return $default(_that.products);case _:
+return $default(_that.products,_that.roomNumber);case _:
return null;
}
@@ -206,7 +207,7 @@ return $default(_that.products);case _:
class _ConciergeState implements ConciergeState {
- const _ConciergeState({final Map<int, DataState> products = const {}}): _products = products;
+ const _ConciergeState({final Map<int, DataState> products = const {}, this.roomNumber = ""}): _products = products;
final Map<int, DataState> _products;
@@ -216,6 +217,7 @@ class _ConciergeState implements ConciergeState {
return EqualUnmodifiableMapView(_products);
}
+@override@JsonKey() final String roomNumber;
/// Create a copy of ConciergeState
/// with the given fields replaced by the non-null parameter values.
@@ -227,16 +229,16 @@ _$ConciergeStateCopyWith<_ConciergeState> get copyWith => __$ConciergeStateCopyW
@override
bool operator ==(Object other) {
- return identical(this, other) || (other.runtimeType == runtimeType&&other is _ConciergeState&&const DeepCollectionEquality().equals(other._products, _products));
+ return identical(this, other) || (other.runtimeType == runtimeType&&other is _ConciergeState&&const DeepCollectionEquality().equals(other._products, _products)&&(identical(other.roomNumber, roomNumber) || other.roomNumber == roomNumber));
}
@override
-int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_products));
+int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_products),roomNumber);
@override
String toString() {
- return 'ConciergeState(products: $products)';
+ return 'ConciergeState(products: $products, roomNumber: $roomNumber)';
}
@@ -247,7 +249,7 @@ abstract mixin class _$ConciergeStateCopyWith<$Res> implements $ConciergeStateCo
factory _$ConciergeStateCopyWith(_ConciergeState value, $Res Function(_ConciergeState) _then) = __$ConciergeStateCopyWithImpl;
@override @useResult
$Res call({
- Map<int, DataState> products
+ Map<int, DataState> products, String roomNumber
});
@@ -264,10 +266,11 @@ class __$ConciergeStateCopyWithImpl<$Res>
/// Create a copy of ConciergeState
/// with the given fields replaced by the non-null parameter values.
-@override @pragma('vm:prefer-inline') $Res call({Object? products = null,}) {
+@override @pragma('vm:prefer-inline') $Res call({Object? products = null,Object? roomNumber = null,}) {
return _then(_ConciergeState(
products: null == products ? _self._products : products // ignore: cast_nullable_to_non_nullable
-as Map<int, DataState>,
+as Map<int, DataState>,roomNumber: null == roomNumber ? _self.roomNumber : roomNumber // ignore: cast_nullable_to_non_nullable
+as String,
));
}
diff --git a/concierge/lib/_generated/presentation/screens/receipt/bloc/receipt_state.freezed.dart b/concierge/lib/_generated/presentation/screens/receipt/bloc/receipt_state.freezed.dart
index 798010b8..a5458491 100644
--- a/concierge/lib/_generated/presentation/screens/receipt/bloc/receipt_state.freezed.dart
+++ b/concierge/lib/_generated/presentation/screens/receipt/bloc/receipt_state.freezed.dart
@@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$ReceiptState {
- bool get isLoading; List<OrderItem> get items; AppError get error;
+ bool get isLoading; AppError get error;
/// Create a copy of ReceiptState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -25,16 +25,16 @@ $ReceiptStateCopyWith<ReceiptState> get copyWith => _$ReceiptStateCopyWithImpl<R
@override
bool operator ==(Object other) {
- return identical(this, other) || (other.runtimeType == runtimeType&&other is ReceiptState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&const DeepCollectionEquality().equals(other.items, items)&&(identical(other.error, error) || other.error == error));
+ return identical(this, other) || (other.runtimeType == runtimeType&&other is ReceiptState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.error, error) || other.error == error));
}
@override
-int get hashCode => Object.hash(runtimeType,isLoading,const DeepCollectionEquality().hash(items),error);
+int get hashCode => Object.hash(runtimeType,isLoading,error);
@override
String toString() {
- return 'ReceiptState(isLoading: $isLoading, items: $items, error: $error)';
+ return 'ReceiptState(isLoading: $isLoading, error: $error)';
}
@@ -45,7 +45,7 @@ abstract mixin class $ReceiptStateCopyWith<$Res> {
factory $ReceiptStateCopyWith(ReceiptState value, $Res Function(ReceiptState) _then) = _$ReceiptStateCopyWithImpl;
@useResult
$Res call({
- bool isLoading, List<OrderItem> items, AppError error
+ bool isLoading, AppError error
});
@@ -62,11 +62,10 @@ class _$ReceiptStateCopyWithImpl<$Res>
/// Create a copy of ReceiptState
/// with the given fields replaced by the non-null parameter values.
-@pragma('vm:prefer-inline') @override $Res call({Object? isLoading = null,Object? items = null,Object? error = null,}) {
+@pragma('vm:prefer-inline') @override $Res call({Object? isLoading = null,Object? error = null,}) {
return _then(_self.copyWith(
isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
-as bool,items: null == items ? _self.items : items // ignore: cast_nullable_to_non_nullable
-as List<OrderItem>,error: null == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
+as bool,error: null == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
as AppError,
));
}
@@ -152,10 +151,10 @@ return $default(_that);case _:
/// }
/// ```
-@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isLoading, List<OrderItem> items, AppError error)? $default,{required TResult orElse(),}) {final _that = this;
+@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isLoading, AppError error)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _ReceiptState() when $default != null:
-return $default(_that.isLoading,_that.items,_that.error);case _:
+return $default(_that.isLoading,_that.error);case _:
return orElse();
}
@@ -173,10 +172,10 @@ return $default(_that.isLoading,_that.items,_that.error);case _:
/// }
/// ```
-@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isLoading, List<OrderItem> items, AppError error) $default,) {final _that = this;
+@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isLoading, AppError error) $default,) {final _that = this;
switch (_that) {
case _ReceiptState():
-return $default(_that.isLoading,_that.items,_that.error);case _:
+return $default(_that.isLoading,_that.error);case _:
throw StateError('Unexpected subclass');
}
@@ -193,10 +192,10 @@ return $default(_that.isLoading,_that.items,_that.error);case _:
/// }
/// ```
-@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isLoading, List<OrderItem> items, AppError error)? $default,) {final _that = this;
+@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isLoading, AppError error)? $default,) {final _that = this;
switch (_that) {
case _ReceiptState() when $default != null:
-return $default(_that.isLoading,_that.items,_that.error);case _:
+return $default(_that.isLoading,_that.error);case _:
return null;
}
@@ -208,17 +207,10 @@ return $default(_that.isLoading,_that.items,_that.error);case _:
class _ReceiptState implements ReceiptState {
- const _ReceiptState({this.isLoading = false, final List<OrderItem> items = const [], this.error = AppError.none}): _items = items;
+ const _ReceiptState({this.isLoading = false, this.error = AppError.none});
@override@JsonKey() final bool isLoading;
- final List<OrderItem> _items;
-@override@JsonKey() List<OrderItem> get items {
- if (_items is EqualUnmodifiableListView) return _items;
- // ignore: implicit_dynamic_type
- return EqualUnmodifiableListView(_items);
-}
-
@override@JsonKey() final AppError error;
/// Create a copy of ReceiptState
@@ -231,16 +223,16 @@ _$ReceiptStateCopyWith<_ReceiptState> get copyWith => __$ReceiptStateCopyWithImp
@override
bool operator ==(Object other) {
- return identical(this, other) || (other.runtimeType == runtimeType&&other is _ReceiptState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&const DeepCollectionEquality().equals(other._items, _items)&&(identical(other.error, error) || other.error == error));
+ return identical(this, other) || (other.runtimeType == runtimeType&&other is _ReceiptState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.error, error) || other.error == error));
}
@override
-int get hashCode => Object.hash(runtimeType,isLoading,const DeepCollectionEquality().hash(_items),error);
+int get hashCode => Object.hash(runtimeType,isLoading,error);
@override
String toString() {
- return 'ReceiptState(isLoading: $isLoading, items: $items, error: $error)';
+ return 'ReceiptState(isLoading: $isLoading, error: $error)';
}
@@ -251,7 +243,7 @@ abstract mixin class _$ReceiptStateCopyWith<$Res> implements $ReceiptStateCopyWi
factory _$ReceiptStateCopyWith(_ReceiptState value, $Res Function(_ReceiptState) _then) = __$ReceiptStateCopyWithImpl;
@override @useResult
$Res call({
- bool isLoading, List<OrderItem> items, AppError error
+ bool isLoading, AppError error
});
@@ -268,11 +260,10 @@ class __$ReceiptStateCopyWithImpl<$Res>
/// Create a copy of ReceiptState
/// with the given fields replaced by the non-null parameter values.
-@override @pragma('vm:prefer-inline') $Res call({Object? isLoading = null,Object? items = null,Object? error = null,}) {
+@override @pragma('vm:prefer-inline') $Res call({Object? isLoading = null,Object? error = null,}) {
return _then(_ReceiptState(
isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
-as bool,items: null == items ? _self._items : items // ignore: cast_nullable_to_non_nullable
-as List<OrderItem>,error: null == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
+as bool,error: null == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
as AppError,
));
}
diff --git a/concierge/lib/concierge_route.dart b/concierge/lib/concierge_route.dart
index 7cb64421..6a3bece3 100644
--- a/concierge/lib/concierge_route.dart
+++ b/concierge/lib/concierge_route.dart
@@ -11,8 +11,8 @@ import 'package:concierge/presentation/screens/review_order/review_order_route.d
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:go_router/go_router.dart';
import 'package:payment_plugin/payment_plugin.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
@@ -22,16 +22,15 @@ import 'data/remote/api/concierge_service.dart';
import 'domain/repositories/property_repository.dart';
import 'flavors.dart';
-final _rootNavigatorKey = GlobalKey<NavigatorState>();
+final conciergeNavigatorKey = GlobalKey<NavigatorState>();
final conciergeShellRoute = StatefulShellRoute.indexedStack(
redirect: (context, state) {
- if(state.matchedLocation == "/exit") context.pop();
return null;
},
branches: [
StatefulShellBranch(
- navigatorKey: _rootNavigatorKey,
+ navigatorKey: conciergeNavigatorKey,
routes: [
$hotelOverviewPageRoute,
$productDetailsRoute,
@@ -45,15 +44,14 @@ final conciergeShellRoute = StatefulShellRoute.indexedStack(
],
builder: (context, state, child) {
Future<(ConciergeService, ConciergeSecureStorage, Dio)> getDependencies() async {
+ F.appFlavor = Flavor.values.firstWhere((flavor) => flavor.name == appFlavor);
final storage = ConciergeSecureStorage();
final dio = Dio(BaseOptions(baseUrl: F.baseConciergeUrl));
dio.interceptors.addAll([
ConciergeInterceptor(storage),
if (kDebugMode) PrettyDioLogger(requestBody: true, requestHeader: true),
]);
- final apimDio = Dio(
- BaseOptions(baseUrl: F.baseApimUrl),
- );
+ final apimDio = Dio(BaseOptions(baseUrl: F.baseApimUrl));
apimDio.interceptors.addAll([
PaymentInterceptor(storage),
if (kDebugMode) PrettyDioLogger(requestBody: true, requestHeader: true),
diff --git a/concierge/lib/data/local/secure_storage/concierge_secure_storage.dart b/concierge/lib/data/local/secure_storage/concierge_secure_storage.dart
index a8b4b714..577e37a3 100644
--- a/concierge/lib/data/local/secure_storage/concierge_secure_storage.dart
+++ b/concierge/lib/data/local/secure_storage/concierge_secure_storage.dart
@@ -2,7 +2,7 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class ConciergeSecureStorage {
static const _tokenKey = 'concierge_user_token';
- static const _subscriptionKey = 'subscription_key';
+ static const _roomNumber = 'room_number';
final FlutterSecureStorage _storage = FlutterSecureStorage(
iOptions: IOSOptions(groupId: "concierge"),
@@ -19,12 +19,12 @@ class ConciergeSecureStorage {
return _storage.read(key: _tokenKey);
}
- Future<void> setSubscriptionKey(String value) async {
- await _storage.write(key: _subscriptionKey, value: value);
+ Future<void> setRoomNumber(String value) async {
+ await _storage.write(key: _roomNumber, value: value);
}
- Future<String> getSubscriptionKey() async {
- return await _storage.read(key: _subscriptionKey) ?? "";
+ Future<String> getRoomNumber() async {
+ return await _storage.read(key: _roomNumber) ?? "";
}
Future<void> dispose() async {
diff --git a/concierge/lib/data/remote/api/concierge_interceptor.dart b/concierge/lib/data/remote/api/concierge_interceptor.dart
index a88847d8..98fabf6d 100644
--- a/concierge/lib/data/remote/api/concierge_interceptor.dart
+++ b/concierge/lib/data/remote/api/concierge_interceptor.dart
@@ -12,6 +12,7 @@ class ConciergeInterceptor extends Interceptor {
if (token != null) {
options.headers["X-Authorization"] = token;
}
+ options.headers["Accept"] = "application/json";
super.onRequest(options, handler);
}
}
diff --git a/concierge/lib/data/remote/api/payment_interceptor.dart b/concierge/lib/data/remote/api/payment_interceptor.dart
index 0708957f..67b5c599 100644
--- a/concierge/lib/data/remote/api/payment_interceptor.dart
+++ b/concierge/lib/data/remote/api/payment_interceptor.dart
@@ -1,5 +1,6 @@
import 'package:concierge/data/local/secure_storage/concierge_secure_storage.dart';
import 'package:dio/dio.dart';
+import 'package:flutter_dotenv/flutter_dotenv.dart';
class PaymentInterceptor extends Interceptor {
final ConciergeSecureStorage _conciergeSecureStorage;
@@ -12,8 +13,7 @@ class PaymentInterceptor extends Interceptor {
if (token != null) {
options.headers["Authorization"] = token;
}
- options.headers["Ocp-Apim-Subscription-Key"] = await _conciergeSecureStorage
- .getSubscriptionKey();
+ options.headers["Ocp-Apim-Subscription-Key"] = dotenv.get("OCP_APIM_SUBSCRIPTION_KEY");
super.onRequest(options, handler);
}
}
diff --git a/concierge/lib/data/remote/models/order.dart b/concierge/lib/data/remote/models/order.dart
index 2f8355de..f32b4c30 100644
--- a/concierge/lib/data/remote/models/order.dart
+++ b/concierge/lib/data/remote/models/order.dart
@@ -17,7 +17,8 @@ class Order {
final int totalPrice;
final String deliveryMethod;
final String requestedDeliveryTime;
- final dynamic estimatedDeliveryTime;
+ @JsonKey(defaultValue: "ASAP")
+ final String estimatedDeliveryTime;
final dynamic pickupLocation;
final int areaId;
final int? locationId;
diff --git a/concierge/lib/domain/repositories/property_repository.dart b/concierge/lib/domain/repositories/property_repository.dart
index 22abc23b..8612a5b1 100644
--- a/concierge/lib/domain/repositories/property_repository.dart
+++ b/concierge/lib/domain/repositories/property_repository.dart
@@ -1,7 +1,6 @@
import 'package:concierge/data/remote/api/concierge_service.dart';
import 'package:concierge/data/remote/models/area_details.dart';
import 'package:concierge/data/remote/models/order.dart';
-import 'package:concierge/data/remote/models/order_review.dart';
import 'package:concierge/data/remote/models/product.dart';
import 'package:concierge/data/remote/models/property.dart';
import 'package:concierge/domain/models/delivery_location.dart';
@@ -44,6 +43,7 @@ class PropertyRepository {
"requested_delivery_time": readyTime.isEmpty ? "ASAP" : readyTime,
"payment_type": chargeToRoom ? "ROOM" : "PAYMENT_SERVICE",
"customer_comment": comment,
+ "order_type": "PRODUCT"
};
if (deliveryLocation is Room) {
body["room"] = roomNumber;
@@ -54,23 +54,6 @@ class PropertyRepository {
return response.data;
}
- Future<OrderReview> reviewOrder() async {
- final body = {
- "area_id": 46,
- "location_code": "null",
- "delivery": true,
- "requested_delivery_time": "ASAP",
- "payment_type": "null",
- "full_name": "null",
- "customer_id": "null",
- "customer_name": "",
- "customer_comment": "",
- "order_type": "PRODUCT",
- };
- final response = await _service.getOrderReview(body);
- return response.data;
- }
-
Future<Order> getOrder(int id) async {
final response = await _service.getOrder(id.toString());
return response.data;
diff --git a/concierge/lib/presentation/app/concierge_cubit.dart b/concierge/lib/presentation/app/concierge_cubit.dart
index 7f403ff2..f8759ae6 100644
--- a/concierge/lib/presentation/app/concierge_cubit.dart
+++ b/concierge/lib/presentation/app/concierge_cubit.dart
@@ -1,4 +1,3 @@
-import 'package:concierge/concierge.dart';
import 'package:concierge/data/local/secure_storage/concierge_secure_storage.dart';
import 'package:concierge/data/remote/models/product.dart';
import 'package:concierge/domain/models/app_error.dart';
@@ -23,14 +22,9 @@ class ConciergeCubit extends BaseCubit<ConciergeState> {
}
Future<void> init() async {
- final flavorName = launchParameters["flavor"] ?? "";
final authToken = launchParameters["auth-token"] ?? "";
- final subscriptionKey = launchParameters["sub-key"] ?? "";
+
if (authToken.isNotEmpty) await _storage.setUserToken(authToken);
- if (subscriptionKey.isNotEmpty) await _storage.setSubscriptionKey(subscriptionKey);
- if (flavorName.isNotEmpty) {
- F.appFlavor = Flavor.values.firstWhere((flavor) => flavor.name == flavorName);
- }
}
DataState getProductState(int pId) {
@@ -63,8 +57,6 @@ class ConciergeCubit extends BaseCubit<ConciergeState> {
safeEmit(state.copyWith(products: copy));
}
- String get roomNumber => launchParameters["room-number"] ?? "0";
-
@override
Future<void> close() async {
await _storage.dispose();
@@ -76,5 +68,6 @@ class ConciergeCubit extends BaseCubit<ConciergeState> {
abstract class ConciergeState with _$ConciergeState {
const factory ConciergeState({
@Default({}) Map<int, DataState> products,
+ @Default("") String roomNumber,
}) = _ConciergeState;
}
diff --git a/concierge/lib/presentation/screens/confirm_order/widgets/confirm_order_action_bar.dart b/concierge/lib/presentation/screens/confirm_order/widgets/confirm_order_action_bar.dart
index 611ffa0d..a716986c 100644
--- a/concierge/lib/presentation/screens/confirm_order/widgets/confirm_order_action_bar.dart
+++ b/concierge/lib/presentation/screens/confirm_order/widgets/confirm_order_action_bar.dart
@@ -20,8 +20,8 @@ class ConfirmOrderActionBar extends StatelessWidget {
backgroundColor: WidgetStatePropertyAll(AppColors.sandColor),
minimumSize: WidgetStatePropertyAll(Size(0, 50)),
),
- onPressed: () {
- PaymentRoute().push(context);
+ onPressed: () async {
+ PaymentRoute().replace(context);
},
child: Text(
context.strings.confirm_order,
diff --git a/concierge/lib/presentation/screens/payment/bloc/payment_cubit.dart b/concierge/lib/presentation/screens/payment/bloc/payment_cubit.dart
index 2da65ed0..fb8a9089 100644
--- a/concierge/lib/presentation/screens/payment/bloc/payment_cubit.dart
+++ b/concierge/lib/presentation/screens/payment/bloc/payment_cubit.dart
@@ -56,7 +56,7 @@ class PaymentCubit extends BaseCubit<PaymentState> {
final orderResponse = await _propertyRepository.createOrder(
products: products.toList(),
areaId: area.id,
- roomNumber: _conciergeCubit.roomNumber,
+ roomNumber: _conciergeCubit.state.roomNumber,
isDelivery: _cartCubit.state.isDelivery,
locationCode: _cartCubit.state.deliveryLocationCode,
deliveryLocation: _cartCubit.state.deliveryLocation,
diff --git a/concierge/lib/presentation/screens/payment/payment_screen.dart b/concierge/lib/presentation/screens/payment/payment_screen.dart
index f0ad7c4e..bfe24f76 100644
--- a/concierge/lib/presentation/screens/payment/payment_screen.dart
+++ b/concierge/lib/presentation/screens/payment/payment_screen.dart
@@ -28,7 +28,7 @@ class PaymentScreen extends StatelessWidget {
BlocListener<PaymentCubit, PaymentState>(
listenWhen: (prev, curr) => !prev.paymentSuccess && curr.paymentSuccess,
listener: (context, state) {
- ReceiptRoute(orderId: state.orderId).go(context);
+ ReceiptRoute(orderId: state.orderId).replace(context);
},
),
],
diff --git a/concierge/lib/presentation/screens/product_details/product_details_screen.dart b/concierge/lib/presentation/screens/product_details/product_details_screen.dart
index 91c09ee2..9d5812ab 100644
--- a/concierge/lib/presentation/screens/product_details/product_details_screen.dart
+++ b/concierge/lib/presentation/screens/product_details/product_details_screen.dart
@@ -33,7 +33,7 @@ class ProductDetailsScreen extends StatelessWidget {
children: [
Builder(
builder: (context) {
- if (state.isLoading) {
+ if (state.isLoading || state.product == null) {
return Center(child: CircularProgressIndicator());
}
if (state.error.isError) {
diff --git a/concierge/lib/presentation/screens/receipt/bloc/receipt_cubit.dart b/concierge/lib/presentation/screens/receipt/bloc/receipt_cubit.dart
index 85931d7c..7e993fcc 100644
--- a/concierge/lib/presentation/screens/receipt/bloc/receipt_cubit.dart
+++ b/concierge/lib/presentation/screens/receipt/bloc/receipt_cubit.dart
@@ -1,3 +1,4 @@
+import 'package:concierge/data/remote/models/order.dart';
import 'package:concierge/domain/models/app_error.dart';
import 'package:concierge/domain/repositories/property_repository.dart';
import 'package:concierge/presentation/base/base_cubit.dart';
@@ -7,6 +8,8 @@ class ReceiptCubit extends BaseCubit<ReceiptState> {
final int orderId;
final PropertyRepository _propertyRepository;
+ late final Order order;
+
ReceiptCubit(this._propertyRepository, {required this.orderId}) : super(const ReceiptState()) {
init();
}
@@ -15,8 +18,7 @@ class ReceiptCubit extends BaseCubit<ReceiptState> {
try {
safeEmit(state.copyWith(isLoading: true));
final response = await _propertyRepository.getOrder(orderId);
- final products = response.orderItems;
- safeEmit(state.copyWith(items: products));
+ order = response;
} catch (e, st) {
handleError(e, st);
safeEmit(state.copyWith(error: AppError.unknown(e.toString())));
diff --git a/concierge/lib/presentation/screens/receipt/bloc/receipt_state.dart b/concierge/lib/presentation/screens/receipt/bloc/receipt_state.dart
index 7b8d8524..cdc12f4e 100644
--- a/concierge/lib/presentation/screens/receipt/bloc/receipt_state.dart
+++ b/concierge/lib/presentation/screens/receipt/bloc/receipt_state.dart
@@ -1,4 +1,3 @@
-import 'package:concierge/data/remote/models/order.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:concierge/domain/models/app_error.dart';
@@ -8,7 +7,6 @@ part '../../../../_generated/presentation/screens/receipt/bloc/receipt_state.fre
abstract class ReceiptState with _$ReceiptState {
const factory ReceiptState({
@Default(false) bool isLoading,
- @Default([]) List<OrderItem> items,
@Default(AppError.none) AppError error,
}) = _ReceiptState;
}
diff --git a/concierge/lib/presentation/screens/receipt/widgets/receipt_action_bar.dart b/concierge/lib/presentation/screens/receipt/widgets/receipt_action_bar.dart
index 3fc27a0c..00794140 100644
--- a/concierge/lib/presentation/screens/receipt/widgets/receipt_action_bar.dart
+++ b/concierge/lib/presentation/screens/receipt/widgets/receipt_action_bar.dart
@@ -1,6 +1,7 @@
import 'package:common/localization/l10n_utils.dart';
+import 'package:concierge/presentation/navigation/app_routes.dart';
+import 'package:concierge/utils/context_utils.dart';
import 'package:flutter/material.dart';
-import 'package:go_router/go_router.dart';
class ReceiptActionBar extends StatelessWidget {
const ReceiptActionBar({super.key});
@@ -12,7 +13,7 @@ class ReceiptActionBar extends StatelessWidget {
padding: EdgeInsets.all(16),
child: TextButton(
onPressed: () {
- context.go("/exit");
+ context.popUntil(AppRoutes.hotelOverviewPage);
},
style: ButtonStyle(
minimumSize: WidgetStatePropertyAll(Size(0, 50)),
diff --git a/concierge/lib/presentation/screens/receipt/widgets/receipt_card.dart b/concierge/lib/presentation/screens/receipt/widgets/receipt_card.dart
index 69412029..662f90a4 100644
--- a/concierge/lib/presentation/screens/receipt/widgets/receipt_card.dart
+++ b/concierge/lib/presentation/screens/receipt/widgets/receipt_card.dart
@@ -1,5 +1,4 @@
import 'package:common/localization/l10n_utils.dart';
-import 'package:concierge/presentation/app/cart_cubit.dart';
import 'package:concierge/presentation/screens/confirm_order/widgets/confirm_order_product_list_tile.dart';
import 'package:concierge/presentation/screens/receipt/bloc/receipt_cubit.dart';
import 'package:concierge/presentation/widgets/padded_column.dart';
@@ -12,8 +11,7 @@ class ReceiptCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
- final cubit = context.read<CartCubit>();
-
+ final cubit = context.read<ReceiptCubit>();
return Container(
height: 500,
decoration: BoxDecoration(
@@ -29,11 +27,11 @@ class ReceiptCard extends StatelessWidget {
child: Stack(
alignment: Alignment.topLeft,
children: [
- Image.network(cubit.products.first.images.first.url),
+ Image.network(cubit.order.image.url),
Padding(
padding: EdgeInsets.all(12),
child: Text(
- "${context.strings.order_to_room} 106",
+ "${context.strings.order_to_room} ${cubit.order.payment.room}",
style: TextStyle(fontSize: 20, color: Colors.white),
),
),
@@ -56,7 +54,7 @@ class ReceiptCard extends StatelessWidget {
style: TextStyle(fontSize: 14, color: Colors.grey),
),
const Gap(4),
- Text("14:55"),
+ Text(cubit.order.estimatedDeliveryTime),
const Gap(16),
Row(
children: [
@@ -84,7 +82,7 @@ class ReceiptCard extends StatelessWidget {
Iterable<Widget> buildOrder(BuildContext context) sync* {
final cubit = context.read<ReceiptCubit>();
yield Divider(color: Colors.grey.shade300);
- for (final orderItem in cubit.state.items) {
+ for (final orderItem in cubit.order.orderItems) {
yield ConfirmOrderProductListTile(
quantity: orderItem.quantity,
price: orderItem.price.toDouble(),
diff --git a/concierge/lib/utils/context_utils.dart b/concierge/lib/utils/context_utils.dart
new file mode 100644
index 00000000..608b61ce
--- /dev/null
+++ b/concierge/lib/utils/context_utils.dart
@@ -0,0 +1,17 @@
+import 'package:flutter/cupertino.dart';
+import 'package:go_router/go_router.dart';
+
+extension ContextUtils on BuildContext {
+ Future<void> popUntil(String route) async {
+ while (route != _matchedLocation && canPop()) {
+ await Future.delayed(Duration(milliseconds: 10));
+ pop();
+ }
+ }
+
+ String get _matchedLocation => router?.state.matchedLocation ?? "";
+
+ GoRouter? get router {
+ return GoRouter.of(this);
+ }
+}
diff --git a/payment_plugin/lib/presentation/screens/payment_processing_page.dart b/payment_plugin/lib/presentation/screens/payment_processing_page.dart
index 79287c5c..58cdb603 100644
--- a/payment_plugin/lib/presentation/screens/payment_processing_page.dart
+++ b/payment_plugin/lib/presentation/screens/payment_processing_page.dart
@@ -92,7 +92,6 @@ class _PaymentProcessingPageState extends State<PaymentProcessingPage>
child: BlocListener<PaymentCubit, PaymentProcessingState>(
listenWhen: (prev, curr) => prev != curr,
listener: (context, state) {
- print("qqq paymentProcessingState=${state.runtimeType}");
if (state is PaymentProcessingStateSessionReceived) {
showAdyenModal(context);
} else if (state is PaymentProcessingStateError) {