Repository: kiwicom/mobile
Pull request #1287 (2018-11-05 15:52:30)

Hotels: Add stay 22 detail query support
Waiting for gql PR to be merged first

tbergq: @RobinCsl please review again


Patch:
diff --git a/app/hotels/src/HotelsContext.js b/app/hotels/src/HotelsContext.js
index 364b67da..4383b1b8 100644
--- a/app/hotels/src/HotelsContext.js
+++ b/app/hotels/src/HotelsContext.js
@@ -21,6 +21,7 @@ const defaultState = {
   actions: {
     setCurrentSearchStats: () => {},
   },
+  getGuestCount: () => 0,
 };
 
 const { Consumer, Provider: ContextProvider } = React.createContext({
@@ -58,6 +59,7 @@ export type State = {|
   currentSearchStats: CurrentSearchStats,
   +latitude: number | null,
   +longitude: number | null,
+  +getGuestCount: () => number,
   +actions: {|
     +setCurrentSearchStats: ({|
       priceMax: number,
@@ -97,6 +99,7 @@ class Provider extends React.Component<Props, State> {
         priceMax: 10000,
         priceMin: 0,
       },
+      getGuestCount: this.getGuestCount,
       actions: {
         setCurrentSearchStats: this.setCurrentSearchStats,
       },
@@ -109,6 +112,17 @@ class Provider extends React.Component<Props, State> {
     });
   };
 
+  getGuestCount = () => {
+    if (this.state.roomsConfiguration == null) {
+      return 0;
+    }
+    return this.state.roomsConfiguration.reduce((sum, current) => {
+      const adults = current.adultsCount;
+      const children = current?.children?.length ?? 0;
+      return sum + adults + children;
+    }, 0);
+  };
+
   render = () => (
     <ContextProvider value={this.state}>{this.props.children}</ContextProvider>
   );
diff --git a/app/hotels/src/allHotels/AllHotelsSearchRow.js b/app/hotels/src/allHotels/AllHotelsSearchRow.js
index 01c8344e..042af9fa 100644
--- a/app/hotels/src/allHotels/AllHotelsSearchRow.js
+++ b/app/hotels/src/allHotels/AllHotelsSearchRow.js
@@ -20,7 +20,9 @@ import { type RoomConfigurationType } from '../HotelsContext';
 import HotelTitle from './HotelTitle';
 import HotelReviewScore from '../components/HotelReviewScore';
 import type { AllHotelsSearchRow as AllHotelsSearchRowProps } from './__generated__/AllHotelsSearchRow.graphql';
-import SingleHotelContext from '../navigation/singleHotel/SingleHotelContext';
+import SingleHotelContext, {
+  type ApiProvider,
+} from '../navigation/singleHotel/SingleHotelContext';
 
 type PropsWithContext = {|
   ...Props,
@@ -29,6 +31,7 @@ type PropsWithContext = {|
   +checkin: Date,
   +checkout: Date,
   +roomsConfiguration: RoomConfigurationType,
+  +apiProvider: ApiProvider,
 |};
 
 class AllHotelsSearchRow extends React.Component<PropsWithContext> {
@@ -40,6 +43,7 @@ class AllHotelsSearchRow extends React.Component<PropsWithContext> {
         checkin: this.props.checkin,
         checkout: this.props.checkout,
         roomsConfiguration: this.props.roomsConfiguration,
+        apiProvider: this.props.apiProvider,
       });
     }
   };
diff --git a/app/hotels/src/allHotels/Stay22HotelsSearch.js b/app/hotels/src/allHotels/Stay22HotelsSearch.js
index b3282ffa..0c9dcdb3 100644
--- a/app/hotels/src/allHotels/Stay22HotelsSearch.js
+++ b/app/hotels/src/allHotels/Stay22HotelsSearch.js
@@ -4,12 +4,8 @@ import * as React from 'react';
 import { graphql, PublicApiRenderer } from '@kiwicom/mobile-relay';
 import { DateFormatter, Translation } from '@kiwicom/mobile-localization';
 import { GeneralError } from '@kiwicom/mobile-shared';
-import idx from 'idx';
 
-import {
-  type RoomConfigurationType,
-  withHotelsContext,
-} from '../HotelsContext';
+import { withHotelsContext } from '../HotelsContext';
 import type { Stay22HotelsSearchQueryResponse } from './__generated__/Stay22HotelsSearchQuery.graphql';
 import Stay22PaginationContainer from './Stay22PaginationContainer';
 
@@ -17,7 +13,7 @@ type Props = {|
   +checkin: Date | null,
   +checkout: Date | null,
   +currency: string,
-  +roomsConfiguration: RoomConfigurationType | null,
+  +getGuestCount: () => number,
   +longitude: number | null,
   +latitude: number | null,
 |};
@@ -29,17 +25,6 @@ export class Stay22HotelsSearch extends React.Component<Props> {
     return <Stay22PaginationContainer data={propsFromRenderer} />;
   };
 
-  getGuests = () => {
-    if (this.props.roomsConfiguration === null) {
-      return 0;
-    }
-    return this.props.roomsConfiguration.reduce((sum, current) => {
-      const adults = current.adultsCount;
-      const children = idx(current, _ => _.children.length) || 0;
-      return sum + adults + children;
-    }, 0);
-  };
-
   render = () => {
     const { checkin, checkout, latitude, longitude, currency } = this.props;
     if (
@@ -75,7 +60,7 @@ export class Stay22HotelsSearch extends React.Component<Props> {
             longitude,
             checkin: DateFormatter(checkin).formatForMachine(),
             checkout: DateFormatter(checkout).formatForMachine(),
-            guests: this.getGuests(),
+            guests: this.props.getGuestCount(),
             currency,
           },
         }}
@@ -89,7 +74,7 @@ export default withHotelsContext(state => ({
   checkin: state.checkin,
   checkout: state.checkout,
   currency: state.currency,
-  roomsConfiguration: state.roomsConfiguration,
+  getGuestCount: state.getGuestCount,
   latitude: state.latitude,
   longitude: state.longitude,
 }))(Stay22HotelsSearch);
diff --git a/app/hotels/src/map/allHotels/HotelSwipeItem.js b/app/hotels/src/map/allHotels/HotelSwipeItem.js
index 4433e886..eadc900b 100644
--- a/app/hotels/src/map/allHotels/HotelSwipeItem.js
+++ b/app/hotels/src/map/allHotels/HotelSwipeItem.js
@@ -92,10 +92,20 @@ class HotelSwipeItem extends React.Component<Props> {
     </SingleHotelContext.Consumer>
   );
 
-  renderSingleHotelContext = (width: number) => context => (
+  renderSingleHotelContext = (width: number) => ({
+    setHotelId,
+    hotelId,
+    checkin,
+    checkout,
+    roomsConfiguration,
+  }) => (
     <HotelSwipeItemWithContext
       {...this.props}
-      {...context}
+      setHotelId={setHotelId}
+      hotelId={hotelId}
+      checkin={checkin}
+      checkout={checkout}
+      roomsConfiguration={roomsConfiguration}
       deviceWidth={width}
     />
   );
diff --git a/app/hotels/src/navigation/allHotels/SearchResultsScreen.js b/app/hotels/src/navigation/allHotels/SearchResultsScreen.js
index 1ed599b8..590404e7 100644
--- a/app/hotels/src/navigation/allHotels/SearchResultsScreen.js
+++ b/app/hotels/src/navigation/allHotels/SearchResultsScreen.js
@@ -23,7 +23,9 @@ import {
 } from './SearchResultsContext';
 import SingleHotelContainer from '../../singleHotel/SingleHotelContainer';
 import type { RoomsConfiguration } from '../../singleHotel/AvailableHotelSearchInput';
-import SingleHotelContext from '../singleHotel/SingleHotelContext';
+import SingleHotelContext, {
+  type ApiProvider,
+} from '../singleHotel/SingleHotelContext';
 
 type Props = {|
   +navigation: NavigationType,
@@ -35,6 +37,7 @@ type Props = {|
   +lastNavigationMode?: 'present' | 'push',
   +setResultType: (show: ResultType) => void,
   +show: ResultType,
+  +cityId?: string,
 |};
 
 const noop = () => {};
@@ -134,26 +137,33 @@ class SearchResultsScreen extends React.Component<Props> {
     }
   };
 
-  render = () => (
-    <SingleHotelContext.Provider
-      hotelId={''}
-      checkin={new Date(this.props.checkin)}
-      checkout={new Date(this.props.checkout)}
-      roomsConfiguration={this.props.roomsConfiguration}
-    >
-      <LayoutDoubleColumn
-        menuComponent={
-          <View style={styles.container}>
-            <NewAllHotels />
-            <View style={styles.button}>
-              <CloseButton onPress={this.onClosePress} />
+  render() {
+    // Stay 22 only supports searching with gps coordinates, if we get passed a cityId from native
+    // we are using booking.com, if we don't get cityId, we should have coordinates, and we are using stay22 provider
+    const apiProvider: ApiProvider =
+      this.props.cityId == null ? 'stay22' : 'booking';
+    return (
+      <SingleHotelContext.Provider
+        hotelId={''}
+        checkin={new Date(this.props.checkin)}
+        checkout={new Date(this.props.checkout)}
+        roomsConfiguration={this.props.roomsConfiguration}
+        apiProvider={apiProvider}
+      >
+        <LayoutDoubleColumn
+          menuComponent={
+            <View style={styles.container}>
+              <NewAllHotels />
+              <View style={styles.button}>
+                <CloseButton onPress={this.onClosePress} />
+              </View>
             </View>
-          </View>
-        }
-        containerComponent={<SingleHotelContainer goBack={noop} />}
-      />
-    </SingleHotelContext.Provider>
-  );
+          }
+          containerComponent={<SingleHotelContainer goBack={noop} />}
+        />
+      </SingleHotelContext.Provider>
+    );
+  }
 }
 
 const styles = StyleSheet.create({
diff --git a/app/hotels/src/navigation/singleHotel/SingleHotelContext.js b/app/hotels/src/navigation/singleHotel/SingleHotelContext.js
index b91403da..68d6b202 100644
--- a/app/hotels/src/navigation/singleHotel/SingleHotelContext.js
+++ b/app/hotels/src/navigation/singleHotel/SingleHotelContext.js
@@ -4,12 +4,15 @@ import * as React from 'react';
 
 import type { RoomConfigurationType } from '../../HotelsContext';
 
+export type ApiProvider = 'booking' | 'stay22';
+
 const defaultState = {
   hotelId: '',
   checkin: new Date(),
   checkout: new Date(),
   roomsConfiguration: [],
   setHotelId: () => {},
+  apiProvider: 'booking',
 };
 
 const { Consumer, Provider: ContextProvider } = React.createContext({
@@ -22,6 +25,7 @@ type Props = {|
   +checkin: Date,
   +checkout: Date,
   +roomsConfiguration: RoomConfigurationType,
+  +apiProvider: ?ApiProvider,
 |};
 
 export type State = {|
@@ -29,6 +33,7 @@ export type State = {|
   +checkin: Date,
   +checkout: Date,
   +roomsConfiguration: RoomConfigurationType,
+  +apiProvider: ApiProvider,
   +setHotelId: (hotelId: string) => void,
 |};
 
@@ -41,6 +46,7 @@ class Provider extends React.Component<Props, State> {
       checkin: props.checkin,
       checkout: props.checkout,
       roomsConfiguration: props.roomsConfiguration,
+      apiProvider: props.apiProvider ?? 'booking',
       setHotelId: this.setHotelId,
     };
   }
diff --git a/app/hotels/src/navigation/singleHotel/SingleHotelNavigationScreen.js b/app/hotels/src/navigation/singleHotel/SingleHotelNavigationScreen.js
index d6d6367c..e4564610 100644
--- a/app/hotels/src/navigation/singleHotel/SingleHotelNavigationScreen.js
+++ b/app/hotels/src/navigation/singleHotel/SingleHotelNavigationScreen.js
@@ -7,13 +7,14 @@ import { WithStandaloneScreen } from '@kiwicom/mobile-shared';
 import SingleHotel from '../../singleHotel/SingleHotelContainer';
 import type { NavigationProps } from '../HotelsNavigationStack';
 import type { AvailableHotelSearchInput } from '../../singleHotel/AvailableHotelSearchInput';
-import SingleHotelContext from './SingleHotelContext';
+import SingleHotelContext, { type ApiProvider } from './SingleHotelContext';
 
 type Props = {
   ...NavigationProps,
   ...AvailableHotelSearchInput,
-  onBackClicked: () => void,
-  isStandAlonePackage?: boolean,
+  +onBackClicked: () => void,
+  +isStandAlonePackage?: boolean,
+  +apiProvider?: ApiProvider,
 };
 
 class SingleHotelNavigationScreen extends React.Component<Props> {
@@ -50,6 +51,7 @@ class SingleHotelNavigationScreen extends React.Component<Props> {
         checkin={this.props.checkin}
         checkout={this.props.checkout}
         roomsConfiguration={this.props.roomsConfiguration}
+        apiProvider={this.props.apiProvider}
       >
         <SingleHotel goBack={this.goBack} />
       </SingleHotelContext.Provider>
diff --git a/app/hotels/src/singleHotel/HotelDetailScreen.js b/app/hotels/src/singleHotel/HotelDetailScreen.js
index b575b475..7735aeaf 100644
--- a/app/hotels/src/singleHotel/HotelDetailScreen.js
+++ b/app/hotels/src/singleHotel/HotelDetailScreen.js
@@ -240,7 +240,7 @@ class HotelDetailScreenWithContext extends React.Component<Props> {
 export default createFragmentContainer(
   HotelDetailScreenWithContext,
   graphql`
-    fragment HotelDetailScreen_availableHotel on HotelAvailability {
+    fragment HotelDetailScreen_availableHotel on HotelAvailabilityInterface {
       hotel {
         ...Header_hotel
         ...BookNow_hotel
diff --git a/app/hotels/src/singleHotel/SingleHotelContainer.js b/app/hotels/src/singleHotel/SingleHotelContainer.js
index 85f58717..a86c31a1 100644
--- a/app/hotels/src/singleHotel/SingleHotelContainer.js
+++ b/app/hotels/src/singleHotel/SingleHotelContainer.js
@@ -13,6 +13,7 @@ import HotelsContext, {
 import SingleHotelContext, {
   type State as SingleHotelState,
 } from '../navigation/singleHotel/SingleHotelContext';
+import Stay22SingleHotel from './Stay22SingleHotel';
 
 type PropsWithContext = {|
   ...Props,
@@ -81,32 +82,40 @@ type Props = {|
 export default class SingleHotelContainerWithContext extends React.Component<
   Props,
 > {
-  renderSingleHotelsContext = ({ currency }: HotelsState) => (
+  renderHotelsContext = ({ currency, getGuestCount }: HotelsState) => (
     <SingleHotelContext.Consumer>
-      {this.renderHotelsContext(currency)}
+      {this.renderSingleHotelsContext(currency, getGuestCount)}
     </SingleHotelContext.Consumer>
   );
 
-  renderHotelsContext = (currency: $PropertyType<HotelsState, 'currency'>) => ({
+  renderSingleHotelsContext = (
+    currency: $PropertyType<HotelsState, 'currency'>,
+    getGuestCount: $PropertyType<HotelsState, 'getGuestCount'>,
+  ) => ({
     checkin,
     checkout,
     roomsConfiguration,
     hotelId,
-  }: SingleHotelState) => (
-    <SingleHotelContainer
-      currency={currency}
-      hotelId={hotelId}
-      checkin={checkin}
-      checkout={checkout}
-      roomsConfiguration={roomsConfiguration}
-      {...this.props}
-    />
-  );
+    apiProvider,
+  }: SingleHotelState) => {
+    const props = {
+      checkin,
+      checkout,
+      roomsConfiguration,
+      hotelId,
+      currency,
+      ...this.props,
+    };
+    if (apiProvider === 'booking') {
+      return <SingleHotelContainer {...props} />;
+    }
+    return <Stay22SingleHotel {...props} getGuestCount={getGuestCount} />;
+  };
 
   render() {
     return (
       <HotelsContext.Consumer>
-        {this.renderSingleHotelsContext}
+        {this.renderHotelsContext}
       </HotelsContext.Consumer>
     );
   }
diff --git a/app/hotels/src/singleHotel/Stay22SingleHotel.js b/app/hotels/src/singleHotel/Stay22SingleHotel.js
new file mode 100644
index 00000000..f5c01ee9
--- /dev/null
+++ b/app/hotels/src/singleHotel/Stay22SingleHotel.js
@@ -0,0 +1,67 @@
+// @flow strict
+
+import * as React from 'react';
+import { graphql, PublicApiRenderer } from '@kiwicom/mobile-relay';
+
+import HotelDetailScreen from './HotelDetailScreen';
+import { type RoomConfigurationType } from '../HotelsContext';
+import { sanitizeDate } from '../GraphQLSanitizers';
+import type { Stay22SingleHotelQueryResponse } from './__generated__/Stay22SingleHotelQuery.graphql';
+
+type Props = {|
+  +goBack: () => void,
+  +currency: string,
+  +hotelId: string,
+  +checkin: Date,
+  +checkout: Date,
+  +roomsConfiguration: RoomConfigurationType,
+  +getGuestCount: () => number,
+|};
+
+export default class Stay22SingleHotel extends React.Component<Props> {
+  renderInner = ({ stay22HotelDetail }: Stay22SingleHotelQueryResponse) => (
+    <HotelDetailScreen
+      availableHotel={stay22HotelDetail}
+      roomsConfiguration={this.props.roomsConfiguration}
+      goBack={this.props.goBack}
+    />
+  );
+
+  render() {
+    const { currency, checkin, checkout, hotelId } = this.props;
+    if (hotelId === '') {
+      return null;
+    }
+    return (
+      <PublicApiRenderer
+        query={graphql`
+          query Stay22SingleHotelQuery(
+            $id: ID!
+            $guests: Int!
+            $currency: Currency
+            $checkin: Date!
+            $checkout: Date!
+          ) {
+            stay22HotelDetail(
+              id: $id
+              guests: $guests
+              currency: $currency
+              checkin: $checkin
+              checkout: $checkout
+            ) {
+              ...HotelDetailScreen_availableHotel
+            }
+          }
+        `}
+        variables={{
+          id: hotelId,
+          guests: this.props.getGuestCount(),
+          checkin: sanitizeDate(checkin),
+          checkout: sanitizeDate(checkout),
+          currency,
+        }}
+        render={this.renderInner}
+      />
+    );
+  }
+}
diff --git a/app/hotels/src/singleHotel/__generated__/HotelDetailScreen_availableHotel.graphql.js b/app/hotels/src/singleHotel/__generated__/HotelDetailScreen_availableHotel.graphql.js
index 8ddf3163..c6daf47d 100644
--- a/app/hotels/src/singleHotel/__generated__/HotelDetailScreen_availableHotel.graphql.js
+++ b/app/hotels/src/singleHotel/__generated__/HotelDetailScreen_availableHotel.graphql.js
@@ -34,7 +34,7 @@ export type HotelDetailScreen_availableHotel = {|
 const node/*: ConcreteFragment*/ = {
   "kind": "Fragment",
   "name": "HotelDetailScreen_availableHotel",
-  "type": "HotelAvailability",
+  "type": "HotelAvailabilityInterface",
   "metadata": null,
   "argumentDefinitions": [],
   "selections": [
@@ -44,7 +44,7 @@ const node/*: ConcreteFragment*/ = {
       "name": "hotel",
       "storageKey": null,
       "args": null,
-      "concreteType": "Hotel",
+      "concreteType": null,
       "plural": false,
       "selections": [
         {
@@ -70,7 +70,7 @@ const node/*: ConcreteFragment*/ = {
       "name": "availableRooms",
       "storageKey": null,
       "args": null,
-      "concreteType": "HotelRoomAvailability",
+      "concreteType": null,
       "plural": true,
       "selections": [
         {
@@ -115,5 +115,5 @@ const node/*: ConcreteFragment*/ = {
   ]
 };
 // prettier-ignore
-(node/*: any*/).hash = '90d48bf84aeae56e24dacf5594636cba';
+(node/*: any*/).hash = 'a98983e9d66695b7ab62938bd14f4f9f';
 module.exports = node;
diff --git a/app/hotels/src/singleHotel/__generated__/SingleHotelContainerQuery.graphql.js b/app/hotels/src/singleHotel/__generated__/SingleHotelContainerQuery.graphql.js
index 78c0d191..d3997a73 100644
--- a/app/hotels/src/singleHotel/__generated__/SingleHotelContainerQuery.graphql.js
+++ b/app/hotels/src/singleHotel/__generated__/SingleHotelContainerQuery.graphql.js
@@ -1,6 +1,6 @@
 /**
  * @flow
- * @relayHash 9a06c4eb2bfef3f72411f14ba75799dc
+ * @relayHash 4bf310410b6a99bf273ad78411720290
  */
 
 /* eslint-disable */
@@ -60,14 +60,16 @@ query SingleHotelContainerQuery(
   }
 }
 
-fragment HotelDetailScreen_availableHotel on HotelAvailability {
+fragment HotelDetailScreen_availableHotel on HotelAvailabilityInterface {
   hotel {
+    __typename
     ...Header_hotel
     ...BookNow_hotel
     ...HotelInformation_hotel
     id
   }
   availableRooms {
+    __typename
     ...RoomList
     id
     incrementalPrice {
@@ -102,7 +104,7 @@ fragment BookNow_hotel on HotelInterface {
   id
 }
 
-fragment HotelInformation_hotel on Hotel {
+fragment HotelInformation_hotel on HotelInterface {
   ...Location_hotel
   ...Description_hotel
   ...HotelReview
@@ -160,7 +162,7 @@ fragment BeddingInfo_room on HotelRoomInterface {
   }
 }
 
-fragment Location_hotel on Hotel {
+fragment Location_hotel on HotelInterface {
   address {
     street
     city
@@ -223,40 +225,47 @@ v1 = [
 v2 = {
   "kind": "ScalarField",
   "alias": null,
-  "name": "name",
+  "name": "__typename",
   "args": null,
   "storageKey": null
 },
 v3 = {
   "kind": "ScalarField",
   "alias": null,
-  "name": "highResUrl",
+  "name": "name",
   "args": null,
   "storageKey": null
 },
 v4 = {
   "kind": "ScalarField",
   "alias": null,
-  "name": "id",
+  "name": "highResUrl",
   "args": null,
   "storageKey": null
 },
 v5 = {
   "kind": "ScalarField",
   "alias": null,
-  "name": "lowResUrl",
+  "name": "id",
   "args": null,
   "storageKey": null
 },
 v6 = {
+  "kind": "ScalarField",
+  "alias": null,
+  "name": "lowResUrl",
+  "args": null,
+  "storageKey": null
+},
+v7 = {
   "kind": "ScalarField",
   "alias": null,
   "name": "amount",
   "args": null,
   "storageKey": null
 },
-v7 = [
-  v6,
+v8 = [
+  v7,
   {
     "kind": "ScalarField",
     "alias": null,
@@ -270,7 +279,7 @@ return {
   "operationKind": "query",
   "name": "SingleHotelContainerQuery",
   "id": null,
-  "text": "query SingleHotelContainerQuery(\n  $search: AvailableHotelSearchInput!\n  $options: AvailableHotelOptionsInput\n) {\n  availableHotel(search: $search, options: $options) {\n    ... on HotelAvailabilityInterface {\n      ...HotelDetailScreen_availableHotel\n    }\n    id\n  }\n}\n\nfragment HotelDetailScreen_availableHotel on HotelAvailability {\n  hotel {\n    ...Header_hotel\n    ...BookNow_hotel\n    ...HotelInformation_hotel\n    id\n  }\n  availableRooms {\n    ...RoomList\n    id\n    incrementalPrice {\n      amount\n      currency\n    }\n  }\n}\n\nfragment Header_hotel on HotelInterface {\n  name\n  mainPhoto {\n    highResUrl\n    id\n  }\n  rating {\n    stars\n    categoryName\n  }\n  photos {\n    edges {\n      node {\n        id\n        lowResUrl\n        highResUrl\n      }\n    }\n  }\n}\n\nfragment BookNow_hotel on HotelInterface {\n  id\n}\n\nfragment HotelInformation_hotel on Hotel {\n  ...Location_hotel\n  ...Description_hotel\n  ...HotelReview\n}\n\nfragment RoomList on HotelRoomAvailabilityInterface {\n  id\n  ...RoomRow_availableRoom\n}\n\nfragment RoomRow_availableRoom on HotelRoomAvailabilityInterface {\n  id\n  ...RoomBadges_availableRoom\n  minimalPrice {\n    amount\n    currency\n  }\n  incrementalPrice {\n    amount\n    currency\n  }\n  room {\n    __typename\n    description {\n      title\n    }\n    ...RoomRowTitle_room\n    roomPhotos {\n      highResUrl\n      lowResUrl\n      id\n    }\n    maxPersons\n    ...BeddingInfo_room\n    id\n  }\n}\n\nfragment RoomBadges_availableRoom on HotelRoomAvailabilityInterface {\n  isBreakfastIncluded\n  isRefundable\n}\n\nfragment RoomRowTitle_room on HotelRoomInterface {\n  description {\n    title\n  }\n}\n\nfragment BeddingInfo_room on HotelRoomInterface {\n  maxPersons\n  bedding {\n    type\n    amount\n  }\n}\n\nfragment Location_hotel on Hotel {\n  address {\n    street\n    city\n  }\n  coordinates {\n    lat\n    lng\n  }\n}\n\nfragment Description_hotel on HotelInterface {\n  summary\n  ...Amenities\n}\n\nfragment HotelReview on HotelInterface {\n  review {\n    score\n    count\n  }\n}\n\nfragment Amenities on HotelInterface {\n  amenities {\n    id\n    name\n  }\n}\n",
+  "text": "query SingleHotelContainerQuery(\n  $search: AvailableHotelSearchInput!\n  $options: AvailableHotelOptionsInput\n) {\n  availableHotel(search: $search, options: $options) {\n    ... on HotelAvailabilityInterface {\n      ...HotelDetailScreen_availableHotel\n    }\n    id\n  }\n}\n\nfragment HotelDetailScreen_availableHotel on HotelAvailabilityInterface {\n  hotel {\n    __typename\n    ...Header_hotel\n    ...BookNow_hotel\n    ...HotelInformation_hotel\n    id\n  }\n  availableRooms {\n    __typename\n    ...RoomList\n    id\n    incrementalPrice {\n      amount\n      currency\n    }\n  }\n}\n\nfragment Header_hotel on HotelInterface {\n  name\n  mainPhoto {\n    highResUrl\n    id\n  }\n  rating {\n    stars\n    categoryName\n  }\n  photos {\n    edges {\n      node {\n        id\n        lowResUrl\n        highResUrl\n      }\n    }\n  }\n}\n\nfragment BookNow_hotel on HotelInterface {\n  id\n}\n\nfragment HotelInformation_hotel on HotelInterface {\n  ...Location_hotel\n  ...Description_hotel\n  ...HotelReview\n}\n\nfragment RoomList on HotelRoomAvailabilityInterface {\n  id\n  ...RoomRow_availableRoom\n}\n\nfragment RoomRow_availableRoom on HotelRoomAvailabilityInterface {\n  id\n  ...RoomBadges_availableRoom\n  minimalPrice {\n    amount\n    currency\n  }\n  incrementalPrice {\n    amount\n    currency\n  }\n  room {\n    __typename\n    description {\n      title\n    }\n    ...RoomRowTitle_room\n    roomPhotos {\n      highResUrl\n      lowResUrl\n      id\n    }\n    maxPersons\n    ...BeddingInfo_room\n    id\n  }\n}\n\nfragment RoomBadges_availableRoom on HotelRoomAvailabilityInterface {\n  isBreakfastIncluded\n  isRefundable\n}\n\nfragment RoomRowTitle_room on HotelRoomInterface {\n  description {\n    title\n  }\n}\n\nfragment BeddingInfo_room on HotelRoomInterface {\n  maxPersons\n  bedding {\n    type\n    amount\n  }\n}\n\nfragment Location_hotel on HotelInterface {\n  address {\n    street\n    city\n  }\n  coordinates {\n    lat\n    lng\n  }\n}\n\nfragment Description_hotel on HotelInterface {\n  summary\n  ...Amenities\n}\n\nfragment HotelReview on HotelInterface {\n  review {\n    score\n    count\n  }\n}\n\nfragment Amenities on HotelInterface {\n  amenities {\n    id\n    name\n  }\n}\n",
   "metadata": {},
   "fragment": {
     "kind": "Fragment",
@@ -317,10 +326,11 @@ return {
             "name": "hotel",
             "storageKey": null,
             "args": null,
-            "concreteType": "Hotel",
+            "concreteType": null,
             "plural": false,
             "selections": [
               v2,
+              v3,
               {
                 "kind": "LinkedField",
                 "alias": null,
@@ -330,8 +340,8 @@ return {
                 "concreteType": "HotelPhoto",
                 "plural": false,
                 "selections": [
-                  v3,
-                  v4
+                  v4,
+                  v5
                 ]
               },
               {
@@ -386,16 +396,16 @@ return {
                         "concreteType": "HotelPhoto",
                         "plural": false,
                         "selections": [
-                          v4,
                           v5,
-                          v3
+                          v6,
+                          v4
                         ]
                       }
                     ]
                   }
                 ]
               },
-              v4,
+              v5,
               {
                 "kind": "LinkedField",
                 "alias": null,
@@ -462,8 +472,8 @@ return {
                 "concreteType": "HotelAmenity",
                 "plural": true,
                 "selections": [
-                  v4,
-                  v2
+                  v5,
+                  v3
                 ]
               },
               {
@@ -499,10 +509,11 @@ return {
             "name": "availableRooms",
             "storageKey": null,
             "args": null,
-            "concreteType": "HotelRoomAvailability",
+            "concreteType": null,
             "plural": true,
             "selections": [
-              v4,
+              v2,
+              v5,
               {
                 "kind": "ScalarField",
                 "alias": null,
@@ -525,7 +536,7 @@ return {
                 "args": null,
                 "concreteType": "Price",
                 "plural": false,
-                "selections": v7
+                "selections": v8
               },
               {
                 "kind": "LinkedField",
@@ -535,7 +546,7 @@ return {
                 "args": null,
                 "concreteType": "Price",
                 "plural": true,
-                "selections": v7
+                "selections": v8
               },
               {
                 "kind": "LinkedField",
@@ -546,13 +557,7 @@ return {
                 "concreteType": null,
                 "plural": false,
                 "selections": [
-                  {
-                    "kind": "ScalarField",
-                    "alias": null,
-                    "name": "__typename",
-                    "args": null,
-                    "storageKey": null
-                  },
+                  v2,
                   {
                     "kind": "LinkedField",
                     "alias": null,
@@ -580,9 +585,9 @@ return {
                     "concreteType": "HotelPhoto",
                     "plural": true,
                     "selections": [
-                      v3,
-                      v5,
-                      v4
+                      v4,
+                      v6,
+                      v5
                     ]
                   },
                   {
@@ -608,15 +613,15 @@ return {
                         "args": null,
                         "storageKey": null
                       },
-                      v6
+                      v7
                     ]
                   },
-                  v4
+                  v5
                 ]
               }
             ]
           },
-          v4
+          v5
         ]
       }
     ]
diff --git a/app/hotels/src/singleHotel/__generated__/Stay22SingleHotelQuery.graphql.js b/app/hotels/src/singleHotel/__generated__/Stay22SingleHotelQuery.graphql.js
new file mode 100644
index 00000000..c8426956
--- /dev/null
+++ b/app/hotels/src/singleHotel/__generated__/Stay22SingleHotelQuery.graphql.js
@@ -0,0 +1,653 @@
+/**
+ * @flow
+ * @relayHash 0dd032a334f5b0752f9f632eb680eaf6
+ */
+
+/* eslint-disable */
+
+'use strict';
+
+/*::
+import type { ConcreteRequest } from 'relay-runtime';
+type HotelDetailScreen_availableHotel$ref = any;
+export type Currency = "AED" | "AFN" | "ALL" | "AMD" | "ANG" | "AOA" | "ARS" | "AUD" | "AWG" | "AZN" | "BAM" | "BBD" | "BDT" | "BGN" | "BHD" | "BIF" | "BMD" | "BND" | "BOB" | "BOV" | "BRL" | "BSD" | "BTN" | "BWP" | "BYN" | "BZD" | "CAD" | "CDF" | "CHE" | "CHF" | "CHW" | "CLF" | "CLP" | "CNY" | "COP" | "COU" | "CRC" | "CUC" | "CUP" | "CVE" | "CZK" | "DJF" | "DKK" | "DOP" | "DZD" | "EGP" | "ERN" | "ETB" | "EUR" | "FJD" | "FKP" | "GBP" | "GEL" | "GHS" | "GIP" | "GMD" | "GNF" | "GTQ" | "GYD" | "HKD" | "HNL" | "HRK" | "HTG" | "HUF" | "IDR" | "ILS" | "INR" | "IQD" | "IRR" | "ISK" | "JMD" | "JOD" | "JPY" | "KES" | "KGS" | "KHR" | "KMF" | "KPW" | "KRW" | "KWD" | "KYD" | "KZT" | "LAK" | "LBP" | "LKR" | "LRD" | "LSL" | "LYD" | "MAD" | "MDL" | "MGA" | "MKD" | "MMK" | "MNT" | "MOP" | "MRU" | "MUR" | "MVR" | "MWK" | "MXN" | "MXV" | "MYR" | "MZN" | "NAD" | "NGN" | "NIO" | "NOK" | "NPR" | "NZD" | "OMR" | "PAB" | "PEN" | "PGK" | "PHP" | "PKR" | "PLN" | "PYG" | "QAR" | "RON" | "RSD" | "RUB" | "RWF" | "SAR" | "SBD" | "SCR" | "SDG" | "SEK" | "SGD" | "SHP" | "SLL" | "SOS" | "SRD" | "SSP" | "STN" | "SVC" | "SYP" | "SZL" | "THB" | "TJS" | "TMT" | "TND" | "TOP" | "TRY" | "TTD" | "TWD" | "TZS" | "UAH" | "UGX" | "USD" | "USN" | "UYI" | "UYU" | "UZS" | "VEF" | "VND" | "VUV" | "WST" | "XAF" | "XAG" | "XAU" | "XBA" | "XBB" | "XBC" | "XBD" | "XCD" | "XDR" | "XOF" | "XPD" | "XPF" | "XPT" | "XSU" | "XTS" | "XUA" | "XXX" | "YER" | "ZAR" | "ZMW" | "ZWL" | "%future added value";
+export type Stay22SingleHotelQueryVariables = {|
+  id: string,
+  guests: number,
+  currency?: ?Currency,
+  checkin: any,
+  checkout: any,
+|};
+export type Stay22SingleHotelQueryResponse = {|
+  +stay22HotelDetail: ?{|
+    +$fragmentRefs: HotelDetailScreen_availableHotel$ref
+  |}
+|};
+export type Stay22SingleHotelQuery = {|
+  variables: Stay22SingleHotelQueryVariables,
+  response: Stay22SingleHotelQueryResponse,
+|};
+*/
+
+
+/*
+query Stay22SingleHotelQuery(
+  $id: ID!
+  $guests: Int!
+  $currency: Currency
+  $checkin: Date!
+  $checkout: Date!
+) {
+  stay22HotelDetail(id: $id, guests: $guests, currency: $currency, checkin: $checkin, checkout: $checkout) {
+    ...HotelDetailScreen_availableHotel
+    id
+  }
+}
+
+fragment HotelDetailScreen_availableHotel on HotelAvailabilityInterface {
+  hotel {
+    __typename
+    ...Header_hotel
+    ...BookNow_hotel
+    ...HotelInformation_hotel
+    id
+  }
+  availableRooms {
+    __typename
+    ...RoomList
+    id
+    incrementalPrice {
+      amount
+      currency
+    }
+  }
+}
+
+fragment Header_hotel on HotelInterface {
+  name
+  mainPhoto {
+    highResUrl
+    id
+  }
+  rating {
+    stars
+    categoryName
+  }
+  photos {
+    edges {
+      node {
+        id
+        lowResUrl
+        highResUrl
+      }
+    }
+  }
+}
+
+fragment BookNow_hotel on HotelInterface {
+  id
+}
+
+fragment HotelInformation_hotel on HotelInterface {
+  ...Location_hotel
+  ...Description_hotel
+  ...HotelReview
+}
+
+fragment RoomList on HotelRoomAvailabilityInterface {
+  id
+  ...RoomRow_availableRoom
+}
+
+fragment RoomRow_availableRoom on HotelRoomAvailabilityInterface {
+  id
+  ...RoomBadges_availableRoom
+  minimalPrice {
+    amount
+    currency
+  }
+  incrementalPrice {
+    amount
+    currency
+  }
+  room {
+    __typename
+    description {
+      title
+    }
+    ...RoomRowTitle_room
+    roomPhotos {
+      highResUrl
+      lowResUrl
+      id
+    }
+    maxPersons
+    ...BeddingInfo_room
+    id
+  }
+}
+
+fragment RoomBadges_availableRoom on HotelRoomAvailabilityInterface {
+  isBreakfastIncluded
+  isRefundable
+}
+
+fragment RoomRowTitle_room on HotelRoomInterface {
+  description {
+    title
+  }
+}
+
+fragment BeddingInfo_room on HotelRoomInterface {
+  maxPersons
+  bedding {
+    type
+    amount
+  }
+}
+
+fragment Location_hotel on HotelInterface {
+  address {
+    street
+    city
+  }
+  coordinates {
+    lat
+    lng
+  }
+}
+
+fragment Description_hotel on HotelInterface {
+  summary
+  ...Amenities
+}
+
+fragment HotelReview on HotelInterface {
+  review {
+    score
+    count
+  }
+}
+
+fragment Amenities on HotelInterface {
+  amenities {
+    id
+    name
+  }
+}
+*/
+
+const node/*: ConcreteRequest*/ = (function(){
+var v0 = [
+  {
+    "kind": "LocalArgument",
+    "name": "id",
+    "type": "ID!",
+    "defaultValue": null
+  },
+  {
+    "kind": "LocalArgument",
+    "name": "guests",
+    "type": "Int!",
+    "defaultValue": null
+  },
+  {
+    "kind": "LocalArgument",
+    "name": "currency",
+    "type": "Currency",
+    "defaultValue": null
+  },
+  {
+    "kind": "LocalArgument",
+    "name": "checkin",
+    "type": "Date!",
+    "defaultValue": null
+  },
+  {
+    "kind": "LocalArgument",
+    "name": "checkout",
+    "type": "Date!",
+    "defaultValue": null
+  }
+],
+v1 = [
+  {
+    "kind": "Variable",
+    "name": "checkin",
+    "variableName": "checkin",
+    "type": "Date!"
+  },
+  {
+    "kind": "Variable",
+    "name": "checkout",
+    "variableName": "checkout",
+    "type": "Date!"
+  },
+  {
+    "kind": "Variable",
+    "name": "currency",
+    "variableName": "currency",
+    "type": "Currency"
+  },
+  {
+    "kind": "Variable",
+    "name": "guests",
+    "variableName": "guests",
+    "type": "Int!"
+  },
+  {
+    "kind": "Variable",
+    "name": "id",
+    "variableName": "id",
+    "type": "ID!"
+  }
+],
+v2 = {
+  "kind": "ScalarField",
+  "alias": null,
+  "name": "__typename",
+  "args": null,
+  "storageKey": null
+},
+v3 = {
+  "kind": "ScalarField",
+  "alias": null,
+  "name": "name",
+  "args": null,
+  "storageKey": null
+},
+v4 = {
+  "kind": "ScalarField",
+  "alias": null,
+  "name": "highResUrl",
+  "args": null,
+  "storageKey": null
+},
+v5 = {
+  "kind": "ScalarField",
+  "alias": null,
+  "name": "id",
+  "args": null,
+  "storageKey": null
+},
+v6 = {
+  "kind": "ScalarField",
+  "alias": null,
+  "name": "lowResUrl",
+  "args": null,
+  "storageKey": null
+},
+v7 = {
+  "kind": "ScalarField",
+  "alias": null,
+  "name": "amount",
+  "args": null,
+  "storageKey": null
+},
+v8 = [
+  v7,
+  {
+    "kind": "ScalarField",
+    "alias": null,
+    "name": "currency",
+    "args": null,
+    "storageKey": null
+  }
+];
+return {
+  "kind": "Request",
+  "operationKind": "query",
+  "name": "Stay22SingleHotelQuery",
+  "id": null,
+  "text": "query Stay22SingleHotelQuery(\n  $id: ID!\n  $guests: Int!\n  $currency: Currency\n  $checkin: Date!\n  $checkout: Date!\n) {\n  stay22HotelDetail(id: $id, guests: $guests, currency: $currency, checkin: $checkin, checkout: $checkout) {\n    ...HotelDetailScreen_availableHotel\n    id\n  }\n}\n\nfragment HotelDetailScreen_availableHotel on HotelAvailabilityInterface {\n  hotel {\n    __typename\n    ...Header_hotel\n    ...BookNow_hotel\n    ...HotelInformation_hotel\n    id\n  }\n  availableRooms {\n    __typename\n    ...RoomList\n    id\n    incrementalPrice {\n      amount\n      currency\n    }\n  }\n}\n\nfragment Header_hotel on HotelInterface {\n  name\n  mainPhoto {\n    highResUrl\n    id\n  }\n  rating {\n    stars\n    categoryName\n  }\n  photos {\n    edges {\n      node {\n        id\n        lowResUrl\n        highResUrl\n      }\n    }\n  }\n}\n\nfragment BookNow_hotel on HotelInterface {\n  id\n}\n\nfragment HotelInformation_hotel on HotelInterface {\n  ...Location_hotel\n  ...Description_hotel\n  ...HotelReview\n}\n\nfragment RoomList on HotelRoomAvailabilityInterface {\n  id\n  ...RoomRow_availableRoom\n}\n\nfragment RoomRow_availableRoom on HotelRoomAvailabilityInterface {\n  id\n  ...RoomBadges_availableRoom\n  minimalPrice {\n    amount\n    currency\n  }\n  incrementalPrice {\n    amount\n    currency\n  }\n  room {\n    __typename\n    description {\n      title\n    }\n    ...RoomRowTitle_room\n    roomPhotos {\n      highResUrl\n      lowResUrl\n      id\n    }\n    maxPersons\n    ...BeddingInfo_room\n    id\n  }\n}\n\nfragment RoomBadges_availableRoom on HotelRoomAvailabilityInterface {\n  isBreakfastIncluded\n  isRefundable\n}\n\nfragment RoomRowTitle_room on HotelRoomInterface {\n  description {\n    title\n  }\n}\n\nfragment BeddingInfo_room on HotelRoomInterface {\n  maxPersons\n  bedding {\n    type\n    amount\n  }\n}\n\nfragment Location_hotel on HotelInterface {\n  address {\n    street\n    city\n  }\n  coordinates {\n    lat\n    lng\n  }\n}\n\nfragment Description_hotel on HotelInterface {\n  summary\n  ...Amenities\n}\n\nfragment HotelReview on HotelInterface {\n  review {\n    score\n    count\n  }\n}\n\nfragment Amenities on HotelInterface {\n  amenities {\n    id\n    name\n  }\n}\n",
+  "metadata": {},
+  "fragment": {
+    "kind": "Fragment",
+    "name": "Stay22SingleHotelQuery",
+    "type": "RootQuery",
+    "metadata": null,
+    "argumentDefinitions": v0,
+    "selections": [
+      {
+        "kind": "LinkedField",
+        "alias": null,
+        "name": "stay22HotelDetail",
+        "storageKey": null,
+        "args": v1,
+        "concreteType": "Stay22HotelDetail",
+        "plural": false,
+        "selections": [
+          {
+            "kind": "FragmentSpread",
+            "name": "HotelDetailScreen_availableHotel",
+            "args": null
+          }
+        ]
+      }
+    ]
+  },
+  "operation": {
+    "kind": "Operation",
+    "name": "Stay22SingleHotelQuery",
+    "argumentDefinitions": v0,
+    "selections": [
+      {
+        "kind": "LinkedField",
+        "alias": null,
+        "name": "stay22HotelDetail",
+        "storageKey": null,
+        "args": v1,
+        "concreteType": "Stay22HotelDetail",
+        "plural": false,
+        "selections": [
+          {
+            "kind": "LinkedField",
+            "alias": null,
+            "name": "hotel",
+            "storageKey": null,
+            "args": null,
+            "concreteType": null,
+            "plural": false,
+            "selections": [
+              v2,
+              v3,
+              {
+                "kind": "LinkedField",
+                "alias": null,
+                "name": "mainPhoto",
+                "storageKey": null,
+                "args": null,
+                "concreteType": "HotelPhoto",
+                "plural": false,
+                "selections": [
+                  v4,
+                  v5
+                ]
+              },
+              {
+                "kind": "LinkedField",
+                "alias": null,
+                "name": "rating",
+                "storageKey": null,
+                "args": null,
+                "concreteType": "HotelRating",
+                "plural": false,
+                "selections": [
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "stars",
+                    "args": null,
+                    "storageKey": null
+                  },
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "categoryName",
+                    "args": null,
+                    "storageKey": null
+                  }
+                ]
+              },
+              {
+                "kind": "LinkedField",
+                "alias": null,
+                "name": "photos",
+                "storageKey": null,
+                "args": null,
+                "concreteType": "HotelPhotoConnection",
+                "plural": false,
+                "selections": [
+                  {
+                    "kind": "LinkedField",
+                    "alias": null,
+                    "name": "edges",
+                    "storageKey": null,
+                    "args": null,
+                    "concreteType": "HotelPhotoEdge",
+                    "plural": true,
+                    "selections": [
+                      {
+                        "kind": "LinkedField",
+                        "alias": null,
+                        "name": "node",
+                        "storageKey": null,
+                        "args": null,
+                        "concreteType": "HotelPhoto",
+                        "plural": false,
+                        "selections": [
+                          v5,
+                          v6,
+                          v4
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              },
+              v5,
+              {
+                "kind": "LinkedField",
+                "alias": null,
+                "name": "address",
+                "storageKey": null,
+                "args": null,
+                "concreteType": "Address",
+                "plural": false,
+                "selections": [
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "street",
+                    "args": null,
+                    "storageKey": null
+                  },
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "city",
+                    "args": null,
+                    "storageKey": null
+                  }
+                ]
+              },
+              {
+                "kind": "LinkedField",
+                "alias": null,
+                "name": "coordinates",
+                "storageKey": null,
+                "args": null,
+                "concreteType": "Coordinates",
+                "plural": false,
+                "selections": [
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "lat",
+                    "args": null,
+                    "storageKey": null
+                  },
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "lng",
+                    "args": null,
+                    "storageKey": null
+                  }
+                ]
+              },
+              {
+                "kind": "ScalarField",
+                "alias": null,
+                "name": "summary",
+                "args": null,
+                "storageKey": null
+              },
+              {
+                "kind": "LinkedField",
+                "alias": null,
+                "name": "amenities",
+                "storageKey": null,
+                "args": null,
+                "concreteType": "HotelAmenity",
+                "plural": true,
+                "selections": [
+                  v5,
+                  v3
+                ]
+              },
+              {
+                "kind": "LinkedField",
+                "alias": null,
+                "name": "review",
+                "storageKey": null,
+                "args": null,
+                "concreteType": "HotelReview",
+                "plural": false,
+                "selections": [
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "score",
+                    "args": null,
+                    "storageKey": null
+                  },
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "count",
+                    "args": null,
+                    "storageKey": null
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            "kind": "LinkedField",
+            "alias": null,
+            "name": "availableRooms",
+            "storageKey": null,
+            "args": null,
+            "concreteType": null,
+            "plural": true,
+            "selections": [
+              v2,
+              v5,
+              {
+                "kind": "ScalarField",
+                "alias": null,
+                "name": "isBreakfastIncluded",
+                "args": null,
+                "storageKey": null
+              },
+              {
+                "kind": "ScalarField",
+                "alias": null,
+                "name": "isRefundable",
+                "args": null,
+                "storageKey": null
+              },
+              {
+                "kind": "LinkedField",
+                "alias": null,
+                "name": "minimalPrice",
+                "storageKey": null,
+                "args": null,
+                "concreteType": "Price",
+                "plural": false,
+                "selections": v8
+              },
+              {
+                "kind": "LinkedField",
+                "alias": null,
+                "name": "incrementalPrice",
+                "storageKey": null,
+                "args": null,
+                "concreteType": "Price",
+                "plural": true,
+                "selections": v8
+              },
+              {
+                "kind": "LinkedField",
+                "alias": null,
+                "name": "room",
+                "storageKey": null,
+                "args": null,
+                "concreteType": null,
+                "plural": false,
+                "selections": [
+                  v2,
+                  {
+                    "kind": "LinkedField",
+                    "alias": null,
+                    "name": "description",
+                    "storageKey": null,
+                    "args": null,
+                    "concreteType": "HotelRoomDescription",
+                    "plural": false,
+                    "selections": [
+                      {
+                        "kind": "ScalarField",
+                        "alias": null,
+                        "name": "title",
+                        "args": null,
+                        "storageKey": null
+                      }
+                    ]
+                  },
+                  {
+                    "kind": "LinkedField",
+                    "alias": null,
+                    "name": "roomPhotos",
+                    "storageKey": null,
+                    "args": null,
+                    "concreteType": "HotelPhoto",
+                    "plural": true,
+                    "selections": [
+                      v4,
+                      v6,
+                      v5
+                    ]
+                  },
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "maxPersons",
+                    "args": null,
+                    "storageKey": null
+                  },
+                  {
+                    "kind": "LinkedField",
+                    "alias": null,
+                    "name": "bedding",
+                    "storageKey": null,
+                    "args": null,
+                    "concreteType": "HotelRoomBedding",
+                    "plural": true,
+                    "selections": [
+                      {
+                        "kind": "ScalarField",
+                        "alias": null,
+                        "name": "type",
+                        "args": null,
+                        "storageKey": null
+                      },
+                      v7
+                    ]
+                  },
+                  v5
+                ]
+              }
+            ]
+          },
+          v5
+        ]
+      }
+    ]
+  }
+};
+})();
+// prettier-ignore
+(node/*: any*/).hash = '1636debee894167a789c2b90ad303f18';
+module.exports = node;
diff --git a/app/hotels/src/singleHotel/hotelInformation/HotelInformation.js b/app/hotels/src/singleHotel/hotelInformation/HotelInformation.js
index 589e519c..7418d6df 100644
--- a/app/hotels/src/singleHotel/hotelInformation/HotelInformation.js
+++ b/app/hotels/src/singleHotel/hotelInformation/HotelInformation.js
@@ -28,7 +28,7 @@ const HotelInformation = (props: Props) => (
 export default (createFragmentContainer(
   HotelInformation,
   graphql`
-    fragment HotelInformation_hotel on Hotel {
+    fragment HotelInformation_hotel on HotelInterface {
       ...Location_hotel
       ...Description_hotel
       ...HotelReview
diff --git a/app/hotels/src/singleHotel/hotelInformation/__generated__/HotelInformation_hotel.graphql.js b/app/hotels/src/singleHotel/hotelInformation/__generated__/HotelInformation_hotel.graphql.js
index a878ebf5..5c65b6c6 100644
--- a/app/hotels/src/singleHotel/hotelInformation/__generated__/HotelInformation_hotel.graphql.js
+++ b/app/hotels/src/singleHotel/hotelInformation/__generated__/HotelInformation_hotel.graphql.js
@@ -23,7 +23,7 @@ export type HotelInformation_hotel = {|
 const node/*: ConcreteFragment*/ = {
   "kind": "Fragment",
   "name": "HotelInformation_hotel",
-  "type": "Hotel",
+  "type": "HotelInterface",
   "metadata": null,
   "argumentDefinitions": [],
   "selections": [
@@ -45,5 +45,5 @@ const node/*: ConcreteFragment*/ = {
   ]
 };
 // prettier-ignore
-(node/*: any*/).hash = 'dd2c3fec5cc896643ea5eec8b06d8972';
+(node/*: any*/).hash = 'b6ce8ee9201943110c43ca76098263d5';
 module.exports = node;
diff --git a/app/hotels/src/singleHotel/hotelInformation/location/Location.js b/app/hotels/src/singleHotel/hotelInformation/location/Location.js
index 051e532a..10007fc3 100644
--- a/app/hotels/src/singleHotel/hotelInformation/location/Location.js
+++ b/app/hotels/src/singleHotel/hotelInformation/location/Location.js
@@ -132,7 +132,7 @@ class LocationWithContext extends React.Component<Props> {
 export default (createFragmentContainer(
   withNavigation(LocationWithContext),
   graphql`
-    fragment Location_hotel on Hotel {
+    fragment Location_hotel on HotelInterface {
       address {
         street
         city
diff --git a/app/hotels/src/singleHotel/hotelInformation/location/__generated__/Location_hotel.graphql.js b/app/hotels/src/singleHotel/hotelInformation/location/__generated__/Location_hotel.graphql.js
index ff0b1a89..4f769629 100644
--- a/app/hotels/src/singleHotel/hotelInformation/location/__generated__/Location_hotel.graphql.js
+++ b/app/hotels/src/singleHotel/hotelInformation/location/__generated__/Location_hotel.graphql.js
@@ -27,7 +27,7 @@ export type Location_hotel = {|
 const node/*: ConcreteFragment*/ = {
   "kind": "Fragment",
   "name": "Location_hotel",
-  "type": "Hotel",
+  "type": "HotelInterface",
   "metadata": null,
   "argumentDefinitions": [],
   "selections": [
@@ -84,5 +84,5 @@ const node/*: ConcreteFragment*/ = {
   ]
 };
 // prettier-ignore
-(node/*: any*/).hash = 'a5f82a0bd11e0cfeb086ea040ca809f6';
+(node/*: any*/).hash = '31c5d4b67f70b638a1019503b8bc7a29';
 module.exports = node;
diff --git a/app/hotels/src/singleHotel/roomList/RoomRow.js b/app/hotels/src/singleHotel/roomList/RoomRow.js
index 7f78bce7..5fcc9a85 100644
--- a/app/hotels/src/singleHotel/roomList/RoomRow.js
+++ b/app/hotels/src/singleHotel/roomList/RoomRow.js
@@ -2,7 +2,6 @@
 
 import * as React from 'react';
 import { View } from 'react-native';
-import idx from 'idx';
 import { StyleSheet } from '@kiwicom/mobile-shared';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import {
@@ -52,22 +51,27 @@ export class RoomRow extends React.Component<Props> {
   };
 
   getIdAndMaxPersons = () => {
-    const id = idx(this.props, _ => _.availableRoom.id);
-    const maxPersons = idx(this.props, _ => _.availableRoom.room.maxPersons);
+    const id = this.props?.availableRoom?.id;
+    const maxPersons = this.props?.availableRoom?.room?.maxPersons;
     return { id, maxPersons };
   };
 
   openGallery = () => {
     const { availableRoom } = this.props;
-    const photosArray = idx(availableRoom, _ => _.room.roomPhotos) || [];
+    const photosArray = availableRoom?.room?.roomPhotos ?? [];
 
-    const photos = photosArray.map(photo => ({
-      key: idx(photo, _ => _.id) || '',
-      highRes: idx(photo, _ => _.highResUrl) || '',
-      lowRes: idx(photo, _ => _.lowResUrl) || '',
-    }));
+    const photos = photosArray.map(photo => {
+      const highRes = photo?.highResUrl ?? '';
+      const lowRes = photo?.lowResUrl ?? highRes; // Fallback to highResUrl since stay22 do not provide lowResUrl
+      const key = photo?.id ?? '';
+      return {
+        key,
+        highRes,
+        lowRes,
+      };
+    });
 
-    const roomTitle = idx(availableRoom, _ => _.room.description.title) || '';
+    const roomTitle = availableRoom?.room?.description?.title ?? '';
     this.props.navigation.navigate('GalleryGrid', {
       hotelName: roomTitle,
       images: photos,
@@ -76,17 +80,17 @@ export class RoomRow extends React.Component<Props> {
 
   render = () => {
     const availableRoom = this.props.availableRoom;
-    const thumbnailUrl = idx(
-      availableRoom,
-      _ => _.room.roomPhotos[0].lowResUrl,
-    );
-    const amount = idx(availableRoom, _ => _.minimalPrice.amount) || null;
-    const currency = idx(availableRoom, _ => _.minimalPrice.currency) || null;
-    const selectableCount =
-      idx(availableRoom, _ => _.incrementalPrice.length) || 0;
-    const id = idx(availableRoom, _ => _.id) || '';
-    const selectedCount = idx(this.props.selected, _ => _[id]) || 0;
-    const room = idx(availableRoom, _ => _.room);
+    // New provider currently does not support lowResUrl, fallback to highResUrl in that case
+    // ThumbnailUrl provides to low quality
+    const photo = availableRoom?.room?.roomPhotos?.[0];
+    const thumbnailUrl = photo?.lowResUrl ?? photo?.highResUrl;
+
+    const amount = availableRoom?.minimalPrice?.amount ?? null;
+    const currency = availableRoom?.minimalPrice?.currency ?? null;
+    const selectableCount = availableRoom?.incrementalPrice?.length ?? 0;
+    const id = availableRoom?.id ?? '';
+    const selectedCount = this.props.selected?.[id] ?? 0;
+    const room = availableRoom?.room;
 
     return (
       <View style={styles.container}>
diff --git a/schema.graphql b/schema.graphql
index a42b31f2..57513711 100644
--- a/schema.graphql
+++ b/schema.graphql
@@ -1567,6 +1567,7 @@ interface HotelInterface {
   rating: HotelRating
   photos: HotelPhotoConnection
   amenities: [HotelAmenity]
+  coordinates: Coordinates
 }
 
 """The urls where the user will be redirected for payment"""
@@ -2373,14 +2374,6 @@ type RootQuery {
   """
   availableHotel(search: AvailableHotelSearchInput!, options: AvailableHotelOptionsInput): HotelAvailability
 
-  """Find booking by its id or databaseId."""
-  booking(
-    """
-    Database ID (human readable ID) of the booking. You should use "node" query if you want to use opaque ID.
-    """
-    id: ID!
-  ): Booking @deprecated(reason: "Use \"node\" query instead.")
-
   """Get the timeline for your booking."""
   bookingTimeline(
     """Only Booking id can be used as ID."""
@@ -2504,7 +2497,7 @@ type RootQuery {
   ): BookingInterface
 
   """Single hotel by ID."""
-  stay22HotelDetail(id: ID!, currency: Currency = EUR): Stay22HotelDetail
+  stay22HotelDetail(id: ID!, guests: Int!, checkin: Date!, checkout: Date!, currency: Currency = EUR): Stay22HotelDetail
 }
 
 type RouteStop {
@@ -2550,6 +2543,7 @@ type Stay22Hotel implements HotelInterface {
 
   """All amenities available in the hotel"""
   amenities: [HotelAmenity]
+  coordinates: Coordinates
 }
 
 type Stay22HotelDetail implements HotelAvailabilityInterface {


Test patch:
diff --git a/app/hotels/src/__tests__/HotelsContext.test.js b/app/hotels/src/__tests__/HotelsContext.test.js
index 80d4be5d..4c02ddf3 100644
--- a/app/hotels/src/__tests__/HotelsContext.test.js
+++ b/app/hotels/src/__tests__/HotelsContext.test.js
@@ -1,6 +1,37 @@
 // @flow strict
 
-import { getAsUtcDate } from '../HotelsContext';
+import * as React from 'react';
+import renderer from 'react-test-renderer';
+
+import HotelsContext, {
+  getAsUtcDate,
+  type RoomConfigurationType,
+} from '../HotelsContext';
+
+const props = {
+  version: 'test',
+  currency: 'EUR',
+  latitude: null,
+  longitude: null,
+  checkin: null,
+  checkout: null,
+  cityId: null,
+  cityName: null,
+};
+
+const Child = () => null;
+
+const getWrapper = (roomsConfiguration: ?RoomConfigurationType) =>
+  renderer
+    .create(
+      <HotelsContext.Provider
+        {...props}
+        roomsConfiguration={roomsConfiguration}
+      >
+        <Child />
+      </HotelsContext.Provider>,
+    )
+    .getInstance();
 
 describe('getAsUtcDate', () => {
   it('should return null for invalid date string', () => {
@@ -12,3 +43,20 @@ describe('getAsUtcDate', () => {
     expect(getAsUtcDate('2018-01-01')).toEqual(new Date(Date.UTC(2018, 0, 1)));
   });
 });
+
+describe('HotelsContext', () => {
+  it('calculates number of guests correctly with undefined roomsConfig', () => {
+    const wrapper = getWrapper();
+    expect(wrapper.getGuestCount()).toBe(0);
+  });
+
+  it('calculates number of guests correctly', () => {
+    const wrapper = getWrapper([
+      { adultsCount: 2, children: [] },
+      // $FlowExpectedError: testing with missing children
+      { adultsCount: 1 },
+      { adultsCount: 1, children: [{ age: 0 }, { age: 2 }, { age: 17 }] },
+    ]);
+    expect(wrapper.getGuestCount()).toBe(7);
+  });
+});
diff --git a/app/hotels/src/allHotels/__tests__/Stay22HotelsSearch.test.js b/app/hotels/src/allHotels/__tests__/Stay22HotelsSearch.test.js
index 9e84a8aa..82aaae28 100644
--- a/app/hotels/src/allHotels/__tests__/Stay22HotelsSearch.test.js
+++ b/app/hotels/src/allHotels/__tests__/Stay22HotelsSearch.test.js
@@ -15,31 +15,6 @@ const getProps = (props: Object = {}) => ({
   ...props,
 });
 
-it('calculates guests correctly', () => {
-  const Component = new Stay22HotelsSearch(getProps());
-  expect(Component.getGuests()).toEqual(2);
-});
-
-it('calculates guests correctly with children', () => {
-  const Component = new Stay22HotelsSearch(
-    getProps({
-      roomsConfiguration: [
-        { adultsCount: 2, children: [{ age: 5 }, { age: 17 }] },
-      ],
-    }),
-  );
-  expect(Component.getGuests()).toEqual(4);
-});
-
-it('calculates guests correctly with missing input', () => {
-  const Component = new Stay22HotelsSearch(
-    getProps({
-      roomsConfiguration: [{ adultsCount: 2 }],
-    }),
-  );
-  expect(Component.getGuests()).toEqual(2);
-});
-
 it('renders error with missing checkin', () => {
   const props = getProps({ checkin: null });
   const instance = renderer.create(<Stay22HotelsSearch {...props} />).root;