diff --git a/README.md b/README.md
index 1d4b408..7f540b1 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,22 @@
# 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
@@ -17,76 +24,4 @@ We'll be reusing the [TREK travel API](https://ada-backtrek-api.herokuapp.com/tr
- 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
-
-
-
-#### 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)!
-
diff --git a/dist/index.html b/dist/index.html
index b873b1e..b3efe0c 100644
--- a/dist/index.html
+++ b/dist/index.html
@@ -1,20 +1,241 @@
+
+
+
- My JavaScript App
+ My Trek Transporter
+
+
+
+
+
+
+
+
+
+
+ ×
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Trips
+
Title
+
Continent
+
Category
+
Weeks
+
ID
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Title
+
Continent
+
Weeks
+
ID
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app.js b/src/app.js
index e7af594..5b96393 100644
--- a/src/app.js
+++ b/src/app.js
@@ -6,8 +6,343 @@ import _ from 'underscore';
import './css/foundation.css';
import './css/style.css';
+import TripList from './app/collections/trip_list';
+import Trip from './app/models/trip';
+import Reservation from './app/models/reservation';
+// import ContinentQuery from '.app/models/continent_query';
+
console.log('it loaded!');
+let tripsTemplate;
+let continentTemplate
+let tripDescriptionTemplate;
+let reserveFormTemplate;
+let tripFormTemplate;
+
+
+const tripList = new TripList();
+
+// Get the modal
+const modal = document.getElementById('myModal');
+
+// Get the button that opens the modal
+const btn = document.getElementById("myBtn");
+
+// Get the element that closes the modal
+const span = document.getElementsByClassName("close")[0];
+
+
+
+
+// When the user clicks on (x), close the modal
+span.onclick = function() {
+ modalHide();
+}
+const modalDisplay = function modalDisplay(){
+ $('.modal').addClass('show');
+ $('.modal').removeClass('hidden');
+ console.log('changed modal display to block')
+};
+
+const modalHide = function modalHide(){
+ $('.modal').addClass('hidden');
+ $('.modal').removeClass('show');
+ console.log('changed modal display to hidden')
+};
+
+// $('.display-status').on('change', modalDisplay);
+
+
+// When the user clicks anywhere outside of the modal, close it
+window.onclick = function(event) {
+ if (event.target == modal) {
+ modalHide()
+ }
+}
+const queryContinent = function queryContinent(event){
+ event.preventDefault();
+
+}
+
+const saveReservation = function saveReservation(event){
+ event.preventDefault();
+ console.log('saveReservation function');
+ let tripNumberID = $('.list-upper-alpha').attr('id');
+ let reservationObject = readFormData(reservationForm);
+
+ let newReservation = new Reservation(reservationObject);
+ newReservation.save({trip_id: tripNumberID}, {
+ success: (model, response) => {
+ const reservationSuccess = 'Successfully added reservation!'
+ console.log(reservationSuccess);
+ $('.display-status').html('')
+ $('.display-status').html(response + reservationSuccess);
+ modalDisplay();
+ },
+ error: (model, response) => {
+ const reservationFailure = 'Failed to save reservation! Server response:';
+ console.log(reservationFailure);
+ console.log(response);
+ $('.display-status').html('')
+ $('.display-status').html(reservationFailure + response);
+ modalDisplay();
+ // handleValidationFailures(response.responseJSON["errors"]);
+ },
+ });
+}
+
+const displayError = function displayError(errorHash){
+
+}
+const saveTrip = function saveTrip(event){
+ event.preventDefault();
+
+ let newTripObject = readFormData(addTripForm);
+ // reservationObject['id'] = reservationID
+
+ console.log(newTripObject);
+ let newTrip = new Trip(newTripObject);
+ console.log('bologna');
+ console.log(newTrip);
+ console.log(`this is ${this}`);
+ if(!newTrip.isValid()){
+ $('.display-status').html('')
+ $('.display-status').html(`${newTrip.validationError}`);
+ modalDisplay();
+ }
+ newTrip.save( {}, {
+ success: (model, response) => {
+ const tripSuccess = 'Successfully added Trip!';
+ console.log(tripSuccess);
+ $('.display-status').html('')
+ console.log(response);
+ $('.display-status').html(tripSuccess);
+ $('#add-trip-form').remove();
+ modalDisplay();
+ // reportStatus('success', 'Successfully added reservation!');
+ },
+ error: (model, response) => {
+ const tripFailure = 'Failed to save trip! Server response:';
+ console.log(`validationError ${response.attributes['validationError']}`);
+ $('.display-status').html('')
+ console.log(response);
+ $('.display-status').html(tripFailure);
+ modalDisplay();
+ },
+ });
+}
+const reservationForm = {
+ fields: ['name', 'age', 'email'],
+ formId: 'add-reservation-form',
+};
+
+// add some more stuff to this form data
+const addTripForm = {
+ fields: ['name', 'continent', 'weeks', 'category', 'about', 'cost'],
+ formId: 'add-trip-form',
+};
+
+const readFormData = function readFormData(formType) {
+ const formData = {};
+ (formType.fields).forEach((field) => {
+ // select the input corresponding to the field we want
+ let jQueryString = "#" + `${formType.formId} [name="${ field }"]`;
+ const inputElement = $(jQueryString);
+ const value = inputElement.val();
+ console.log(`value is ${value}`);
+
+
+ // Don't take empty strings, so that Backbone can
+ // fill in default values
+ if (value != ''){
+ formData[field] = value;
+ }
+
+ inputElement.val('');
+ });
+
+ console.log(formData);
+
+ return formData;
+};
+const formDivElement = $('#hidden-form');
+
+const renderTripForm = function rendertripForm() {
+
+ formDivElement.html('');
+
+ console.log(' about to fetch form')
+
+
+ const tripFormHTML = $(tripFormTemplate());
+ console.log(`this is tripformhtml ${tripFormHTML}`)
+ $("#reserve-button").remove();
+ formDivElement.append(tripFormHTML);
+ $('#add-trip-form').on('submit', saveTrip);
+};
+
+const renderReserveForm = function renderReserveForm() {
+
+ formDivElement.html('');
+
+ console.log(' about to fetch form')
+
+
+ const reserveFormHTML = $(reserveFormTemplate());
+ console.log(`this is reserveformhtml ${reserveFormHTML}`)
+ $("#reserve-button").remove();
+ formDivElement.append(reserveFormHTML);
+ $('#add-reservation-form').on('submit', saveReservation);
+
+};
+
+const renderTrips = function renderTrips(tripList) {
+ // let oneTrip = (tripList.first());
+ // let size = 0, key;
+ // for (key in oneTrip) {
+ // if (oneTrip.hasOwnProperty(key)) size++;
+ // }
+ //
+ // console.log(size);
+ // console.log('trip length');
+ // console.log('triplist length');
+ const tripTableElement = $('#trips-list');
+ const continentTableElement = $('#continent-list');
+ tripTableElement.html('');
+ continentTableElement.html('');
+ tripList.forEach((trip) => {
+ if($('#trip-table').hasClass('show')){
+ const generatedHTML = $(tripsTemplate(trip.attributes));
+ tripTableElement.append(generatedHTML);
+ generatedHTML.on('click', (event) =>{
+ renderTripDetails(trip);
+ })
+ } else{
+ const generatedContinentHTML = $(continentTemplate(trip.attributes));
+ continentTableElement.append(generatedContinentHTML);
+ generatedContinentHTML.on('click', (event) =>{
+ renderTripDetails(trip);
+ })
+ };
+ });
+
+ // Provide visual feedback for sorting
+ $('th.sort').removeClass('current-sort-field');
+ // $(`th.sort.${ tripList.comparator }`).addClass('current-sort-field');
+};
+
+
+const renderTripDetails = function renderTripDetails(trip) {
+
+ const tripDivElement = $('#trip-details');
+ formDivElement.html('');
+ tripDivElement.html('');
+ trip.fetch({
+ success: (model) => {
+ const detailsHTML = $(tripDescriptionTemplate(trip.attributes));
+ tripDivElement.append(detailsHTML);
+ $('#reserve-button').on('click', renderReserveForm);
+ $("#add-reservation-form").remove();
+ }
+ });
+
+ console.log(trip);
+ console.log($(this).attr('class'));
+};
+
+const sortTrips = function sortTrips(){
+ let sortCategory = $(this).attr('class').split(' ')[1];
+ tripList.comparator = sortCategory;
+ tripList.sort();
+ console.log('sorted');
+};
+
+const singleTrip = function singleTrip(tripId){
+ console.log(`tripId is ${tripId}`)
+ let singleTripVar = tripList.findWhere({id: tripId});
+ console.log(singleTripVar);
+};
+
+// const renderAllTrips = function
$(document).ready( () => {
- $('main').html('