Repository: kiwicom/mobile
Pull request #805 (2018-07-02 15:06:16)

MMB: Add return outbound flights to boarding passes


Patch:
diff --git a/app/MMB/src/scenes/tickets/__generated__/TicketRefetchQuery.graphql.js b/app/MMB/src/scenes/tickets/__generated__/TicketRefetchQuery.graphql.js
index 52ac0812..ad03ce69 100644
--- a/app/MMB/src/scenes/tickets/__generated__/TicketRefetchQuery.graphql.js
+++ b/app/MMB/src/scenes/tickets/__generated__/TicketRefetchQuery.graphql.js
@@ -1,6 +1,6 @@
 /**
  * @flow
- * @relayHash 66f243440c2fb2dbea1b2f4f4de76900
+ * @relayHash 5252d2c2ca96b1c1240235e00e79d83b
  */
 
 /* eslint-disable */
@@ -54,20 +54,34 @@ fragment ETicket on BookingAssets {
 }
 
 fragment BoardingPassReturn on BookingReturn {
+  ...OutboundFlights
+}
+
+fragment OutboundFlights on BookingReturn {
   outbound {
     legs {
       id
-      departure {
-        airport {
-          city {
-            name
-          }
-          id
-        }
+      ...FlightFromTo
+    }
+  }
+}
+
+fragment FlightFromTo on Leg {
+  departure {
+    localTime
+    airport {
+      city {
+        name
       }
-      boardingPass {
-        boardingPassUrl
+      id
+    }
+  }
+  arrival {
+    airport {
+      city {
+        name
       }
+      id
     }
   }
 }
@@ -96,13 +110,43 @@ v2 = {
   "name": "id",
   "args": null,
   "storageKey": null
+},
+v3 = {
+  "kind": "LinkedField",
+  "alias": null,
+  "name": "airport",
+  "storageKey": null,
+  "args": null,
+  "concreteType": "Location",
+  "plural": false,
+  "selections": [
+    {
+      "kind": "LinkedField",
+      "alias": null,
+      "name": "city",
+      "storageKey": null,
+      "args": null,
+      "concreteType": "LocationArea",
+      "plural": false,
+      "selections": [
+        {
+          "kind": "ScalarField",
+          "alias": null,
+          "name": "name",
+          "args": null,
+          "storageKey": null
+        }
+      ]
+    },
+    v2
+  ]
 };
 return {
   "kind": "Request",
   "operationKind": "query",
   "name": "TicketRefetchQuery",
   "id": null,
-  "text": "query TicketRefetchQuery(\n  $id: ID!\n) {\n  node(id: $id) {\n    __typename\n    ... on BookingInterface {\n      ...TicketRefetch\n    }\n    id\n  }\n}\n\nfragment TicketRefetch on BookingInterface {\n  id\n  ...BoardingPasses\n  assets {\n    ...ETicket\n  }\n}\n\nfragment BoardingPasses on Node {\n  __typename\n  ... on BookingReturn {\n    ...BoardingPassReturn\n  }\n}\n\nfragment ETicket on BookingAssets {\n  ticketUrl\n}\n\nfragment BoardingPassReturn on BookingReturn {\n  outbound {\n    legs {\n      id\n      departure {\n        airport {\n          city {\n            name\n          }\n          id\n        }\n      }\n      boardingPass {\n        boardingPassUrl\n      }\n    }\n  }\n}\n",
+  "text": "query TicketRefetchQuery(\n  $id: ID!\n) {\n  node(id: $id) {\n    __typename\n    ... on BookingInterface {\n      ...TicketRefetch\n    }\n    id\n  }\n}\n\nfragment TicketRefetch on BookingInterface {\n  id\n  ...BoardingPasses\n  assets {\n    ...ETicket\n  }\n}\n\nfragment BoardingPasses on Node {\n  __typename\n  ... on BookingReturn {\n    ...BoardingPassReturn\n  }\n}\n\nfragment ETicket on BookingAssets {\n  ticketUrl\n}\n\nfragment BoardingPassReturn on BookingReturn {\n  ...OutboundFlights\n}\n\nfragment OutboundFlights on BookingReturn {\n  outbound {\n    legs {\n      id\n      ...FlightFromTo\n    }\n  }\n}\n\nfragment FlightFromTo on Leg {\n  departure {\n    localTime\n    airport {\n      city {\n        name\n      }\n      id\n    }\n  }\n  arrival {\n    airport {\n      city {\n        name\n      }\n      id\n    }\n  }\n}\n",
   "metadata": {},
   "fragment": {
     "kind": "Fragment",
@@ -202,53 +246,25 @@ return {
                         "plural": false,
                         "selections": [
                           {
-                            "kind": "LinkedField",
+                            "kind": "ScalarField",
                             "alias": null,
-                            "name": "airport",
-                            "storageKey": null,
+                            "name": "localTime",
                             "args": null,
-                            "concreteType": "Location",
-                            "plural": false,
-                            "selections": [
-                              {
-                                "kind": "LinkedField",
-                                "alias": null,
-                                "name": "city",
-                                "storageKey": null,
-                                "args": null,
-                                "concreteType": "LocationArea",
-                                "plural": false,
-                                "selections": [
-                                  {
-                                    "kind": "ScalarField",
-                                    "alias": null,
-                                    "name": "name",
-                                    "args": null,
-                                    "storageKey": null
-                                  }
-                                ]
-                              },
-                              v2
-                            ]
-                          }
+                            "storageKey": null
+                          },
+                          v3
                         ]
                       },
                       {
                         "kind": "LinkedField",
                         "alias": null,
-                        "name": "boardingPass",
+                        "name": "arrival",
                         "storageKey": null,
                         "args": null,
-                        "concreteType": "BoardingPass",
+                        "concreteType": "RouteStop",
                         "plural": false,
                         "selections": [
-                          {
-                            "kind": "ScalarField",
-                            "alias": null,
-                            "name": "boardingPassUrl",
-                            "args": null,
-                            "storageKey": null
-                          }
+                          v3
                         ]
                       }
                     ]
diff --git a/app/MMB/src/scenes/tickets/__generated__/TicketSceneQuery.graphql.js b/app/MMB/src/scenes/tickets/__generated__/TicketSceneQuery.graphql.js
index f6d241fc..bf66e7b9 100644
--- a/app/MMB/src/scenes/tickets/__generated__/TicketSceneQuery.graphql.js
+++ b/app/MMB/src/scenes/tickets/__generated__/TicketSceneQuery.graphql.js
@@ -1,6 +1,6 @@
 /**
  * @flow
- * @relayHash e2efe741b01834490e4e4911aee4f51f
+ * @relayHash 80723ba743a71d7426069894c6580fec
  */
 
 /* eslint-disable */
@@ -54,20 +54,34 @@ fragment ETicket on BookingAssets {
 }
 
 fragment BoardingPassReturn on BookingReturn {
+  ...OutboundFlights
+}
+
+fragment OutboundFlights on BookingReturn {
   outbound {
     legs {
       id
-      departure {
-        airport {
-          city {
-            name
-          }
-          id
-        }
+      ...FlightFromTo
+    }
+  }
+}
+
+fragment FlightFromTo on Leg {
+  departure {
+    localTime
+    airport {
+      city {
+        name
       }
-      boardingPass {
-        boardingPassUrl
+      id
+    }
+  }
+  arrival {
+    airport {
+      city {
+        name
       }
+      id
     }
   }
 }
@@ -96,13 +110,43 @@ v2 = {
   "name": "id",
   "args": null,
   "storageKey": null
+},
+v3 = {
+  "kind": "LinkedField",
+  "alias": null,
+  "name": "airport",
+  "storageKey": null,
+  "args": null,
+  "concreteType": "Location",
+  "plural": false,
+  "selections": [
+    {
+      "kind": "LinkedField",
+      "alias": null,
+      "name": "city",
+      "storageKey": null,
+      "args": null,
+      "concreteType": "LocationArea",
+      "plural": false,
+      "selections": [
+        {
+          "kind": "ScalarField",
+          "alias": null,
+          "name": "name",
+          "args": null,
+          "storageKey": null
+        }
+      ]
+    },
+    v2
+  ]
 };
 return {
   "kind": "Request",
   "operationKind": "query",
   "name": "TicketSceneQuery",
   "id": null,
-  "text": "query TicketSceneQuery(\n  $bookingId: ID!\n) {\n  node(id: $bookingId) {\n    __typename\n    ... on BookingInterface {\n      ...TicketRefetch\n    }\n    id\n  }\n}\n\nfragment TicketRefetch on BookingInterface {\n  id\n  ...BoardingPasses\n  assets {\n    ...ETicket\n  }\n}\n\nfragment BoardingPasses on Node {\n  __typename\n  ... on BookingReturn {\n    ...BoardingPassReturn\n  }\n}\n\nfragment ETicket on BookingAssets {\n  ticketUrl\n}\n\nfragment BoardingPassReturn on BookingReturn {\n  outbound {\n    legs {\n      id\n      departure {\n        airport {\n          city {\n            name\n          }\n          id\n        }\n      }\n      boardingPass {\n        boardingPassUrl\n      }\n    }\n  }\n}\n",
+  "text": "query TicketSceneQuery(\n  $bookingId: ID!\n) {\n  node(id: $bookingId) {\n    __typename\n    ... on BookingInterface {\n      ...TicketRefetch\n    }\n    id\n  }\n}\n\nfragment TicketRefetch on BookingInterface {\n  id\n  ...BoardingPasses\n  assets {\n    ...ETicket\n  }\n}\n\nfragment BoardingPasses on Node {\n  __typename\n  ... on BookingReturn {\n    ...BoardingPassReturn\n  }\n}\n\nfragment ETicket on BookingAssets {\n  ticketUrl\n}\n\nfragment BoardingPassReturn on BookingReturn {\n  ...OutboundFlights\n}\n\nfragment OutboundFlights on BookingReturn {\n  outbound {\n    legs {\n      id\n      ...FlightFromTo\n    }\n  }\n}\n\nfragment FlightFromTo on Leg {\n  departure {\n    localTime\n    airport {\n      city {\n        name\n      }\n      id\n    }\n  }\n  arrival {\n    airport {\n      city {\n        name\n      }\n      id\n    }\n  }\n}\n",
   "metadata": {},
   "fragment": {
     "kind": "Fragment",
@@ -202,53 +246,25 @@ return {
                         "plural": false,
                         "selections": [
                           {
-                            "kind": "LinkedField",
+                            "kind": "ScalarField",
                             "alias": null,
-                            "name": "airport",
-                            "storageKey": null,
+                            "name": "localTime",
                             "args": null,
-                            "concreteType": "Location",
-                            "plural": false,
-                            "selections": [
-                              {
-                                "kind": "LinkedField",
-                                "alias": null,
-                                "name": "city",
-                                "storageKey": null,
-                                "args": null,
-                                "concreteType": "LocationArea",
-                                "plural": false,
-                                "selections": [
-                                  {
-                                    "kind": "ScalarField",
-                                    "alias": null,
-                                    "name": "name",
-                                    "args": null,
-                                    "storageKey": null
-                                  }
-                                ]
-                              },
-                              v2
-                            ]
-                          }
+                            "storageKey": null
+                          },
+                          v3
                         ]
                       },
                       {
                         "kind": "LinkedField",
                         "alias": null,
-                        "name": "boardingPass",
+                        "name": "arrival",
                         "storageKey": null,
                         "args": null,
-                        "concreteType": "BoardingPass",
+                        "concreteType": "RouteStop",
                         "plural": false,
                         "selections": [
-                          {
-                            "kind": "ScalarField",
-                            "alias": null,
-                            "name": "boardingPassUrl",
-                            "args": null,
-                            "storageKey": null
-                          }
+                          v3
                         ]
                       }
                     ]
diff --git a/app/MMB/src/scenes/tickets/boardingPasses/BoardingPassReturn.js b/app/MMB/src/scenes/tickets/boardingPasses/BoardingPassReturn.js
index 5c1df479..a5868e30 100644
--- a/app/MMB/src/scenes/tickets/boardingPasses/BoardingPassReturn.js
+++ b/app/MMB/src/scenes/tickets/boardingPasses/BoardingPassReturn.js
@@ -1,69 +1,27 @@
 // @flow strict
 
 import * as React from 'react';
-import { View } from 'react-native';
-import { TextIcon, StyleSheet, Color } from '@kiwicom/mobile-shared';
 import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
-import { Translation } from '@kiwicom/mobile-localization';
-import { SeparatorFullWidth } from '@kiwicom/mobile-navigation';
-import idx from 'idx';
 
+import OutboundFlights from './OutboundFlights';
 import type { BoardingPassReturn as BoardingPassReturnType } from './__generated__/BoardingPassReturn.graphql';
 
 type Props = {|
   +data: BoardingPassReturnType,
 |};
 
-export const BoardingPassReturn = (props: Props) => {
-  const outbound = idx(props.data, _ => _.outbound.legs) || [];
-  return (
-    <React.Fragment>
-      <View style={styles.row}>
-        <TextIcon code="&#xe079;" style={styles.outboundIcon} />
-        <Translation passThrough="departure" />
-      </View>
-      <SeparatorFullWidth />
-      {outbound.map(item => (
-        <Translation
-          passThrough={idx(item, _ => _.departure.airport.city.name)}
-          key={idx(item, _ => _.id)}
-        />
-      ))}
-    </React.Fragment>
-  );
-};
+export const BoardingPassReturn = (props: Props) => (
+  <React.Fragment>
+    <OutboundFlights data={props.data} />
+    {/* <InboundFlights />*/}
+  </React.Fragment>
+);
 
 export default createFragmentContainer(
   BoardingPassReturn,
   graphql`
     fragment BoardingPassReturn on BookingReturn {
-      outbound {
-        legs {
-          id
-          departure {
-            airport {
-              city {
-                name
-              }
-            }
-          }
-          boardingPass {
-            boardingPassUrl
-          }
-        }
-      }
+      ...OutboundFlights
     }
   `,
 );
-
-const styles = StyleSheet.create({
-  row: {
-    flexDirection: 'row',
-  },
-  outboundIcon: {
-    color: Color.brand,
-    transform: [{ rotate: '90deg' }],
-    marginEnd: 18,
-    fontSize: 18,
-  },
-});
diff --git a/app/MMB/src/scenes/tickets/boardingPasses/FlightFromTo.js b/app/MMB/src/scenes/tickets/boardingPasses/FlightFromTo.js
new file mode 100644
index 00000000..fac2fe62
--- /dev/null
+++ b/app/MMB/src/scenes/tickets/boardingPasses/FlightFromTo.js
@@ -0,0 +1,96 @@
+// @flow strict
+
+import * as React from 'react';
+import { View } from 'react-native';
+import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
+import { Translation, DateFormatter } from '@kiwicom/mobile-localization';
+import { TextIcon, StyleSheet, Color, Text } from '@kiwicom/mobile-shared';
+import idx from 'idx';
+
+import type { FlightFromTo as RouteStopType } from './__generated__/FlightFromTo.graphql';
+
+type Props = {|
+  +data: RouteStopType,
+|};
+
+const FlightFromTo = (props: Props) => {
+  const date = idx(props.data, _ => _.departure.localTime);
+  const shortDate = date
+    ? DateFormatter(new Date(date)).formatToShortDate()
+    : '';
+  const time = date ? DateFormatter(new Date(date)).formatToTime() : '';
+  return (
+    <View style={styles.row}>
+      <View style={styles.dateContainer}>
+        <Text style={styles.dateText}>
+          <Translation passThrough={shortDate} />
+        </Text>
+        <Text style={styles.dateText}>
+          <Translation passThrough={time} />
+        </Text>
+      </View>
+      <View style={[styles.row, styles.cityContainer]}>
+        <Text style={styles.cityText}>
+          <Translation
+            passThrough={idx(props.data, _ => _.departure.airport.city.name)}
+          />
+        </Text>
+        <TextIcon code="&#xe099;" style={styles.icon} />
+        <Text style={styles.cityText}>
+          <Translation
+            passThrough={idx(props.data, _ => _.arrival.airport.city.name)}
+          />
+        </Text>
+      </View>
+    </View>
+  );
+};
+export default createFragmentContainer(
+  FlightFromTo,
+  graphql`
+    fragment FlightFromTo on Leg {
+      departure {
+        localTime
+        airport {
+          city {
+            name
+          }
+        }
+      }
+      arrival {
+        airport {
+          city {
+            name
+          }
+        }
+      }
+    }
+  `,
+);
+
+const styles = StyleSheet.create({
+  row: {
+    flexDirection: 'row',
+  },
+  dateText: {
+    fontSize: 12,
+    fontWeight: '600',
+    color: Color.textLight,
+  },
+  dateContainer: {
+    marginEnd: 10,
+  },
+  cityContainer: {
+    alignSelf: 'flex-start',
+  },
+  icon: {
+    color: Color.textLight,
+    fontSize: 8,
+    alignSelf: 'center',
+    marginHorizontal: 8,
+  },
+  cityText: {
+    fontSize: 16,
+    fontWeight: '600',
+  },
+});
diff --git a/app/MMB/src/scenes/tickets/boardingPasses/OutboundFlights.js b/app/MMB/src/scenes/tickets/boardingPasses/OutboundFlights.js
new file mode 100644
index 00000000..f395f04f
--- /dev/null
+++ b/app/MMB/src/scenes/tickets/boardingPasses/OutboundFlights.js
@@ -0,0 +1,71 @@
+// @flow strict
+
+import * as React from 'react';
+import { View } from 'react-native';
+import { TextIcon, StyleSheet, Color, Text } from '@kiwicom/mobile-shared';
+import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
+import { Translation } from '@kiwicom/mobile-localization';
+import { SeparatorFullWidth } from '@kiwicom/mobile-navigation';
+import idx from 'idx';
+
+import FlightFromTo from './FlightFromTo';
+import type { OutboundFlights as OutboundFlightsType } from './__generated__/OutboundFlights.graphql';
+
+type Props = {|
+  +data: OutboundFlightsType,
+|};
+
+const OutboundFlights = (props: Props) => {
+  const outbound = idx(props.data, _ => _.outbound.legs) || [];
+  return (
+    <React.Fragment>
+      <View style={styles.row}>
+        <TextIcon code="&#xe079;" style={styles.outboundIcon} />
+        <Text style={styles.departureText}>
+          <Translation id="mmb.boarding_passes.outbound_flights.departure" />
+        </Text>
+      </View>
+      <View style={styles.separator}>
+        <SeparatorFullWidth />
+      </View>
+      {outbound.map(item => (
+        <FlightFromTo data={item} key={idx(item, _ => _.id)} />
+      ))}
+    </React.Fragment>
+  );
+};
+
+export default createFragmentContainer(
+  OutboundFlights,
+  graphql`
+    fragment OutboundFlights on BookingReturn {
+      outbound {
+        legs {
+          id
+          ...FlightFromTo
+        }
+      }
+    }
+  `,
+);
+
+const styles = StyleSheet.create({
+  row: {
+    flexDirection: 'row',
+  },
+  separator: {
+    marginBottom: 20,
+    marginTop: 9,
+  },
+  departureText: {
+    color: Color.textLight,
+    fontSize: 12,
+    alignSelf: 'center',
+  },
+  outboundIcon: {
+    color: Color.brand,
+    transform: [{ rotate: '90deg' }],
+    marginEnd: 18,
+    fontSize: 18,
+  },
+});
diff --git a/app/MMB/src/scenes/tickets/boardingPasses/__generated__/BoardingPassReturn.graphql.js b/app/MMB/src/scenes/tickets/boardingPasses/__generated__/BoardingPassReturn.graphql.js
index b14b184a..54175b52 100644
--- a/app/MMB/src/scenes/tickets/boardingPasses/__generated__/BoardingPassReturn.graphql.js
+++ b/app/MMB/src/scenes/tickets/boardingPasses/__generated__/BoardingPassReturn.graphql.js
@@ -8,24 +8,11 @@
 
 /*::
 import type { ConcreteFragment } from 'relay-runtime';
+type OutboundFlights$ref = any;
 import type { FragmentReference } from "relay-runtime";
 declare export opaque type BoardingPassReturn$ref: FragmentReference;
 export type BoardingPassReturn = {|
-  +outbound: ?{|
-    +legs: ?$ReadOnlyArray<?{|
-      +id: string,
-      +departure: ?{|
-        +airport: ?{|
-          +city: ?{|
-            +name: ?string
-          |}
-        |}
-      |},
-      +boardingPass: ?{|
-        +boardingPassUrl: ?string
-      |},
-    |}>
-  |},
+  +$fragmentRefs: OutboundFlights$ref,
   +$refType: BoardingPassReturn$ref,
 |};
 */
@@ -39,94 +26,12 @@ const node/*: ConcreteFragment*/ = {
   "argumentDefinitions": [],
   "selections": [
     {
-      "kind": "LinkedField",
-      "alias": null,
-      "name": "outbound",
-      "storageKey": null,
-      "args": null,
-      "concreteType": "Trip",
-      "plural": false,
-      "selections": [
-        {
-          "kind": "LinkedField",
-          "alias": null,
-          "name": "legs",
-          "storageKey": null,
-          "args": null,
-          "concreteType": "Leg",
-          "plural": true,
-          "selections": [
-            {
-              "kind": "ScalarField",
-              "alias": null,
-              "name": "id",
-              "args": null,
-              "storageKey": null
-            },
-            {
-              "kind": "LinkedField",
-              "alias": null,
-              "name": "departure",
-              "storageKey": null,
-              "args": null,
-              "concreteType": "RouteStop",
-              "plural": false,
-              "selections": [
-                {
-                  "kind": "LinkedField",
-                  "alias": null,
-                  "name": "airport",
-                  "storageKey": null,
-                  "args": null,
-                  "concreteType": "Location",
-                  "plural": false,
-                  "selections": [
-                    {
-                      "kind": "LinkedField",
-                      "alias": null,
-                      "name": "city",
-                      "storageKey": null,
-                      "args": null,
-                      "concreteType": "LocationArea",
-                      "plural": false,
-                      "selections": [
-                        {
-                          "kind": "ScalarField",
-                          "alias": null,
-                          "name": "name",
-                          "args": null,
-                          "storageKey": null
-                        }
-                      ]
-                    }
-                  ]
-                }
-              ]
-            },
-            {
-              "kind": "LinkedField",
-              "alias": null,
-              "name": "boardingPass",
-              "storageKey": null,
-              "args": null,
-              "concreteType": "BoardingPass",
-              "plural": false,
-              "selections": [
-                {
-                  "kind": "ScalarField",
-                  "alias": null,
-                  "name": "boardingPassUrl",
-                  "args": null,
-                  "storageKey": null
-                }
-              ]
-            }
-          ]
-        }
-      ]
+      "kind": "FragmentSpread",
+      "name": "OutboundFlights",
+      "args": null
     }
   ]
 };
 // prettier-ignore
-(node/*: any*/).hash = '38dc6391e6fda38ac84b24b9da43296f';
+(node/*: any*/).hash = '6db725bea412141076147b589d9d82d1';
 module.exports = node;
diff --git a/app/MMB/src/scenes/tickets/boardingPasses/__generated__/FlightFromTo.graphql.js b/app/MMB/src/scenes/tickets/boardingPasses/__generated__/FlightFromTo.graphql.js
new file mode 100644
index 00000000..964e500b
--- /dev/null
+++ b/app/MMB/src/scenes/tickets/boardingPasses/__generated__/FlightFromTo.graphql.js
@@ -0,0 +1,107 @@
+/**
+ * @flow
+ */
+
+/* eslint-disable */
+
+'use strict';
+
+/*::
+import type { ConcreteFragment } from 'relay-runtime';
+import type { FragmentReference } from "relay-runtime";
+declare export opaque type FlightFromTo$ref: FragmentReference;
+export type FlightFromTo = {|
+  +departure: ?{|
+    +localTime: ?any,
+    +airport: ?{|
+      +city: ?{|
+        +name: ?string
+      |}
+    |},
+  |},
+  +arrival: ?{|
+    +airport: ?{|
+      +city: ?{|
+        +name: ?string
+      |}
+    |}
+  |},
+  +$refType: FlightFromTo$ref,
+|};
+*/
+
+
+const node/*: ConcreteFragment*/ = (function(){
+var v0 = {
+  "kind": "LinkedField",
+  "alias": null,
+  "name": "airport",
+  "storageKey": null,
+  "args": null,
+  "concreteType": "Location",
+  "plural": false,
+  "selections": [
+    {
+      "kind": "LinkedField",
+      "alias": null,
+      "name": "city",
+      "storageKey": null,
+      "args": null,
+      "concreteType": "LocationArea",
+      "plural": false,
+      "selections": [
+        {
+          "kind": "ScalarField",
+          "alias": null,
+          "name": "name",
+          "args": null,
+          "storageKey": null
+        }
+      ]
+    }
+  ]
+};
+return {
+  "kind": "Fragment",
+  "name": "FlightFromTo",
+  "type": "Leg",
+  "metadata": null,
+  "argumentDefinitions": [],
+  "selections": [
+    {
+      "kind": "LinkedField",
+      "alias": null,
+      "name": "departure",
+      "storageKey": null,
+      "args": null,
+      "concreteType": "RouteStop",
+      "plural": false,
+      "selections": [
+        {
+          "kind": "ScalarField",
+          "alias": null,
+          "name": "localTime",
+          "args": null,
+          "storageKey": null
+        },
+        v0
+      ]
+    },
+    {
+      "kind": "LinkedField",
+      "alias": null,
+      "name": "arrival",
+      "storageKey": null,
+      "args": null,
+      "concreteType": "RouteStop",
+      "plural": false,
+      "selections": [
+        v0
+      ]
+    }
+  ]
+};
+})();
+// prettier-ignore
+(node/*: any*/).hash = 'b9c0c09e147be2363082ac0c9cbc77e9';
+module.exports = node;
diff --git a/app/MMB/src/scenes/tickets/boardingPasses/__generated__/OutboundFlights.graphql.js b/app/MMB/src/scenes/tickets/boardingPasses/__generated__/OutboundFlights.graphql.js
new file mode 100644
index 00000000..e2adf04d
--- /dev/null
+++ b/app/MMB/src/scenes/tickets/boardingPasses/__generated__/OutboundFlights.graphql.js
@@ -0,0 +1,71 @@
+/**
+ * @flow
+ */
+
+/* eslint-disable */
+
+'use strict';
+
+/*::
+import type { ConcreteFragment } from 'relay-runtime';
+type FlightFromTo$ref = any;
+import type { FragmentReference } from "relay-runtime";
+declare export opaque type OutboundFlights$ref: FragmentReference;
+export type OutboundFlights = {|
+  +outbound: ?{|
+    +legs: ?$ReadOnlyArray<?{|
+      +id: string,
+      +$fragmentRefs: FlightFromTo$ref,
+    |}>
+  |},
+  +$refType: OutboundFlights$ref,
+|};
+*/
+
+
+const node/*: ConcreteFragment*/ = {
+  "kind": "Fragment",
+  "name": "OutboundFlights",
+  "type": "BookingReturn",
+  "metadata": null,
+  "argumentDefinitions": [],
+  "selections": [
+    {
+      "kind": "LinkedField",
+      "alias": null,
+      "name": "outbound",
+      "storageKey": null,
+      "args": null,
+      "concreteType": "Trip",
+      "plural": false,
+      "selections": [
+        {
+          "kind": "LinkedField",
+          "alias": null,
+          "name": "legs",
+          "storageKey": null,
+          "args": null,
+          "concreteType": "Leg",
+          "plural": true,
+          "selections": [
+            {
+              "kind": "ScalarField",
+              "alias": null,
+              "name": "id",
+              "args": null,
+              "storageKey": null
+            },
+            {
+              "kind": "FragmentSpread",
+              "name": "FlightFromTo",
+              "args": null
+            }
+          ]
+        }
+      ]
+    }
+  ]
+};
+// prettier-ignore
+(node/*: any*/).hash = '40e147f599679e03859f19829161fa65';
+module.exports = node;
diff --git a/packages/localization/src/DateFormatter.js b/packages/localization/src/DateFormatter.js
index 6844e666..972c3cf3 100644
--- a/packages/localization/src/DateFormatter.js
+++ b/packages/localization/src/DateFormatter.js
@@ -18,6 +18,14 @@ function date(date: Date) {
   }).format(date);
 }
 
+function shortDate(date: Date) {
+  return Intl.DateTimeFormat(DEVICE_LOCALE, {
+    timeZone: 'UTC', // this is very important!
+    month: 'numeric',
+    day: 'numeric',
+  }).format(date);
+}
+
 function time(date: Date) {
   return Intl.DateTimeFormat(DEVICE_LOCALE, {
     timeZone: 'UTC', // this is very important!
@@ -51,6 +59,7 @@ function DateFormatter(rawDate: Date = DateUtils.getUTCNow()) {
   return {
     formatToDate: () => date(rawDate),
     formatToTime: () => time(rawDate),
+    formatToShortDate: () => shortDate(rawDate),
 
     // note: I am not sure about the naming - improve when needed
     formatToBirthday: () => birthday(rawDate),
diff --git a/packages/localization/src/vocabularies/ManageMyBooking.js b/packages/localization/src/vocabularies/ManageMyBooking.js
index 65de238f..8cafe690 100644
--- a/packages/localization/src/vocabularies/ManageMyBooking.js
+++ b/packages/localization/src/vocabularies/ManageMyBooking.js
@@ -28,6 +28,7 @@ export default {
 
   // MMB Boarding passes
   'mmb.boarding_passes.boarding_pass': 'Boarding Pass',
+  'mmb.boarding_passes.outbound_flights.departure': 'Departure',
 
   // MMB Flight overview
   'mmb.flight_overview.title': 'Flight Overview',


Test patch:
diff --git a/packages/localization/src/__tests__/DateFormatter.test.js b/packages/localization/src/__tests__/DateFormatter.test.js
index 9f5ac4a7..2d0d0654 100644
--- a/packages/localization/src/__tests__/DateFormatter.test.js
+++ b/packages/localization/src/__tests__/DateFormatter.test.js
@@ -46,3 +46,12 @@ it('always returns UTC', () => {
     DateFormatter(new Date('2018-12-24T00:00:00+02:00')).formatToTime(),
   ).toBe('10:00 PM');
 });
+
+it('formats shortDate correctly', () => {
+  expect(DateFormatter(new Date('2018-12-24')).formatToShortDate()).toBe(
+    '12/24',
+  );
+  expect(
+    DateFormatter(new Date('2018-12-24T00:00:00Z')).formatToShortDate(),
+  ).toBe('12/24');
+});