Repository: kiwicom/mobile
Pull request #961 (2018-08-06 14:44:26)

MMB: Show menu item in explore component


Patch:
diff --git a/android/dependencies.gradle b/android/dependencies.gradle
index 873e91f3..22c5042d 100644
--- a/android/dependencies.gradle
+++ b/android/dependencies.gradle
@@ -6,7 +6,7 @@ ext {
     targetSdkVersionVar = 27
     buildToolsVersionVar = "27.0.2"
 
-    reactNativeVersion = "0.51.0"
+    reactNativeVersion = "0.55.4"
     supportVersion = "26.1.0"
     playServicesVersion = "11.8.0"
 }
diff --git a/app/MMB/src/__generated__/MainMenuContainerQuery.graphql.js b/app/MMB/src/__generated__/MainMenuContainerQuery.graphql.js
index ae6ca99e..b89e0a93 100644
--- a/app/MMB/src/__generated__/MainMenuContainerQuery.graphql.js
+++ b/app/MMB/src/__generated__/MainMenuContainerQuery.graphql.js
@@ -1,6 +1,6 @@
 /**
  * @flow
- * @relayHash 284bf6ca3e255374a3bc9aaea48eb677
+ * @relayHash 8a011e75d8306bd5c689420828cc6373
  */
 
 /* eslint-disable */
@@ -298,6 +298,7 @@ fragment ExploreText on Trip {
   }
   arrival {
     airport {
+      ...ExploreMenuGroup
       city {
         name
       }
@@ -305,6 +306,10 @@ fragment ExploreText on Trip {
     }
   }
 }
+
+fragment ExploreMenuGroup on Location {
+  code
+}
 */
 
 const node/*: ConcreteRequest*/ = (function(){
@@ -527,6 +532,13 @@ v12 = [
         "concreteType": "Location",
         "plural": false,
         "selections": [
+          {
+            "kind": "ScalarField",
+            "alias": null,
+            "name": "code",
+            "args": null,
+            "storageKey": null
+          },
           v6,
           v4,
           v7
@@ -546,7 +558,7 @@ return {
   "operationKind": "query",
   "name": "MainMenuContainerQuery",
   "id": null,
-  "text": "query MainMenuContainerQuery(\n  $bookingId: Int!\n  $authToken: String!\n) {\n  singleBooking(id: $bookingId, authToken: $authToken) {\n    __typename\n    ...MainMenu\n    id\n  }\n}\n\nfragment MainMenu on BookingInterface {\n  databaseId\n  authToken\n  isPastBooking\n  ...ExploreCity\n  ...Header\n  ...PassengerMenuGroup\n  ...MissingInformation\n}\n\nfragment ExploreCity on BookingInterface {\n  ...CardContent\n}\n\nfragment Header on BookingInterface {\n  isPastBooking\n  ...StatusBar\n  ...TripInfo\n  ...TripOverview\n}\n\nfragment PassengerMenuGroup on BookingInterface {\n  ...PassengerMenuDetail\n}\n\nfragment MissingInformation on BookingInterface {\n  passengers {\n    travelDocument {\n      idNumber\n    }\n  }\n}\n\nfragment PassengerMenuDetail on BookingInterface {\n  ...Visa\n  passengers {\n    databaseId\n    ...Passenger\n  }\n}\n\nfragment Visa on BookingInterface {\n  passengers {\n    visaInformation {\n      requiredIn {\n        name\n        id\n      }\n      warningIn {\n        name\n        id\n      }\n    }\n  }\n}\n\nfragment Passenger on Passenger {\n  fullName\n  title\n  birthday\n}\n\nfragment StatusBar on BookingInterface {\n  ...StatusBarIcon\n  databaseId\n}\n\nfragment TripInfo on BookingInterface {\n  __typename\n  ... on BookingOneWay {\n    ...TripInfoOneWay\n  }\n  ... on BookingReturn {\n    ...TripInfoReturn\n  }\n  ... on BookingMulticity {\n    ...TripInfoMulticity\n  }\n}\n\nfragment TripOverview on BookingInterface {\n  __typename\n  ... on BookingOneWay {\n    ...OneWayTimeline\n  }\n  ... on BookingReturn {\n    ...ReturnTimeline\n  }\n  ... on BookingMulticity {\n    ...MulticityTimeline\n  }\n}\n\nfragment OneWayTimeline on BookingOneWay {\n  trip {\n    ...Timeline\n  }\n}\n\nfragment ReturnTimeline on BookingReturn {\n  outbound {\n    ...Timeline\n  }\n  inbound {\n    ...Timeline\n  }\n}\n\nfragment MulticityTimeline on BookingMulticity {\n  trips {\n    ...Timeline\n  }\n}\n\nfragment Timeline on Trip {\n  legs {\n    departure {\n      ...TimelineDeparture_routeStop\n    }\n    arrival {\n      ...TimelineArrival\n    }\n    ...TimelineDeparture_legInfo\n    id\n  }\n}\n\nfragment TimelineDeparture_routeStop on RouteStop {\n  ...TimelineTitle\n}\n\nfragment TimelineArrival on RouteStop {\n  ...TimelineTitle\n}\n\nfragment TimelineDeparture_legInfo on Leg {\n  flightNumber\n  airline {\n    name\n    logoUrl\n  }\n}\n\nfragment TimelineTitle on RouteStop {\n  localTime\n  airport {\n    locationId\n    city {\n      name\n    }\n    id\n  }\n}\n\nfragment TripInfoOneWay on BookingOneWay {\n  trip {\n    ...TripCities\n    ...TripTimes\n  }\n}\n\nfragment TripInfoReturn on BookingReturn {\n  outbound {\n    ...TripCities\n    ...TripTimes\n  }\n  inbound {\n    ...TripTimes\n  }\n}\n\nfragment TripInfoMulticity on BookingMulticity {\n  trips {\n    ...TripCities\n    ...TripTimes\n  }\n}\n\nfragment TripCities on Trip {\n  departure {\n    ...Location\n  }\n  arrival {\n    ...Location\n  }\n}\n\nfragment TripTimes on Trip {\n  ...Duration\n  departure {\n    ...DateTime\n  }\n  arrival {\n    ...DateTime\n  }\n}\n\nfragment Duration on Trip {\n  duration\n}\n\nfragment DateTime on RouteStop {\n  localTime\n}\n\nfragment Location on RouteStop {\n  airport {\n    city {\n      name\n    }\n    ...CountryFlag\n    id\n  }\n}\n\nfragment CountryFlag on Location {\n  countryFlagURL\n}\n\nfragment StatusBarIcon on BookingInterface {\n  status\n  isPastBooking\n}\n\nfragment CardContent on BookingInterface {\n  __typename\n  ...ExploreOneWay\n  ...ExploreReturn\n  ...ExploreMulticity\n}\n\nfragment ExploreOneWay on BookingInterface {\n  ... on BookingOneWay {\n    trip {\n      ...ExploreText\n    }\n  }\n}\n\nfragment ExploreReturn on BookingInterface {\n  ... on BookingReturn {\n    outbound {\n      ...ExploreText\n    }\n  }\n}\n\nfragment ExploreMulticity on BookingInterface {\n  ... on BookingMulticity {\n    trips {\n      departure {\n        time\n      }\n      ...ExploreText\n    }\n  }\n}\n\nfragment ExploreText on Trip {\n  departure {\n    time\n  }\n  arrival {\n    airport {\n      city {\n        name\n      }\n      id\n    }\n  }\n}\n",
+  "text": "query MainMenuContainerQuery(\n  $bookingId: Int!\n  $authToken: String!\n) {\n  singleBooking(id: $bookingId, authToken: $authToken) {\n    __typename\n    ...MainMenu\n    id\n  }\n}\n\nfragment MainMenu on BookingInterface {\n  databaseId\n  authToken\n  isPastBooking\n  ...ExploreCity\n  ...Header\n  ...PassengerMenuGroup\n  ...MissingInformation\n}\n\nfragment ExploreCity on BookingInterface {\n  ...CardContent\n}\n\nfragment Header on BookingInterface {\n  isPastBooking\n  ...StatusBar\n  ...TripInfo\n  ...TripOverview\n}\n\nfragment PassengerMenuGroup on BookingInterface {\n  ...PassengerMenuDetail\n}\n\nfragment MissingInformation on BookingInterface {\n  passengers {\n    travelDocument {\n      idNumber\n    }\n  }\n}\n\nfragment PassengerMenuDetail on BookingInterface {\n  ...Visa\n  passengers {\n    databaseId\n    ...Passenger\n  }\n}\n\nfragment Visa on BookingInterface {\n  passengers {\n    visaInformation {\n      requiredIn {\n        name\n        id\n      }\n      warningIn {\n        name\n        id\n      }\n    }\n  }\n}\n\nfragment Passenger on Passenger {\n  fullName\n  title\n  birthday\n}\n\nfragment StatusBar on BookingInterface {\n  ...StatusBarIcon\n  databaseId\n}\n\nfragment TripInfo on BookingInterface {\n  __typename\n  ... on BookingOneWay {\n    ...TripInfoOneWay\n  }\n  ... on BookingReturn {\n    ...TripInfoReturn\n  }\n  ... on BookingMulticity {\n    ...TripInfoMulticity\n  }\n}\n\nfragment TripOverview on BookingInterface {\n  __typename\n  ... on BookingOneWay {\n    ...OneWayTimeline\n  }\n  ... on BookingReturn {\n    ...ReturnTimeline\n  }\n  ... on BookingMulticity {\n    ...MulticityTimeline\n  }\n}\n\nfragment OneWayTimeline on BookingOneWay {\n  trip {\n    ...Timeline\n  }\n}\n\nfragment ReturnTimeline on BookingReturn {\n  outbound {\n    ...Timeline\n  }\n  inbound {\n    ...Timeline\n  }\n}\n\nfragment MulticityTimeline on BookingMulticity {\n  trips {\n    ...Timeline\n  }\n}\n\nfragment Timeline on Trip {\n  legs {\n    departure {\n      ...TimelineDeparture_routeStop\n    }\n    arrival {\n      ...TimelineArrival\n    }\n    ...TimelineDeparture_legInfo\n    id\n  }\n}\n\nfragment TimelineDeparture_routeStop on RouteStop {\n  ...TimelineTitle\n}\n\nfragment TimelineArrival on RouteStop {\n  ...TimelineTitle\n}\n\nfragment TimelineDeparture_legInfo on Leg {\n  flightNumber\n  airline {\n    name\n    logoUrl\n  }\n}\n\nfragment TimelineTitle on RouteStop {\n  localTime\n  airport {\n    locationId\n    city {\n      name\n    }\n    id\n  }\n}\n\nfragment TripInfoOneWay on BookingOneWay {\n  trip {\n    ...TripCities\n    ...TripTimes\n  }\n}\n\nfragment TripInfoReturn on BookingReturn {\n  outbound {\n    ...TripCities\n    ...TripTimes\n  }\n  inbound {\n    ...TripTimes\n  }\n}\n\nfragment TripInfoMulticity on BookingMulticity {\n  trips {\n    ...TripCities\n    ...TripTimes\n  }\n}\n\nfragment TripCities on Trip {\n  departure {\n    ...Location\n  }\n  arrival {\n    ...Location\n  }\n}\n\nfragment TripTimes on Trip {\n  ...Duration\n  departure {\n    ...DateTime\n  }\n  arrival {\n    ...DateTime\n  }\n}\n\nfragment Duration on Trip {\n  duration\n}\n\nfragment DateTime on RouteStop {\n  localTime\n}\n\nfragment Location on RouteStop {\n  airport {\n    city {\n      name\n    }\n    ...CountryFlag\n    id\n  }\n}\n\nfragment CountryFlag on Location {\n  countryFlagURL\n}\n\nfragment StatusBarIcon on BookingInterface {\n  status\n  isPastBooking\n}\n\nfragment CardContent on BookingInterface {\n  __typename\n  ...ExploreOneWay\n  ...ExploreReturn\n  ...ExploreMulticity\n}\n\nfragment ExploreOneWay on BookingInterface {\n  ... on BookingOneWay {\n    trip {\n      ...ExploreText\n    }\n  }\n}\n\nfragment ExploreReturn on BookingInterface {\n  ... on BookingReturn {\n    outbound {\n      ...ExploreText\n    }\n  }\n}\n\nfragment ExploreMulticity on BookingInterface {\n  ... on BookingMulticity {\n    trips {\n      departure {\n        time\n      }\n      ...ExploreText\n    }\n  }\n}\n\nfragment ExploreText on Trip {\n  departure {\n    time\n  }\n  arrival {\n    airport {\n      ...ExploreMenuGroup\n      city {\n        name\n      }\n      id\n    }\n  }\n}\n\nfragment ExploreMenuGroup on Location {\n  code\n}\n",
   "metadata": {},
   "fragment": {
     "kind": "Fragment",
diff --git a/app/MMB/src/__generated__/MainMenuRefetchQuery.graphql.js b/app/MMB/src/__generated__/MainMenuRefetchQuery.graphql.js
index ed47d823..a624d8b9 100644
--- a/app/MMB/src/__generated__/MainMenuRefetchQuery.graphql.js
+++ b/app/MMB/src/__generated__/MainMenuRefetchQuery.graphql.js
@@ -1,6 +1,6 @@
 /**
  * @flow
- * @relayHash b4ba6707b1f9c8ab878ad48a268e38a7
+ * @relayHash 58aa7f3c60ca3605a7a000376caa6875
  */
 
 /* eslint-disable */
@@ -298,6 +298,7 @@ fragment ExploreText on Trip {
   }
   arrival {
     airport {
+      ...ExploreMenuGroup
       city {
         name
       }
@@ -305,6 +306,10 @@ fragment ExploreText on Trip {
     }
   }
 }
+
+fragment ExploreMenuGroup on Location {
+  code
+}
 */
 
 const node/*: ConcreteRequest*/ = (function(){
@@ -527,6 +532,13 @@ v12 = [
         "concreteType": "Location",
         "plural": false,
         "selections": [
+          {
+            "kind": "ScalarField",
+            "alias": null,
+            "name": "code",
+            "args": null,
+            "storageKey": null
+          },
           v6,
           v4,
           v7
@@ -546,7 +558,7 @@ return {
   "operationKind": "query",
   "name": "MainMenuRefetchQuery",
   "id": null,
-  "text": "query MainMenuRefetchQuery(\n  $id: Int!\n  $authToken: String!\n) {\n  singleBooking(id: $id, authToken: $authToken) {\n    __typename\n    ...MainMenu\n    id\n  }\n}\n\nfragment MainMenu on BookingInterface {\n  databaseId\n  authToken\n  isPastBooking\n  ...ExploreCity\n  ...Header\n  ...PassengerMenuGroup\n  ...MissingInformation\n}\n\nfragment ExploreCity on BookingInterface {\n  ...CardContent\n}\n\nfragment Header on BookingInterface {\n  isPastBooking\n  ...StatusBar\n  ...TripInfo\n  ...TripOverview\n}\n\nfragment PassengerMenuGroup on BookingInterface {\n  ...PassengerMenuDetail\n}\n\nfragment MissingInformation on BookingInterface {\n  passengers {\n    travelDocument {\n      idNumber\n    }\n  }\n}\n\nfragment PassengerMenuDetail on BookingInterface {\n  ...Visa\n  passengers {\n    databaseId\n    ...Passenger\n  }\n}\n\nfragment Visa on BookingInterface {\n  passengers {\n    visaInformation {\n      requiredIn {\n        name\n        id\n      }\n      warningIn {\n        name\n        id\n      }\n    }\n  }\n}\n\nfragment Passenger on Passenger {\n  fullName\n  title\n  birthday\n}\n\nfragment StatusBar on BookingInterface {\n  ...StatusBarIcon\n  databaseId\n}\n\nfragment TripInfo on BookingInterface {\n  __typename\n  ... on BookingOneWay {\n    ...TripInfoOneWay\n  }\n  ... on BookingReturn {\n    ...TripInfoReturn\n  }\n  ... on BookingMulticity {\n    ...TripInfoMulticity\n  }\n}\n\nfragment TripOverview on BookingInterface {\n  __typename\n  ... on BookingOneWay {\n    ...OneWayTimeline\n  }\n  ... on BookingReturn {\n    ...ReturnTimeline\n  }\n  ... on BookingMulticity {\n    ...MulticityTimeline\n  }\n}\n\nfragment OneWayTimeline on BookingOneWay {\n  trip {\n    ...Timeline\n  }\n}\n\nfragment ReturnTimeline on BookingReturn {\n  outbound {\n    ...Timeline\n  }\n  inbound {\n    ...Timeline\n  }\n}\n\nfragment MulticityTimeline on BookingMulticity {\n  trips {\n    ...Timeline\n  }\n}\n\nfragment Timeline on Trip {\n  legs {\n    departure {\n      ...TimelineDeparture_routeStop\n    }\n    arrival {\n      ...TimelineArrival\n    }\n    ...TimelineDeparture_legInfo\n    id\n  }\n}\n\nfragment TimelineDeparture_routeStop on RouteStop {\n  ...TimelineTitle\n}\n\nfragment TimelineArrival on RouteStop {\n  ...TimelineTitle\n}\n\nfragment TimelineDeparture_legInfo on Leg {\n  flightNumber\n  airline {\n    name\n    logoUrl\n  }\n}\n\nfragment TimelineTitle on RouteStop {\n  localTime\n  airport {\n    locationId\n    city {\n      name\n    }\n    id\n  }\n}\n\nfragment TripInfoOneWay on BookingOneWay {\n  trip {\n    ...TripCities\n    ...TripTimes\n  }\n}\n\nfragment TripInfoReturn on BookingReturn {\n  outbound {\n    ...TripCities\n    ...TripTimes\n  }\n  inbound {\n    ...TripTimes\n  }\n}\n\nfragment TripInfoMulticity on BookingMulticity {\n  trips {\n    ...TripCities\n    ...TripTimes\n  }\n}\n\nfragment TripCities on Trip {\n  departure {\n    ...Location\n  }\n  arrival {\n    ...Location\n  }\n}\n\nfragment TripTimes on Trip {\n  ...Duration\n  departure {\n    ...DateTime\n  }\n  arrival {\n    ...DateTime\n  }\n}\n\nfragment Duration on Trip {\n  duration\n}\n\nfragment DateTime on RouteStop {\n  localTime\n}\n\nfragment Location on RouteStop {\n  airport {\n    city {\n      name\n    }\n    ...CountryFlag\n    id\n  }\n}\n\nfragment CountryFlag on Location {\n  countryFlagURL\n}\n\nfragment StatusBarIcon on BookingInterface {\n  status\n  isPastBooking\n}\n\nfragment CardContent on BookingInterface {\n  __typename\n  ...ExploreOneWay\n  ...ExploreReturn\n  ...ExploreMulticity\n}\n\nfragment ExploreOneWay on BookingInterface {\n  ... on BookingOneWay {\n    trip {\n      ...ExploreText\n    }\n  }\n}\n\nfragment ExploreReturn on BookingInterface {\n  ... on BookingReturn {\n    outbound {\n      ...ExploreText\n    }\n  }\n}\n\nfragment ExploreMulticity on BookingInterface {\n  ... on BookingMulticity {\n    trips {\n      departure {\n        time\n      }\n      ...ExploreText\n    }\n  }\n}\n\nfragment ExploreText on Trip {\n  departure {\n    time\n  }\n  arrival {\n    airport {\n      city {\n        name\n      }\n      id\n    }\n  }\n}\n",
+  "text": "query MainMenuRefetchQuery(\n  $id: Int!\n  $authToken: String!\n) {\n  singleBooking(id: $id, authToken: $authToken) {\n    __typename\n    ...MainMenu\n    id\n  }\n}\n\nfragment MainMenu on BookingInterface {\n  databaseId\n  authToken\n  isPastBooking\n  ...ExploreCity\n  ...Header\n  ...PassengerMenuGroup\n  ...MissingInformation\n}\n\nfragment ExploreCity on BookingInterface {\n  ...CardContent\n}\n\nfragment Header on BookingInterface {\n  isPastBooking\n  ...StatusBar\n  ...TripInfo\n  ...TripOverview\n}\n\nfragment PassengerMenuGroup on BookingInterface {\n  ...PassengerMenuDetail\n}\n\nfragment MissingInformation on BookingInterface {\n  passengers {\n    travelDocument {\n      idNumber\n    }\n  }\n}\n\nfragment PassengerMenuDetail on BookingInterface {\n  ...Visa\n  passengers {\n    databaseId\n    ...Passenger\n  }\n}\n\nfragment Visa on BookingInterface {\n  passengers {\n    visaInformation {\n      requiredIn {\n        name\n        id\n      }\n      warningIn {\n        name\n        id\n      }\n    }\n  }\n}\n\nfragment Passenger on Passenger {\n  fullName\n  title\n  birthday\n}\n\nfragment StatusBar on BookingInterface {\n  ...StatusBarIcon\n  databaseId\n}\n\nfragment TripInfo on BookingInterface {\n  __typename\n  ... on BookingOneWay {\n    ...TripInfoOneWay\n  }\n  ... on BookingReturn {\n    ...TripInfoReturn\n  }\n  ... on BookingMulticity {\n    ...TripInfoMulticity\n  }\n}\n\nfragment TripOverview on BookingInterface {\n  __typename\n  ... on BookingOneWay {\n    ...OneWayTimeline\n  }\n  ... on BookingReturn {\n    ...ReturnTimeline\n  }\n  ... on BookingMulticity {\n    ...MulticityTimeline\n  }\n}\n\nfragment OneWayTimeline on BookingOneWay {\n  trip {\n    ...Timeline\n  }\n}\n\nfragment ReturnTimeline on BookingReturn {\n  outbound {\n    ...Timeline\n  }\n  inbound {\n    ...Timeline\n  }\n}\n\nfragment MulticityTimeline on BookingMulticity {\n  trips {\n    ...Timeline\n  }\n}\n\nfragment Timeline on Trip {\n  legs {\n    departure {\n      ...TimelineDeparture_routeStop\n    }\n    arrival {\n      ...TimelineArrival\n    }\n    ...TimelineDeparture_legInfo\n    id\n  }\n}\n\nfragment TimelineDeparture_routeStop on RouteStop {\n  ...TimelineTitle\n}\n\nfragment TimelineArrival on RouteStop {\n  ...TimelineTitle\n}\n\nfragment TimelineDeparture_legInfo on Leg {\n  flightNumber\n  airline {\n    name\n    logoUrl\n  }\n}\n\nfragment TimelineTitle on RouteStop {\n  localTime\n  airport {\n    locationId\n    city {\n      name\n    }\n    id\n  }\n}\n\nfragment TripInfoOneWay on BookingOneWay {\n  trip {\n    ...TripCities\n    ...TripTimes\n  }\n}\n\nfragment TripInfoReturn on BookingReturn {\n  outbound {\n    ...TripCities\n    ...TripTimes\n  }\n  inbound {\n    ...TripTimes\n  }\n}\n\nfragment TripInfoMulticity on BookingMulticity {\n  trips {\n    ...TripCities\n    ...TripTimes\n  }\n}\n\nfragment TripCities on Trip {\n  departure {\n    ...Location\n  }\n  arrival {\n    ...Location\n  }\n}\n\nfragment TripTimes on Trip {\n  ...Duration\n  departure {\n    ...DateTime\n  }\n  arrival {\n    ...DateTime\n  }\n}\n\nfragment Duration on Trip {\n  duration\n}\n\nfragment DateTime on RouteStop {\n  localTime\n}\n\nfragment Location on RouteStop {\n  airport {\n    city {\n      name\n    }\n    ...CountryFlag\n    id\n  }\n}\n\nfragment CountryFlag on Location {\n  countryFlagURL\n}\n\nfragment StatusBarIcon on BookingInterface {\n  status\n  isPastBooking\n}\n\nfragment CardContent on BookingInterface {\n  __typename\n  ...ExploreOneWay\n  ...ExploreReturn\n  ...ExploreMulticity\n}\n\nfragment ExploreOneWay on BookingInterface {\n  ... on BookingOneWay {\n    trip {\n      ...ExploreText\n    }\n  }\n}\n\nfragment ExploreReturn on BookingInterface {\n  ... on BookingReturn {\n    outbound {\n      ...ExploreText\n    }\n  }\n}\n\nfragment ExploreMulticity on BookingInterface {\n  ... on BookingMulticity {\n    trips {\n      departure {\n        time\n      }\n      ...ExploreText\n    }\n  }\n}\n\nfragment ExploreText on Trip {\n  departure {\n    time\n  }\n  arrival {\n    airport {\n      ...ExploreMenuGroup\n      city {\n        name\n      }\n      id\n    }\n  }\n}\n\nfragment ExploreMenuGroup on Location {\n  code\n}\n",
   "metadata": {},
   "fragment": {
     "kind": "Fragment",
diff --git a/app/MMB/src/components/exploreCity/CardContent.js b/app/MMB/src/components/exploreCity/CardContent.js
index 009af39d..233c69bf 100644
--- a/app/MMB/src/components/exploreCity/CardContent.js
+++ b/app/MMB/src/components/exploreCity/CardContent.js
@@ -20,7 +20,6 @@ const CardContent = (props: Props) => {
       {type === 'BookingOneWay' && <ExploreOneWay data={props.data} />}
       {type === 'BookingReturn' && <ExploreReturn data={props.data} />}
       {type === 'BookingMulticity' && <ExploreMulticity data={props.data} />}
-      {/* TODO: Add button */}
     </React.Fragment>
   );
 };
diff --git a/app/MMB/src/components/exploreCity/ExploreCity.js b/app/MMB/src/components/exploreCity/ExploreCity.js
index 1ab7e549..802a05b7 100644
--- a/app/MMB/src/components/exploreCity/ExploreCity.js
+++ b/app/MMB/src/components/exploreCity/ExploreCity.js
@@ -15,9 +15,7 @@ type Props = {|
 const ExploreCity = (props: Props) => (
   <View style={styles.container}>
     <SimpleCard style={styles.card}>
-      <View style={styles.cardContent}>
-        <CardContent data={props.data} />
-      </View>
+      <CardContent data={props.data} />
     </SimpleCard>
   </View>
 );
@@ -36,10 +34,8 @@ const styles = StyleSheet.create({
     marginTop: 21,
   },
   card: {
-    paddingTop: 30,
+    paddingTop: 20,
+    paddingBottom: 0,
     paddingHorizontal: 0,
   },
-  cardContent: {
-    paddingHorizontal: 20,
-  },
 });
diff --git a/app/MMB/src/components/exploreCity/ExploreText.js b/app/MMB/src/components/exploreCity/ExploreText.js
index 8c8164c8..e0abaac3 100644
--- a/app/MMB/src/components/exploreCity/ExploreText.js
+++ b/app/MMB/src/components/exploreCity/ExploreText.js
@@ -1,12 +1,15 @@
 // @flow strict
 
 import * as React from 'react';
+import { View } from 'react-native';
 import { Translation, DateUtils } from '@kiwicom/mobile-localization';
 import { StyleSheet, Text, Color } from '@kiwicom/mobile-shared';
 import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
+import { SeparatorFullWidth } from '@kiwicom/mobile-navigation';
 import idx from 'idx';
 
 import ExploreButton from './ExploreButton';
+import ExploreMenuGroup from './menuGroup/ExploreMenuGroup';
 import type { ExploreText as TripType } from './__generated__/ExploreText.graphql';
 
 type Props = {|
@@ -17,32 +20,39 @@ const ExploreText = (props: Props) => {
   const city = idx(props.data, _ => _.arrival.airport.city.name);
   const date = new Date(idx(props.data, _ => _.departure.time) || 0);
   const daysLeft = DateUtils.diffInDays(date, DateUtils.getUTCToday());
+  const airport = idx(props.data, _ => _.arrival.airport);
   return (
     <React.Fragment>
-      <Text style={styles.title}>
-        {daysLeft > 0 ? (
-          <Translation id="mmb.main_menu.explore_city.prepare_for_trip" />
-        ) : (
-          <Translation
-            id="mmb.main_menu.explore_city.spending_time_in"
-            values={{ city }}
-          />
-        )}
-      </Text>
-      <Text style={styles.subText}>
-        {daysLeft > 0 ? (
-          <Translation
-            id="mmb.main_menu.eplore_city.your_trip_in_days"
-            values={{
-              city,
-              days: daysLeft,
-            }}
-          />
-        ) : (
-          <Translation id="mmb.main_menu.explore_city.find_stuff_to_do" />
-        )}
-      </Text>
-      <ExploreButton cityName={city || ''} />
+      <View style={styles.padding}>
+        <Text style={styles.title}>
+          {daysLeft > 0 ? (
+            <Translation id="mmb.main_menu.explore_city.prepare_for_trip" />
+          ) : (
+            <Translation
+              id="mmb.main_menu.explore_city.spending_time_in"
+              values={{ city }}
+            />
+          )}
+        </Text>
+        <Text style={styles.subText}>
+          {daysLeft > 0 ? (
+            <Translation
+              id="mmb.main_menu.eplore_city.your_trip_in_days"
+              values={{
+                city,
+                days: daysLeft,
+              }}
+            />
+          ) : (
+            <Translation id="mmb.main_menu.explore_city.find_stuff_to_do" />
+          )}
+        </Text>
+      </View>
+      <View style={[styles.padding, styles.buttonContainer]}>
+        <ExploreButton cityName={city || ''} />
+      </View>
+      <SeparatorFullWidth />
+      <ExploreMenuGroup data={airport} />
     </React.Fragment>
   );
 };
@@ -56,6 +66,7 @@ export default createFragmentContainer(
       }
       arrival {
         airport {
+          ...ExploreMenuGroup
           city {
             name
           }
@@ -75,4 +86,10 @@ const styles = StyleSheet.create({
     fontSize: 12,
     marginTop: 7,
   },
+  padding: {
+    paddingHorizontal: 20,
+  },
+  buttonContainer: {
+    marginBottom: 25,
+  },
 });
diff --git a/app/MMB/src/components/exploreCity/__generated__/ExploreText.graphql.js b/app/MMB/src/components/exploreCity/__generated__/ExploreText.graphql.js
index acdad3f3..a2102605 100644
--- a/app/MMB/src/components/exploreCity/__generated__/ExploreText.graphql.js
+++ b/app/MMB/src/components/exploreCity/__generated__/ExploreText.graphql.js
@@ -8,6 +8,7 @@
 
 /*::
 import type { ConcreteFragment } from 'relay-runtime';
+type ExploreMenuGroup$ref = any;
 import type { FragmentReference } from "relay-runtime";
 declare export opaque type ExploreText$ref: FragmentReference;
 export type ExploreText = {|
@@ -18,7 +19,8 @@ export type ExploreText = {|
     +airport: ?{|
       +city: ?{|
         +name: ?string
-      |}
+      |},
+      +$fragmentRefs: ExploreMenuGroup$ref,
     |}
   |},
   +$refType: ExploreText$ref,
@@ -69,6 +71,11 @@ const node/*: ConcreteFragment*/ = {
           "concreteType": "Location",
           "plural": false,
           "selections": [
+            {
+              "kind": "FragmentSpread",
+              "name": "ExploreMenuGroup",
+              "args": null
+            },
             {
               "kind": "LinkedField",
               "alias": null,
@@ -94,5 +101,5 @@ const node/*: ConcreteFragment*/ = {
   ]
 };
 // prettier-ignore
-(node/*: any*/).hash = '0f03e6175cd2e10809b5a08a47183f2b';
+(node/*: any*/).hash = '876aeb47c6ffb4c886ebada67d270c1c';
 module.exports = node;
diff --git a/app/MMB/src/components/exploreCity/menuGroup/ExploreMenuGroup.js b/app/MMB/src/components/exploreCity/menuGroup/ExploreMenuGroup.js
new file mode 100644
index 00000000..c3de8ece
--- /dev/null
+++ b/app/MMB/src/components/exploreCity/menuGroup/ExploreMenuGroup.js
@@ -0,0 +1,45 @@
+// @flow strict
+
+import * as React from 'react';
+import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
+import { TextIcon } from '@kiwicom/mobile-shared';
+import { MenuGroup } from '@kiwicom/mobile-navigation';
+import { Translation } from '@kiwicom/mobile-localization';
+import idx from 'idx';
+
+import ExploreMenuItem from './ExploreMenuItem';
+import type { ExploreMenuGroup as LocationType } from './__generated__/ExploreMenuGroup.graphql';
+
+type Props = {|
+  +data: LocationType,
+|};
+
+class ExploreMenuGroup extends React.Component<Props> {
+  onOrderTransportPress = () => {
+    console.warn('TODO');
+  };
+
+  render = () => (
+    <MenuGroup>
+      <ExploreMenuItem
+        title={
+          <Translation
+            id="mmb.main_menu.explore_city.explore_menu_group.order_transport"
+            values={{ iata: idx(this.props.data, _ => _.code) || '' }}
+          />
+        }
+        onPress={this.onOrderTransportPress}
+        icon={<TextIcon code=";" />}
+      />
+    </MenuGroup>
+  );
+}
+
+export default createFragmentContainer(
+  ExploreMenuGroup,
+  graphql`
+    fragment ExploreMenuGroup on Location {
+      code
+    }
+  `,
+);
diff --git a/app/MMB/src/components/exploreCity/menuGroup/ExploreMenuItem.js b/app/MMB/src/components/exploreCity/menuGroup/ExploreMenuItem.js
new file mode 100644
index 00000000..52800a18
--- /dev/null
+++ b/app/MMB/src/components/exploreCity/menuGroup/ExploreMenuItem.js
@@ -0,0 +1,61 @@
+// @flow strict
+
+import * as React from 'react';
+import { View, Platform } from 'react-native';
+import {
+  TextIcon,
+  StyleSheet,
+  Color,
+  Icon,
+  Touchable,
+} from '@kiwicom/mobile-shared';
+import type { TranslationType } from '@kiwicom/mobile-localization';
+
+type Props = {|
+  +icon: React.Element<typeof TextIcon>,
+  +onPress: () => void,
+  +title: TranslationType,
+|};
+
+export default function ExploreMenuItem(props: Props) {
+  const icon = React.cloneElement(props.icon, {
+    style: [props.icon.props.style, styles.icon],
+  });
+  return (
+    <Touchable style={[styles.row, styles.button]} onPress={props.onPress}>
+      <React.Fragment>
+        <View style={[styles.row, styles.leftContent]}>
+          {icon}
+          {props.title}
+        </View>
+        <View style={styles.rightArrow}>
+          {Platform.select({
+            ios: <Icon name="chevron-right" size={26} color={Color.brand} />,
+            android: null,
+          })}
+        </View>
+      </React.Fragment>
+    </Touchable>
+  );
+}
+
+const styles = StyleSheet.create({
+  row: {
+    flexDirection: 'row',
+  },
+  button: {
+    padding: 14,
+    justifyContent: 'space-between',
+  },
+  rightArrow: {
+    alignSelf: 'flex-end',
+  },
+  leftContent: {
+    alignItems: 'center',
+  },
+  icon: {
+    marginEnd: 16,
+    color: Color.textLight,
+    fontSize: 18,
+  },
+});
diff --git a/app/MMB/src/components/exploreCity/menuGroup/__generated__/ExploreMenuGroup.graphql.js b/app/MMB/src/components/exploreCity/menuGroup/__generated__/ExploreMenuGroup.graphql.js
new file mode 100644
index 00000000..de835508
--- /dev/null
+++ b/app/MMB/src/components/exploreCity/menuGroup/__generated__/ExploreMenuGroup.graphql.js
@@ -0,0 +1,38 @@
+/**
+ * @flow
+ */
+
+/* eslint-disable */
+
+'use strict';
+
+/*::
+import type { ConcreteFragment } from 'relay-runtime';
+import type { FragmentReference } from "relay-runtime";
+declare export opaque type ExploreMenuGroup$ref: FragmentReference;
+export type ExploreMenuGroup = {|
+  +code: ?string,
+  +$refType: ExploreMenuGroup$ref,
+|};
+*/
+
+
+const node/*: ConcreteFragment*/ = {
+  "kind": "Fragment",
+  "name": "ExploreMenuGroup",
+  "type": "Location",
+  "metadata": null,
+  "argumentDefinitions": [],
+  "selections": [
+    {
+      "kind": "ScalarField",
+      "alias": null,
+      "name": "code",
+      "args": null,
+      "storageKey": null
+    }
+  ]
+};
+// prettier-ignore
+(node/*: any*/).hash = '1bc8908689a270942afec22bb6d352bc';
+module.exports = node;
diff --git a/packages/localization/src/vocabularies/ManageMyBooking.js b/packages/localization/src/vocabularies/ManageMyBooking.js
index f168a124..dda8e05c 100644
--- a/packages/localization/src/vocabularies/ManageMyBooking.js
+++ b/packages/localization/src/vocabularies/ManageMyBooking.js
@@ -248,6 +248,8 @@ export default {
   'mmb.main_menu.explore_city.spending_time_in': 'Spending time in __city__?',
   'mmb.main_menu.explore_city.find_stuff_to_do': 'Find something to do',
   'mmb.main_menu.explore_city.card_content.explore': 'Explore __city__',
+  'mmb.main_menu.explore_city.explore_menu_group.order_transport':
+    'Order transportation to __iata__',
 
   'mmb.main_menu.manage': 'Manage',
   'mmb.main_menu.manage.help': 'Help',
diff --git a/packages/navigation/src/MenuItem.js b/packages/navigation/src/MenuItem.js
index abda3528..6b7c43e9 100644
--- a/packages/navigation/src/MenuItem.js
+++ b/packages/navigation/src/MenuItem.js
@@ -1,7 +1,7 @@
 // @flow
 
 import * as React from 'react';
-import { View } from 'react-native';
+import { View, Platform } from 'react-native';
 import {
   Color,
   TextIcon,
@@ -76,11 +76,14 @@ function MenuItem(props: Props) {
           <View style={styleSheet.rightArrow}>{props.actionIcon}</View>
         ) : (
           <AdaptableLayout
-            renderOnNarrow={
-              <View style={styleSheet.rightArrow}>
-                <Icon name="chevron-right" size={26} color={Color.brand} />
-              </View>
-            }
+            renderOnNarrow={Platform.select({
+              ios: (
+                <View style={styleSheet.rightArrow}>
+                  <Icon name="chevron-right" size={26} color={Color.brand} />
+                </View>
+              ),
+              android: null,
+            })}
           />
         )}
       </React.Fragment>
diff --git a/packages/playground/src/Playground.js b/packages/playground/src/Playground.js
index fbb7735e..85df9a4d 100644
--- a/packages/playground/src/Playground.js
+++ b/packages/playground/src/Playground.js
@@ -40,7 +40,7 @@ export default class Playground extends React.Component<Props> {
 
     return {
       title: 'Playground',
-      headerLeft: <HeaderBackButton tintColor={Color.white} onPress={goBack} />,
+      headerLeft: <HeaderBackButton tintColor={Color.brand} onPress={goBack} />,
     };
   };
 
diff --git a/packages/playground/src/PlaygroundImports.js b/packages/playground/src/PlaygroundImports.js
index 9174a3bd..d8917864 100644
--- a/packages/playground/src/PlaygroundImports.js
+++ b/packages/playground/src/PlaygroundImports.js
@@ -16,10 +16,18 @@ import '../../../app/MMB/src/scenes/passenger/visa/__tests__/VisaRequired.test.j
 import '../../../app/MMB/src/scenes/passenger/__tests__/Passenger.test.js';
 import '../../../app/MMB/src/components/alert/__tests__/Alert.test.js';
 import '../../../packages/shared/src/popup/__tests__/ButtonPopupPlayground.test.js';
+import '../../../packages/shared/src/loaders/__tests__/IconLoading.test.js';
+import '../../../packages/shared/src/loaders/__tests__/FullPageLoading.test.js';
 import '../../../packages/shared/src/forms/datePicker/__tests__/DatePicker.test.js';
+import '../../../packages/shared/src/forms/__tests__/TextInput.test.js';
+import '../../../packages/shared/src/forms/__tests__/Switch.test.js';
 import '../../../packages/shared/src/forms/__tests__/Slider.test.js';
+import '../../../packages/shared/src/forms/__tests__/Checkbox.test.js';
+import '../../../packages/shared/src/forms/__tests__/AgePicker.test.js';
 import '../../../packages/shared/src/buttons/__tests__/TextButton.test.js';
+import '../../../packages/shared/src/buttons/__tests__/LinkButton.test.js';
 import '../../../packages/shared/src/buttons/__tests__/IncrementDecrementButtons.test.js';
+import '../../../packages/shared/src/buttons/__tests__/Button.test.js';
 import '../../../packages/shared/src/__tests__/Text.test.js';
 import '../../../packages/shared/src/__tests__/SimpleCard.test.js';
 import '../../../packages/shared/src/__tests__/ReadMore.test.js';
diff --git a/packages/shared/index.js b/packages/shared/index.js
index 83a9fca8..f9847d4a 100644
--- a/packages/shared/index.js
+++ b/packages/shared/index.js
@@ -22,11 +22,10 @@ export { default as AppleWalletButton } from './src/buttons/AppleWalletButton';
 export { default as AgePicker } from './src/forms/AgePicker';
 export { default as Checkbox } from './src/forms/Checkbox';
 export { default as DatePicker } from './src/forms/datePicker/DatePicker';
-export { default as ErrorMessage } from './src/forms/ErrorMessage';
 export { default as NumberControl } from './src/forms/NumberControl';
 export { default as Slider } from './src/forms/Slider';
 export { default as TextInput } from './src/forms/TextInput';
-export { default as Switch } from './src/forms/Switch.js';
+export { default as Switch } from './src/forms/Switch';
 
 export { default as FullPageLoading } from './src/loaders/FullPageLoading';
 export { default as IconLoading } from './src/loaders/IconLoading';
@@ -64,6 +63,7 @@ export { default as WebView } from './src/WebView';
 export { default as SimpleCard } from './src/SimpleCard';
 
 export { default as GeneralError } from './src/errors/GeneralError';
+export { default as ErrorMessage } from './src/errors/ErrorMessage';
 
 export { default as ReadMore } from './src/ReadMore';
 export { default as BottomSheet } from './src/BottomSheet';


Test patch:
diff --git a/packages/shared/src/buttons/__tests__/Button.test.js b/packages/shared/src/buttons/__tests__/Button.test.js
new file mode 100644
index 00000000..733d9f01
--- /dev/null
+++ b/packages/shared/src/buttons/__tests__/Button.test.js
@@ -0,0 +1,19 @@
+// @flow strict
+
+import * as React from 'react';
+import { PlaygroundRenderer } from '@kiwicom/mobile-playground';
+import { Translation } from '@kiwicom/mobile-localization';
+
+import Button from '../Button';
+
+const noop = () => {};
+
+describe('Button', () => {
+  it('renders', () => {
+    PlaygroundRenderer.render(
+      <Button onPress={noop}>
+        <Translation passThrough="Button" />
+      </Button>,
+    );
+  });
+});
diff --git a/packages/shared/src/buttons/__tests__/IncrementDecrementButtons.test.js b/packages/shared/src/buttons/__tests__/IncrementDecrementButtons.test.js
index 3ac2408e..4c7de8f6 100644
--- a/packages/shared/src/buttons/__tests__/IncrementDecrementButtons.test.js
+++ b/packages/shared/src/buttons/__tests__/IncrementDecrementButtons.test.js
@@ -31,7 +31,7 @@ describe('IncrementDecrementButtons', () => {
       <IncrementDecrementButtons
         onIncrement={onIncrement}
         onDecrement={onDecrement}
-        number={1}
+        number={2}
         min={1}
         max={3}
       />,
diff --git a/packages/shared/src/buttons/__tests__/LinkButton.test.js b/packages/shared/src/buttons/__tests__/LinkButton.test.js
new file mode 100644
index 00000000..8b0ff582
--- /dev/null
+++ b/packages/shared/src/buttons/__tests__/LinkButton.test.js
@@ -0,0 +1,20 @@
+// @flow strict
+
+import * as React from 'react';
+import { PlaygroundRenderer } from '@kiwicom/mobile-playground';
+import { Translation } from '@kiwicom/mobile-localization';
+
+import LinkButton from '../LinkButton';
+
+const noop = () => {};
+
+describe('Button', () => {
+  it('renders', () => {
+    PlaygroundRenderer.render(
+      <LinkButton
+        onPress={noop}
+        title={<Translation passThrough="Link button" />}
+      />,
+    );
+  });
+});
diff --git a/packages/shared/src/buttons/__tests__/__snapshots__/Button.test.js.snap b/packages/shared/src/buttons/__tests__/__snapshots__/Button.test.js.snap
new file mode 100644
index 00000000..5a4bb26b
--- /dev/null
+++ b/packages/shared/src/buttons/__tests__/__snapshots__/Button.test.js.snap
@@ -0,0 +1,29 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Button renders 1`] = `
+<Touchable
+  accessibilityComponentType="button"
+  borderlessRipple={false}
+  disabled={false}
+  onPress={[Function]}
+  rippleColor="rgba(0, 0, 0, .32)"
+  style={
+    Array [
+      Object {
+        "alignItems": "center",
+        "backgroundColor": "#00a991",
+        "borderRadius": 6,
+        "flexGrow": 1,
+        "height": 44,
+        "justifyContent": "center",
+        "paddingHorizontal": 11,
+      },
+      undefined,
+    ]
+  }
+>
+  <Translation
+    passThrough="Button"
+  />
+</Touchable>
+`;
diff --git a/packages/shared/src/buttons/__tests__/__snapshots__/IncrementDecrementButtons.test.js.snap b/packages/shared/src/buttons/__tests__/__snapshots__/IncrementDecrementButtons.test.js.snap
index 65e69c6c..d537b537 100644
--- a/packages/shared/src/buttons/__tests__/__snapshots__/IncrementDecrementButtons.test.js.snap
+++ b/packages/shared/src/buttons/__tests__/__snapshots__/IncrementDecrementButtons.test.js.snap
@@ -32,7 +32,7 @@ exports[`IncrementDecrementButtons renders 1`] = `
         }
       }
       text="–"
-      touchable={false}
+      touchable={true}
     />
   </Component>
   <Button
diff --git a/packages/shared/src/buttons/__tests__/__snapshots__/LinkButton.test.js.snap b/packages/shared/src/buttons/__tests__/__snapshots__/LinkButton.test.js.snap
new file mode 100644
index 00000000..f291ba82
--- /dev/null
+++ b/packages/shared/src/buttons/__tests__/__snapshots__/LinkButton.test.js.snap
@@ -0,0 +1,29 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Button renders 1`] = `
+<Button
+  disabled={false}
+  onPress={[Function]}
+  style={
+    Object {
+      "backgroundColor": "transparent",
+    }
+  }
+>
+  <ButtonTitle
+    style={
+      Array [
+        Object {
+          "color": "#00a991",
+        },
+        undefined,
+      ]
+    }
+    text={
+      <Translation
+        passThrough="Link button"
+      />
+    }
+  />
+</Button>
+`;
diff --git a/packages/shared/src/forms/ErrorMessage.js b/packages/shared/src/errors/ErrorMessage.js
similarity index 100%
rename from packages/shared/src/forms/ErrorMessage.js
rename to packages/shared/src/errors/ErrorMessage.js
diff --git a/packages/shared/src/forms/__tests__/AgePicker.test.js b/packages/shared/src/forms/__tests__/AgePicker.test.js
new file mode 100644
index 00000000..612bb4ec
--- /dev/null
+++ b/packages/shared/src/forms/__tests__/AgePicker.test.js
@@ -0,0 +1,50 @@
+// @flow strict
+
+import * as React from 'react';
+import { PlaygroundRenderer } from '@kiwicom/mobile-playground';
+import { Translation } from '@kiwicom/mobile-localization';
+
+import TextButton from '../../buttons/TextButton';
+import AgePicker from '../AgePicker';
+
+type State = {|
+  isVisible: boolean,
+  number: number,
+|};
+
+class Wrapper extends React.Component<{||}, State> {
+  state = {
+    isVisible: false,
+    number: 0,
+  };
+
+  toggle = () => {
+    this.setState(state => ({
+      isVisible: !state.isVisible,
+    }));
+  };
+
+  onChange = (number: number) => {
+    this.setState({ number });
+  };
+
+  render = () => (
+    <React.Fragment>
+      <TextButton
+        title={<Translation passThrough="Show age picker" />}
+        onPress={this.toggle}
+      />
+      <AgePicker
+        isVisible={this.state.isVisible}
+        onClose={this.toggle}
+        max={3}
+        min={1}
+        onChange={this.onChange}
+      />
+    </React.Fragment>
+  );
+}
+
+it('renders', () => {
+  PlaygroundRenderer.render(<Wrapper />, false, 'AgePicker');
+});
diff --git a/packages/shared/src/forms/__tests__/Checkbox.test.js b/packages/shared/src/forms/__tests__/Checkbox.test.js
new file mode 100644
index 00000000..be2231ea
--- /dev/null
+++ b/packages/shared/src/forms/__tests__/Checkbox.test.js
@@ -0,0 +1,25 @@
+// @flow strict
+
+import * as React from 'react';
+import { PlaygroundRenderer } from '@kiwicom/mobile-playground';
+import { Translation } from '@kiwicom/mobile-localization';
+
+import Checkbox from '../Checkbox';
+
+const noop = () => {};
+
+it('not checked', () => {
+  PlaygroundRenderer.render(
+    <Checkbox onPress={noop} isChecked={false}>
+      <Translation passThrough="Unchecked" />
+    </Checkbox>,
+  );
+});
+
+it('checked', () => {
+  PlaygroundRenderer.render(
+    <Checkbox onPress={noop} isChecked={true}>
+      <Translation passThrough="Checked" />
+    </Checkbox>,
+  );
+});
diff --git a/packages/shared/src/forms/__tests__/Switch.test.js b/packages/shared/src/forms/__tests__/Switch.test.js
new file mode 100644
index 00000000..120bd2f5
--- /dev/null
+++ b/packages/shared/src/forms/__tests__/Switch.test.js
@@ -0,0 +1,14 @@
+// @flow strict
+
+import * as React from 'react';
+import { PlaygroundRenderer } from '@kiwicom/mobile-playground';
+
+import Switch from '../Switch';
+
+it('renders with false', () => {
+  PlaygroundRenderer.render(<Switch value={false} onValueChange={jest.fn()} />);
+});
+
+it('renders with true', () => {
+  PlaygroundRenderer.render(<Switch value={true} onValueChange={jest.fn()} />);
+});
diff --git a/packages/shared/src/forms/__tests__/TextInput.test.js b/packages/shared/src/forms/__tests__/TextInput.test.js
new file mode 100644
index 00000000..f95231e7
--- /dev/null
+++ b/packages/shared/src/forms/__tests__/TextInput.test.js
@@ -0,0 +1,21 @@
+// @flow strict
+
+import * as React from 'react';
+import { PlaygroundRenderer } from '@kiwicom/mobile-playground';
+import { Translation } from '@kiwicom/mobile-localization';
+
+import TextInput from '../TextInput';
+
+it('renders', () => {
+  PlaygroundRenderer.render(<TextInput />);
+});
+
+it('renders with default value', () => {
+  PlaygroundRenderer.render(<TextInput defaultValue="Default value" />);
+});
+
+it('renders with placeholder', () => {
+  PlaygroundRenderer.render(
+    <TextInput placeholder={<Translation passThrough="Placeholder" />} />,
+  );
+});
diff --git a/packages/shared/src/forms/__tests__/__snapshots__/AgePicker.test.js.snap b/packages/shared/src/forms/__tests__/__snapshots__/AgePicker.test.js.snap
new file mode 100644
index 00000000..b6b622c1
--- /dev/null
+++ b/packages/shared/src/forms/__tests__/__snapshots__/AgePicker.test.js.snap
@@ -0,0 +1,22 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders 1`] = `
+<React.Fragment>
+  <TextButton
+    disabled={false}
+    onPress={[Function]}
+    title={
+      <Translation
+        passThrough="Show age picker"
+      />
+    }
+  />
+  <AgePicker
+    isVisible={false}
+    max={3}
+    min={1}
+    onChange={[Function]}
+    onClose={[Function]}
+  />
+</React.Fragment>
+`;
diff --git a/packages/shared/src/forms/__tests__/__snapshots__/Checkbox.test.js.snap b/packages/shared/src/forms/__tests__/__snapshots__/Checkbox.test.js.snap
new file mode 100644
index 00000000..cb41f2cc
--- /dev/null
+++ b/packages/shared/src/forms/__tests__/__snapshots__/Checkbox.test.js.snap
@@ -0,0 +1,82 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`checked 1`] = `
+<TouchableWithoutFeedback
+  onPress={[Function]}
+>
+  <Component
+    style={
+      Array [
+        Object {
+          "flexDirection": "row",
+          "paddingBottom": 8,
+          "paddingTop": 8,
+        },
+        undefined,
+      ]
+    }
+  >
+    <Component
+      style={
+        Object {
+          "flex": 3,
+          "height": 26,
+          "justifyContent": "center",
+        }
+      }
+    >
+      <Translation
+        passThrough="Checked"
+      />
+    </Component>
+    <Component
+      style={
+        Object {
+          "alignItems": "flex-end",
+          "flex": 1,
+          "justifyContent": "center",
+        }
+      }
+    >
+      <Icon
+        color="#00a991"
+        name="check"
+        size={26}
+      />
+    </Component>
+  </Component>
+</TouchableWithoutFeedback>
+`;
+
+exports[`not checked 1`] = `
+<TouchableWithoutFeedback
+  onPress={[Function]}
+>
+  <Component
+    style={
+      Array [
+        Object {
+          "flexDirection": "row",
+          "paddingBottom": 8,
+          "paddingTop": 8,
+        },
+        undefined,
+      ]
+    }
+  >
+    <Component
+      style={
+        Object {
+          "flex": 3,
+          "height": 26,
+          "justifyContent": "center",
+        }
+      }
+    >
+      <Translation
+        passThrough="Unchecked"
+      />
+    </Component>
+  </Component>
+</TouchableWithoutFeedback>
+`;
diff --git a/packages/shared/src/forms/__tests__/__snapshots__/Switch.test.js.snap b/packages/shared/src/forms/__tests__/__snapshots__/Switch.test.js.snap
new file mode 100644
index 00000000..bb6a9da6
--- /dev/null
+++ b/packages/shared/src/forms/__tests__/__snapshots__/Switch.test.js.snap
@@ -0,0 +1,19 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders with false 1`] = `
+<Switch
+  disabled={false}
+  onTintColor="#00a991"
+  onValueChange={[MockFunction]}
+  value={false}
+/>
+`;
+
+exports[`renders with true 1`] = `
+<Switch
+  disabled={false}
+  onTintColor="#00a991"
+  onValueChange={[MockFunction]}
+  value={true}
+/>
+`;
diff --git a/packages/shared/src/forms/__tests__/__snapshots__/TextInput.test.js.snap b/packages/shared/src/forms/__tests__/__snapshots__/TextInput.test.js.snap
new file mode 100644
index 00000000..14b8fc44
--- /dev/null
+++ b/packages/shared/src/forms/__tests__/__snapshots__/TextInput.test.js.snap
@@ -0,0 +1,121 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders 1`] = `
+<Component
+  style={
+    Object {
+      "flexDirection": "row",
+      "height": 47,
+    }
+  }
+>
+  <TextInput
+    allowFontScaling={true}
+    autoCorrect={false}
+    onChangeText={[Function]}
+    placeholder={null}
+    style={
+      Array [
+        Object {
+          "fontSize": 14,
+        },
+        Object {
+          "backgroundColor": "#e8edf1",
+          "borderRadius": 6,
+          "color": "#171b1e",
+          "flex": 1,
+          "padding": 10,
+        },
+      ]
+    }
+    underlineColorAndroid="transparent"
+  />
+</Component>
+`;
+
+exports[`renders with default value 1`] = `
+<Component
+  style={
+    Object {
+      "flexDirection": "row",
+      "height": 47,
+    }
+  }
+>
+  <TextInput
+    allowFontScaling={true}
+    autoCorrect={false}
+    defaultValue="Default value"
+    onChangeText={[Function]}
+    placeholder={null}
+    style={
+      Array [
+        Object {
+          "fontSize": 14,
+        },
+        Object {
+          "backgroundColor": "#e8edf1",
+          "borderRadius": 6,
+          "color": "#171b1e",
+          "flex": 1,
+          "padding": 10,
+        },
+      ]
+    }
+    underlineColorAndroid="transparent"
+  />
+</Component>
+`;
+
+exports[`renders with placeholder 1`] = `
+<Component
+  style={
+    Object {
+      "flexDirection": "row",
+      "height": 47,
+    }
+  }
+>
+  <TextInput
+    allowFontScaling={true}
+    autoCorrect={false}
+    onChangeText={[Function]}
+    placeholder={null}
+    style={
+      Array [
+        Object {
+          "fontSize": 14,
+        },
+        Object {
+          "backgroundColor": "#e8edf1",
+          "borderRadius": 6,
+          "color": "#171b1e",
+          "flex": 1,
+          "padding": 10,
+        },
+      ]
+    }
+    underlineColorAndroid="transparent"
+  />
+  <Text
+    pointerEvents="none"
+    style={
+      Array [
+        Object {
+          "fontSize": 14,
+        },
+        Object {
+          "color": "#7f91a8",
+          "padding": 10,
+          "paddingVertical": 15,
+          "position": "absolute",
+        },
+      ]
+    }
+  >
+    <Translation
+      passThrough="Placeholder"
+    />
+  </Text>
+</Component>
+`;
diff --git a/packages/shared/src/loaders/__tests__/FullPageLoading.test.js b/packages/shared/src/loaders/__tests__/FullPageLoading.test.js
new file mode 100644
index 00000000..3b3d5689
--- /dev/null
+++ b/packages/shared/src/loaders/__tests__/FullPageLoading.test.js
@@ -0,0 +1,10 @@
+// @flow strict
+
+import * as React from 'react';
+import { PlaygroundRenderer } from '@kiwicom/mobile-playground';
+
+import FullPageLoading from '../FullPageLoading';
+
+it('renders', () => {
+  PlaygroundRenderer.render(<FullPageLoading />);
+});
diff --git a/packages/shared/src/loaders/__tests__/IconLoading.test.js b/packages/shared/src/loaders/__tests__/IconLoading.test.js
new file mode 100644
index 00000000..465c748a
--- /dev/null
+++ b/packages/shared/src/loaders/__tests__/IconLoading.test.js
@@ -0,0 +1,10 @@
+// @flow strict
+
+import * as React from 'react';
+import { PlaygroundRenderer } from '@kiwicom/mobile-playground';
+
+import IconLoading from '../IconLoading';
+
+it('renders', () => {
+  PlaygroundRenderer.render(<IconLoading />);
+});
diff --git a/packages/shared/src/loaders/__tests__/__snapshots__/FullPageLoading.test.js.snap b/packages/shared/src/loaders/__tests__/__snapshots__/FullPageLoading.test.js.snap
new file mode 100644
index 00000000..816884d9
--- /dev/null
+++ b/packages/shared/src/loaders/__tests__/__snapshots__/FullPageLoading.test.js.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders 1`] = `
+<CenteredView>
+  <IconLoading
+    size="small"
+  />
+</CenteredView>
+`;
diff --git a/packages/shared/src/loaders/__tests__/__snapshots__/IconLoading.test.js.snap b/packages/shared/src/loaders/__tests__/__snapshots__/IconLoading.test.js.snap
new file mode 100644
index 00000000..d6abe0b9
--- /dev/null
+++ b/packages/shared/src/loaders/__tests__/__snapshots__/IconLoading.test.js.snap
@@ -0,0 +1,10 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders 1`] = `
+<ActivityIndicator
+  animating={true}
+  color="#00a991"
+  hidesWhenStopped={true}
+  size="small"
+/>
+`;