Skip to content
91 changes: 13 additions & 78 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,92 +1,27 @@
# BackTREK

## Introduction

For this project we'll be returning to the TREK API, using Backbone to build an application that can handle data in complex ways.

This is an individual, [stage 2](https://github.com/Ada-Developers-Academy/pedagogy/blob/master/rule-of-three.md#stage-2) project.
For this project I used the TREK API, using Backbone to build an application that can handle data in complex ways.

We'll be reusing the [TREK travel API](https://ada-backtrek-api.herokuapp.com/trips), [documented here](https://github.com/AdaGold/trip_api). The core purpose of the website will be the same, but we'll use Backbone to better organize our code and to provide all sorts of extra functionality.

**NOTE THAT THE URL FOR THE TREK API HAS CHANGED** It is now at https://ada-backtrek-api.herokuapp.com, though all the endpoints are the same.

With this application, you can add trips, view trips, and reserve trips. It also has the functionality to let you filter trips by price, name, continent, category, duration and id.

## Setup
1. Clone the repository
2. Install depenencies in your repository
```
yarn install
```
3. Serve front end with Webpack
```
yarn start
```
## Learning Goals

- Generate HTML using Underscore templates
- Use Backbone and jQuery to work with a complex API
- Manage application data using Backbone models and collections
- Build an attractive, robust, and feature-rich user interface

## General Requirements

The code you write should obey the following rules:

- Use Backbone's event workflow. Code that responds to DOM events should be separate from code that updates the DOM.
- Any dynamic elements on the page shall be rendered using Underscore templates
- Any errors encountered while interacting with the API shall be politely reported to the user

This project has 3 waves, arranged more-or-less in order of difficulty. It's worthwhile to read through all three before you start, and come up with a plan for how to organize your code. However, make sure to pace yourself, and only try to solve one problem at a time.

## Wave 1: Displaying Data

In wave 1, you'll use our new functionality (Underscore templates, Backbone models and collections) to achieve feature parity with the original TREK project.

- A user can click a link to see a list of trips
- A user can click on a trip to see details of that trip

## Wave 2: Creating Data

In wave 2, your focus should be on sending data to the server and handling the response.

- A user can create a new trip
- A user can reserve a spot on a trip
- Question: is Backbone API integration useful here? How would this work? What other options are there?

Pay careful attention to error handling! The TREK API now includes server-side validation - what happens when these fail? How will you let the user know what happened?

Your app should also include client-side validation, to preemptively catch as many errors as possible and give the user quick feedback. Feel free to inspect the server-side validation code for [reservations](https://github.com/AdaGold/trip_api/blob/master/app/models/trip.rb) and [new trips](https://github.com/AdaGold/trip_api/blob/master/app/models/trip_reservation.rb), if it will help you.

## Wave 3: Organizing Data

### Sorting

Users should be able to sort the list of trips by:

- Name
- Category
- Continent
- Weeks
- Cost

The user should be given some sort of visual feedback that the data has been sorted, even if the order didn't change.

### Filtering

Add a form to the top of your trip list. The form should have a dropdown to select `Name`, `Category`, `Continent`, `Cost` or `Weeks`, as well as a text box.

When the user types in the text box, the list of trips will be filtered to only show trips that match.
- For a text field (`Name`, `Category`, `Continent`), the trip's value for that field should _include_ the filter value.
- Filtering for `Continent` `asia` should match both `Asia` and `Australasia`
- For a numeric field (`Weeks`, `Cost`), the trip's value for that field should be _less than or equal to_ the filter value.

The list of displayed trips should be updated with every keystroke. This means that making a new query against the API every time will be too slow. Instead, you should filter your list in JavaScript, probably via a custom method on the collection.

Your app should gracefully handle the case where none of the trips match the filter.

This feature is complex - it's what brings this project from stage 1 to stage 2. Spend some time thinking it through before you start writing code. What data needs to be where, how will code be organized, and how are you going to avoid stepping on your own feet?

## Optional Wireframes

These wireframes are optional. Some of the content matches closely with what we've done before, but some (such as getting validation failures to appear inline) is quite challenging!

For an extra challenge, if user input is blocked by client-side validations, have the errors resolve themselves as the user types.

#### Normal View

![Normal View](images/wireframe.jpg)

#### Add-Trip Modal

Foundation includes modal functionality, but it can be tricky to get it to work right. Instead, [roll your own](https://www.w3schools.com/howto/howto_css_modals.asp)!

![Add Trip Modal](images/wireframe-modal.png)
225 changes: 223 additions & 2 deletions dist/index.html
Original file line number Diff line number Diff line change
@@ -1,20 +1,241 @@
<!DOCTYPE html>


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My JavaScript App</title>
<title>My Trek Transporter</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/css/foundation-float.css" > -->

<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
</head>
<body>
<header>
<nav class="top-bar" data-topbar role="navigation">

<h1><a href="#">Trek Transporter</a></h1>

<section class="top-bar-section">

<button class='button' id='view-all-trips'>View All Trips</button>
<button class='button' id= 'add-trip'>Add a Trip</button>
<div class="dropdown">
<button class="continent-dropbtn button">Continents</button>
<div id="continent-dropdown" class="dropdown-content ">
<option value='North America'>North America</option>
<option value='South America'>South America</option>
<option value='Asia'>Asia</option>
<option value='Europe'>Europe</option>
<option value='Australia'>Australia</option>
<option value='Africa'>Africa</option>
<option value='Australasia'>Australasia</option>
</div>
</div>
<div class="dropdown">
<button class="cost-dropbtn button">Maximum Cost</button>
<div id="cost-dropdown" class="dropdown-content">
<option value="50">$50</option>
<option value="100">$100</option>
<option value="1000">$1000</option>
<option value="5000">$5000</option>
<option value="10000">$10000</option>
<option value="1000000000">$1,000,000,000</option>
</div>
</div>
</section>
</nav>
</header>

<main>

<!-- The Modal -->
<div id="myModal" class="modal hidden">

<!-- Modal content -->
<div class="modal-content">
<span class="close">&times;</span>
<p class='display-status'></p>
</div>

</div>


<aside class="side-bar columns large-4 small-12">
<div id="trip-details">

</div>
<div id="hidden-form">

</div>
</aside>
<div class="columns large-8 small-12">


<section id="trip-table" class="hidden">


<table class = "all-trips">
<thead>
<h2>Trips</h2>
<th class="sort name">Title</th>
<th class="sort continent">Continent</th>
<th class="sort category">Category</th>
<th class="sort weeks">Weeks</th>
<th class="sort id">ID</th>

</thead>
<tbody id="trips-list">
</tbody>
</table>

</section>
<section id="continent-table" class="hidden">


<table class = "continent-trips">
<thead>
<h2 id='api-query'></h2>
<th class="sort name">Title</th>
<th class="sort continent">Continent</th>
<th class="sort weeks">Weeks</th>
<th class="sort id">ID</th>

</thead>
<tbody id="continent-list">
</tbody>
</table>
<!-- "id":7,"name":"Sziget Festival Experience","continent":"Europe","weeks":1 -->
</section>
</div>
</main>
<footer>

</footer>
<script src="app.bundle.js" type="text/javascript"></script>

<script type="text/template" id="trips-template">
<tr class="trip" id = "<%- id %>">
<td>
<%- name %>
</td>

<td>
<%- continent %>
</td>
<td>
<%- category %>
</td>
<td>
<%- weeks %>
</td>
<td>
<%- id %>
</td>
<div id="trip-show">

</div>
</tr>
</script>

<script type="text/template" id="continent-template">
<tr class="trip" id = "<%- id %>">
<td>
<%- name %>
</td>

<td>
<%- continent %>
</td>
<td>
<%- weeks %>
</td>
<td>
<%- id %>
</td>
<div id="trip-show">

</div>
</tr>
</script>

<script type="text/template" id="trips-description-template">
<div class="trip-description">

<article>
<h2><%- name %></h2>
<ul class="list-upper-alpha" id = "<%- id %>" >
<li><em>Cost:</em> <%- cost %></li>
<li><em>Continent:</em> <%- continent %></li>
<li><em>Duration (weeks):</em> <%- weeks %></li>
<li><em>Id:</em> <%- id %></li>
</ul>
<p>
<%- about %>
</br>
<button name="button" class="button reserve" id = "reserve-button">Reserve</button>

</p>
</article>

</div>

</script>

<script type="text/template" id="reserve-trip-form-template">
<h2>Reserve a Trip</h2>
<form id="add-reservation-form">
<label for="name">Name</label>
<input type="text" name="name"></input>

<label for="email"><em>email</em></label>
<input type="text" name="email"></input>

<label for="age"><em>Age</em></label>
<input type="number" name="age"></input>

<input type="submit" value="Reserve Now" class="button" id="submit-reservation"></input>
</form>
</script>


<script type="text/template" id="add-trip-form-template">
<h2>Add a Trip</h2>
<form id="add-trip-form">
<label for="name">Title</label>
<input type="text" name="name"></input>

<label for="continent"><em>Continent</em></label>
<!-- <input type="text" name="continent"></input> -->
<select name="continent">
<option value="Europe">Europe</option>
<option value="Asia">Asia</option>
<option value="Australia">Australia</option>
<option value="Australasia">Australasia</option>
<option value="Africa">Africa</option>
<option value="South America">South America</option>
<option value="North America">North America</option>
</select>

<label for="category"><em>Category</em></label>
<input type="text" name="category"></input>

<label for="weeks"><em>Duration</em>(weeks)</label>
<input type="number" name="weeks"></input>

<label for="about"><em>Description</em></label>
<input type="text" name="about"></input>

<label for="cost"><em>Price</em>(usd)</label>
<input type="number" step="0.01" name="cost"></input>

<input type="submit" value="Add Trip" class="button" id="submit-reservation"></input>
</form>
</script>


<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script>

<script src="app.bundle.js" type="text/javascript"></script>
</body>
</html>
Loading