Skip to content

reveza/BusbudCodingChallenge

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

coding-challenge-frontend-b

osheaga

It will be hot this summer in Montreal with the Osheaga festival! Your challenge is to build a microsite that allows a traveler from NYC to find one-way departure schedules for the festival's opening weekend.

Functional Requirements

  • Has a simple onboarding screen that will trigger the departure search
  • Lists all the departures for a given origin city (New York - geohash: dr5reg) and a given destination city (Montréal - geohash: f25dvk) for a given day (the 29th of July 2016) for 1 adult.
  • For each departure, we want, at least, to see the departure time, the arrival time, the location name and the price (use prices.total of the departure).

Non-functional requirements

  • The code should be hosted on github, and the repo should be shared with Busbud and submitted as a pull request
  • The microsite should be deployed to Heroku.

Bonus

  • Localization: support for multiple languages (English, French, ...)
  • Responsive design

Remarks

  • You can setup your microsite any way you like; we're partial to NodeJS, ExpressJS and React
  • CSS can be written using SASS, LESS or similar higher-level language
  • All API requests need a special Accept HTTP Header, as described below

Supporting API

For all these requests, you MUST change the Accept header to:

application/vnd.busbud+json; version=2; profile=https://schema.busbud.com/v2/

Search is performed in two steps

  1. A search is initialized, and may be complete if results are served from cache
  2. An initialized and incomplete search is polled until complete

Initialize search

To get departures, search is initialized via the following endpoint:

https://napi.busbud.com/x-departures/:origin/:destination/:outbound_date

Path parameters:

  • origin : Origin's geohash
  • destination : Destination's geohash
  • outbound_date : ISO 8601 Outbound departure date

Querystring parameters:

  • adult : Number of adults
  • child : Number of children
  • senior : Number of seniors
  • lang : ISO 3166-1 alpha-2 language code
  • currency : ISO 4217 currency code

The response looks like:

{
  "origin_city_id": "375dd5879001acbd84a4683dedf9eed1",
  "destination_city_id": "375dd5879001acbd84a4683ded9c875b",
  "cities": [
    { City },
    { City }
  ],
  "locations": [
    { Location }
    { Location }
  ],
  "operators": [
    { Operator },
    { Operator }
  ],
  "departures": [
    { XDeparture },
    { XDeparture }
  ],
  "complete": false,
  "ttl": 900,
  "is_valid_route": true
}

Where a City is like:

   {
      "id": "375dd5879001acbd84a4683deda84183",
      "locale": "en",
      "region_id": 6417,
      "name": "New York",
      "lat": 40.71427,
      "lon": -74.00597,
      "geohash": "dr5reg",
      "timezone": "America/New_York",
      "image_url": "/images/promos/city-blocks/new-york.jpg",
      "legacy_url_form": "NewYork,NewYork,UnitedStates",
      "full_name": "New York, New York, United States",
      "region": {
        "id": 6417,
        "locale": "en",
        "country_code2": "US",
        "name": "New York",
        "country": {
          "code2": "US",
          "locale": "en",
          "code3": "USA",
          "name": "United States",
          "continent": "NA",
          "default_locale": "en",
          "default_currency": "USD",
          "population": 310232863
        }
      }
    }

Where a Location is like:

    {
      "id": 3970,
      "city_id": "375dd5879001acbd84a4683dedfb933e",
      "name": "Métro Bonaventure Bus Station",
      "address": [
        "997 Rue St-Antoine Ouest",
        "Montreal, QC H3C 1A6"
      ],
      "type": "transit_station",
      "lat": 45.4988273060484,
      "lon": -73.5644745826722,
      "geohash": "f25dvfzcz"
    }

Where an Operator is like:

    {
      "id": "bfc27cd544ca49c18d000f2bc00c58c0",
      "source_id": 155,
      "profile_id": 111,
      "name": "Greyhound",
      "url": null,
      "logo_url": "https://busbud-pubweb-assets-staging.global.ssl.fastly.net/images-service/operator-logos/greyhound.png?hash=1{&height,width}",
      "display_name": "Greyhound",
      "sellable": true,
      "fuzzy_prices": false,
      "sell_tickets_cutoff": {
        "hours": 1
      },
      "amenities": {
        "classes": {
          "Normal": {
            "display_name": "Economy",
            "wifi": true,
            "toilet": true,
            "ac": true,
            "food": false,
            "refreshment": false,
            "power_outlets": true,
            "tv": false,
            "bus_attendant": false,
            "leg_room": false
          },
          "Economy": {
            "display_name": "Economy",
            "wifi": true,
            "toilet": true,
            "ac": true,
            "food": false,
            "refreshment": false,
            "power_outlets": true,
            "tv": false,
            "bus_attendant": false,
            "leg_room": false
          }
        }
      },
      "source": "greyhound_us",
      "referral_deal": false,
      "display_url": null,
      "fraud_check": "iovation",
      "terms": {
        "refund": false,
        "exchange": true,
        "bag_allowed": true,
        "piece_of_id": false,
        "boarding_requirement": "printed_tkt",
        "extra_bag_policy": true,
        "use_new_ticket": false,
        "exchange_cutoff": 24,
        "nb_checked_bags": 1,
        "kg_by_bag": 25,
        "nb_carry_on": 1,
        "extra_bag_cost": 1500
      }
    }

And an XDeparture is :

    {
      "id": "7c5dd26a",
      "source_id": 155,
      "checkout_type": "new",
      "operator_id": "bfc27cd544ca49c18d000f2bc00c58c0",
      "origin_location_id": 1942,
      "destination_location_id": 1938,
      "class": "Economy",
      "class_name": "Economy",
      "amenities": {
        "display_name": "Economy",
        "wifi": true,
        "toilet": true,
        "ac": true,
        "food": false,
        "refreshment": false,
        "power_outlets": true,
        "tv": false,
        "bus_attendant": false,
        "leg_room": false
      },
      "available_seats": 55,
      "prices": {
        "total": 5200,
        "breakdown": {
          "base": 5200
        },
        "categories": {},
        "discounted": false
      },
      "ticket_types": [
        "print"
      ],
      "departure_timezone": "America/New_York",
      "arrival_timezone": "America/Montreal",
      "departure_time": "2016-01-14T00:01:00",
      "arrival_time": "2016-01-14T07:55:00"
    }

Poll search

While the complete property from the response is false, you need to call:

https://napi.busbud.com/x-departures/:origin/:destination/:outbound_date/poll

with all the same parameters as the previous endpoint, plus the following additional querystring parameter:

  • index : Index from which to return new departures

The response is similar to:

{
  "departures": [
    { XDeparture },
    { XDeparture }
  ],
  "operators": [
    { Operator },
    { Operator }
  ],
  "complete": true,
  "ttl": 900
}

About

A microsite that lists bus travel schedules for a given route and a given date

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • HTML 51.3%
  • JavaScript 41.9%
  • CSS 6.8%