diff --git a/dist/index.html b/dist/index.html
index b873b1e..c471626 100644
--- a/dist/index.html
+++ b/dist/index.html
@@ -2,19 +2,148 @@
- My JavaScript App
+ BackTREK
+
+
-
+
+ World Trek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trips:
+
+
+ | Name |
+ Category |
+ Continent |
+ Cost |
+ Weeks |
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app.js b/src/app.js
index e7af594..cbde339 100644
--- a/src/app.js
+++ b/src/app.js
@@ -6,8 +6,350 @@ import _ from 'underscore';
import './css/foundation.css';
import './css/style.css';
-console.log('it loaded!');
+import Trip from './app/models/trip';
+import TripList from './app/collections/trip_list';
+import Reservation from './app/models/reservation';
+
+//console.log('it loaded!');
+
+//TRIPS TABLE:
+const tripList = new TripList();
+let tripsTemplate;
+
+const renderTrips = function renderTrips(tripList) {
+ console.log('it loaded!');
+ $('#load-trips').hide();
+ $('#add-new-trip').show();
+ tripsTemplate = _.template($('#trips-template').html());
+ //get the element to append to
+ const tripListTable = $('#trips-list');
+ tripListTable.empty();
+ tripList.forEach((trip) => {
+ tripListTable.append(tripsTemplate(trip.attributes));
+ //console.log(trip);
+ });
+ console.log('finished loading trips')
+};
+
+//TRIP DETAILS (ONE TRIP)
+let singleTripTemplate;
+const renderSingleTrip = function renderSingleTrip(tripID) {
+ console.log('it loaded a trip!');
+ console.log(tripID);
+ const tripDetailsContainer = $('#trip-details-container');
+ tripDetailsContainer.empty();
+ //why am i defining let singleTripTemplate outsie of method instead of inside?
+ singleTripTemplate = _.template($('#single-trip-template').html());
+ let trip;
+ trip = new Trip({id: tripID});
+ trip.fetch().done(() => {
+ $('#trip-details-container').append(singleTripTemplate(trip.attributes));
+ $('#trip-details-container').attr('tripID', tripID);
+ });
+ console.log(trip);
+}
+
+
+
+//EVENT LISTENER
+//1. Create listener:
+// const bogusListener = function bogusListener(event) {
+// console.log('Event Occurred!');
+// console.log(event);
+// console.log(this);
+// };
+// // // 2. Register the Event Handler with the Component
+// tripList.on('bogus', bogusListener);
+// // // 3. Trigger the event
+// tripList.trigger('bogus', 'Argument!');
+
+const tripFields = ["name", "category", "continent", "cost", "weeks", "about"];
+const reservationFields = ["name", "age", "email"];
+
+const events = {
+ addTrip(event) {
+ event.preventDefault();
+ console.log('in addTrip method! Trip Data:')
+ const tripData = {};
+ tripFields.forEach( (field) => {
+ tripData[field] = $(`input[name=${field}]`).val();
+ });
+ console.log(tripData);
+ const trip = new Trip(tripData);
+
+ if (trip.isValid()) {
+ console.log("Trip is valid");
+ trip.save({}, {
+ success: events.successfullTripSave,
+ error: events.failedTripSave,
+ });
+ } else {
+ console.log('NOT VALID');
+ events.failedTripSave(trip, {errors: trip.isValid() });
+ }
+
+ console.log('finished')
+
+ },
+ successfullTripSave(trip, response) {
+ console.log('successfulTripSave');
+ tripList.add(trip);
+ console.log('Trip Added');
+ console.log(trip);
+ console.log(response);
+ $('#status-messages ul').empty();
+ $('#status-messages ul').append(`${trip.get('name')} added!`)
+ $('#status-messages').show();
+ document.getElementByID('#add-a-trip-form-container').style.display = "none";
+ document.getElementByID('#add-trip-form').reset();
+ },
+ failedTripSave(trip, response) {
+ console.log('failedTripSave');
+ console.log(trip);
+ console.log(response);
+ $('#status-messages ul').empty();
+ $('#status-messages ul').append(`${trip.get('name')} WAS NOT added!`);
+ console.log(response.responseJSON);
+ const displayErrors = response.responseJSON.errors
+ for (var key in displayErrors){
+ console.log(key);
+ $('#status-messages ul').append(`${key}: ${displayErrors[key]}`);
+ };
+ $('#status-messages').show();
+ },
+ sortBooks(event) {
+ // remove current-sort-field from the class
+ // list of any element that has it.
+ $('.current-sort-field').removeClass('current-sort-field');
+ // Add the class to the current selected element
+ $(this).addClass('current-sort-field');
+ // Get the class list of the selected element
+ const classes = $(this).attr('class').split(/\s+/);
+
+ classes.forEach((className) => {
+ if (tripFields.includes(className)) {
+ if (className === tripList.comparator) {
+ tripList.models.reverse();
+ tripList.trigger('sort', tripList);
+ }
+ else {
+ tripList.comparator = className;
+ tripList.sort();
+ }
+ }
+ });
+ },
+ addReservation(event) {
+ event.preventDefault();
+ console.log('in addReservation method! Reservation Data:');
+ const reservationData = {};
+ reservationFields.forEach( (field) => {
+ reservationData[field] = $(`#add-reservation-form input[name=${field}]`).val();
+ });
+ console.log(reservationData);
+ const tripNumber= $('#add-reservation-form').attr('trip-id');
+
+ console.log(`tripNumber: ${tripNumber}`);
+
+ // reservation.set({"tripID": `${tripNumber}` });
+ const postURL = `https://ada-backtrek-api.herokuapp.com/trips/${tripNumber}/reservations/`;
+ const reservation = new Reservation(reservationData);
+ //const reservation = new Reservation(reservationData, {url:postURL});
+ reservation.set({"url": `${postURL}` });
+ console.log(reservation.get('url'));
+ console.log(reservation);
+ if (reservation.isValid()) {
+ reservation.save({}, {
+ success: events.successfullReservationSave,
+ error: events.failedReservationSave,
+ });
+ } else {
+ console.log('NOT VALID RESERVATION DATA');
+ events.failedReservationSave(reservation, {errors: reservation.validate() });
+ }
+ },
+ successfullReservationSave(reservation, response) {
+ console.log('successfulReservationSave');
+ console.log(reservation);
+ console.log(response);
+ $('#status-messages ul').empty();
+ $('#status-messages ul').append(`${reservation.get('name')} added!`)
+ $('#status-messages').show();
+ },
+ failedReservationSave(reservation, response) {
+ console.log('failedReservationSave');
+ console.log(reservation);
+ console.log(response);
+ console.log(response.responseText);
+ //let JSONresponse = JSON.parse(response);
+ //console.log(JSONresponse);
+ //console.log(JSON.stringify(response));
+ //const responseJSON = JSON.stringify(response);
+ $('#status-messages ul').append(`${reservation.get('name')} WAS NOT added!`);
+ $('#status-messages ul').empty();
+ //responseJSON.forEach(function(data) {
+ // $('#status-messages ul').append(`${data}`);
+ //});
+ $('#status-messages').show();
+ },
+
+};
+
+//POST RESERVATION INFO (RECEIVE INFO FROM FORM)
+const submitReservation = function submitReservation() {
+ $('#add-reservation-form').submit( function(e) {
+ e.preventDefault();
+ let form = document.createElement("form");
+ let tripID = $('#add-reservation-form').attr('trip-id');
+ console.log(`tripID from trip ul: ${tripID}`);
+ //$('#trip-details-container').attr('reservation-trip-id');
+ const url = 'https://ada-backtrek-api.herokuapp.com/trips/' + tripID + '/reservations/';
+ console.log(`URL: ${url}`);
+ const personName = $(this).serializeArray()[0].value;
+ const formData = $(this).serialize();
+ console.log(`formData: ${formData}`)
+
+ $.post(url, formData, (response) => {
+ console.log('Received POST response:');
+ console.log(response);
+ alert(`Reservation confirmed for ${personName}` );
+ console.log(`successfully posted reservation for ${personName}`)
+ console.log(response);
+ })
+ .fail(function(response){
+ console.log(response);
+ $('#status-messages ul').append('Post was unsuccessful')
+ })
+ .always(function(){
+ console.log('always even if we have success or failure');
+ });
+ });
+};
+
+//MODAL
+
+const modalAddTrip = function() {
+ const modal = $('#add-a-trip-form-container');
+ const openModal = $('#add-new-trip');
+ // const closeModal = $('.close');
+ const closeModal = document.getElementsByClassName("close")[0];
+ openModal.onclick = function() {
+ modal.style.display = "block";
+ };
+ closeModal.onclick = function() {
+ modal.style.display = "none";
+ };
+ window.onclick = function(event) {
+ if (event.target == modal) {
+ modal.style.display = "none";
+ }
+ };
+}
+// function openDialog(selector) {
+// $(selector)
+// .clone()
+// .show()
+// .appendTo('#overlay')
+// .parent()
+// .fadeIn('fast');
+// }
+
+// function closeDialog(selector) {
+// $(selector)
+// .parents('#overlay')
+// .fadeOut('fast', function() {
+// $(this)
+// .find(".dialog")
+// .remove();
+// });
+// }
+
+ // window.onload = function onloadFunction() {
+ // //setup edit person dialog
+ // console.log('In onloadFunction');
+ // $('#add-a-trip-form-container').dialog({
+ // autoOpen: false,
+ // draggable: true,
+ // title: "Did This Work?",
+ // open: function(type, data) {
+ // $(this).parent().appendTo("#add-trip-form");
+ // }
+ // });
+ // }
$(document).ready( () => {
- $('main').html('Hello World!
');
+ $('#reservation-form-container').hide();
+ $('#add-a-trip-form-container').hide();
+ $('#trips-table-container').hide();
+ $('#add-new-trip').hide();
+
+ modalAddTrip();
+
+ $('#load-trips').on('click', function(){
+ console.log('clicked load');
+ $('#trips-table-container').show();
+ tripList.fetch();
+ });
+
+ $('#trips-table-container').on('click', 'tr', function () {
+ const tripID = $(this).attr('data-id');
+ renderSingleTrip(tripID);
+ $('#add-reservation-form').attr('trip-id',`${tripID}`);
+ $('#reservation-form-container').show();
+ });
+
+ //submit reservation button USING AJAX
+ $('#add-reservation-form').on('click','#submit-reservation', function(){
+ console.log('pressed reservation form button');
+ submitReservation();
+ $('#reservation-form-container').hide();
+ });
+
+ //show form to Add a Trip
+ $('#add-new-trip').on('click', function() {
+ // openDialog('#add-a-trip-form-container');
+ $('#add-a-trip-form-container').show();
+ // $('.dialog').dialog();
+ // return false;
+ });
+
+ // $('#add-a-trip-form-container')
+ // .find('.ok, .cancel')
+ // .live('click', function() {
+ // closeDialog(this);
+ // })
+ // .end()
+ // .find('.ok')
+ // .live('click', function() {
+ // console.log('Clicked Submit!')
+ // })
+ // .end()
+ // .find('cancel')
+ // .live('click', function() {
+ // console.log('Clicked Cancel')
+ // });
+
+ //submit form to Add a Trip
+ //creates a new instance of the Trip model
+ //$('#add-a-trip-form-container').on('submit','#add-trip-form', events.addTrip);
+ $('#add-trip-form').on('submit', events.addTrip);
+ //tripsTemplate = _.template($('#trips-template').html());
+ //THIS WAY DOESN"T WORK- it just performs the submit, rather than waits to hear if a submit event is happening
+ //$('#add-trip-form').submit(events.addTrip);
+
+ //submit form to add a reservation USING RESERVATION MODEL (DOESN'T WORK):
+ //$('#reservation-form-container').on('submit','#add-reservation-form', events.addReservation);
+
+
+
+ //sort table:
+ $('.sort').click(events.sortBooks);
+ tripList.on('sort',renderTrips,tripList);
+
+ //update table
+ tripList.on('update', renderTrips, tripList);
+
+
+
+
});
diff --git a/src/app/collections/trip_list.js b/src/app/collections/trip_list.js
new file mode 100644
index 0000000..a77fbc0
--- /dev/null
+++ b/src/app/collections/trip_list.js
@@ -0,0 +1,14 @@
+import Backbone from 'backbone';
+
+//import model so collection knows what its a collection of:
+import Trip from '../models/trip';
+
+const TripList = Backbone.Collection.extend({
+ model: Trip,
+ url: 'https://ada-backtrek-api.herokuapp.com/trips',
+ parse: function(response) {
+ return response;
+ },
+});
+
+export default TripList;
diff --git a/src/app/models/reservation.js b/src/app/models/reservation.js
new file mode 100644
index 0000000..ab005c1
--- /dev/null
+++ b/src/app/models/reservation.js
@@ -0,0 +1,23 @@
+import Backbone from 'backbone';
+
+const Reservation = Backbone.Model.extend({
+ url: function(){
+ return this.instanceUrl;
+ },
+ initialize: function(attributes){
+ this.instanceUrl = attributes.url;
+ },
+ parse: function(response) {
+ return response;
+ },
+ validate: function(attributes) {
+ // console.log(this.url);
+ // console.log(attributes)
+ console.log('in the Reservation validate function');
+ const errors = {};
+ },
+
+
+});
+
+export default Reservation;
diff --git a/src/app/models/trip.js b/src/app/models/trip.js
new file mode 100644
index 0000000..e0f8b08
--- /dev/null
+++ b/src/app/models/trip.js
@@ -0,0 +1,52 @@
+import Backbone from 'backbone';
+
+const Trip = Backbone.Model.extend({
+ urlRoot: 'https://ada-backtrek-api.herokuapp.com/trips/',
+ parse: function(response) {
+ return response;
+ },
+ initialize: function(attributes) {
+ console.log('Attributes from initialize function:');
+ console.log(attributes);
+ console.log(`In initialize for the trip ${attributes.name}`);
+ },
+ validate: function(attributes) {
+ console.log('in the Trip validate function');
+ console.log(attributes); //UNDEFINED
+ //CAUSES ERROR- CANNOT READ PROPERTY OF 'NAME' OF UNDEFINED: console.log(attributes.name);
+ const errors = {};
+
+ if (!attributes.name) {
+ errors['name'] = ["Trip name cannot be blank"];
+ }
+ if (!attributes.category) {
+ errors['category'] = ["Category cannot be blank."];
+ }
+ if (!attributes.continent) {
+ errors['continent'] = ["Continent cannot be blank."];
+ }
+ if (!attributes.cost) {
+ errors['cost'] = ["Cost cannot be blank."];
+ }
+ if (!attributes.weeks) {
+ errors['weeks'] = ["Weeks cannot be blank."];
+ }
+
+ const CONTINENTS = ['Africa', 'Antartica', 'Asia', 'Australasia', 'Europe', 'North America', 'South America'];
+ if (CONTINENTS.includes(attributes.continent)) {
+ console.log('valid continent');
+ } else {
+ console.log('invalid continent');
+ errors['continent'] = ["Continent must be: Africa, Antartica, Asia, Australasia, Europe, North America or South America"];
+ }
+
+ console.log(`errors: ${errors.keys}`);
+ if ( Object.keys(errors).length > 0 ) {
+ return errors;
+ } else {
+ return false;
+ }
+ },
+});
+
+export default Trip;
diff --git a/src/css/style.css b/src/css/style.css
index b7b2d44..080928c 100644
--- a/src/css/style.css
+++ b/src/css/style.css
@@ -1,2 +1,85 @@
+body {
+ margin: 20px;
+}
-/* Your styles go here! */
+.title {
+ display: flex;
+ justify-content: center;
+}
+
+#add-a-trip-form-container {
+ display: none;
+ position: absolute;
+ margin: 100px auto;
+ overflow: auto;
+ width: 60%;
+ height: 100%;
+ padding: 40px;
+ background-color: rgb(0,0,0);
+ background-color: rgba(0,0,0,0.8);
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ border: 1px solid black;
+ /*-mox-border-radius: 10px;*/
+ z-index: 1;
+}
+.close {
+ font-size: 28px;
+}
+
+#add-trip-form {
+ color: white;
+}
+
+/*#submit-new-trip-button {
+ margin: 10px;
+}*/
+
+.new-trip-title {
+ color: white;
+}
+
+.trip-ul {
+ list-style: none;
+}
+
+/*.reservation-form-container {
+ margin: 10px;
+}*/
+
+/* STATUS MESSAGE STYLING */
+#status-messages {
+ background-color: #dfdfdf;
+
+ /* Hide by default */
+ display: none;
+
+ border-radius: 1rem;
+ margin: 1rem;
+ height: 100%;
+ padding: .8rem;
+}
+
+#status-messages ul {
+ list-style: none;
+ margin-left: 0;
+}
+
+#status-messages button.clear {
+ margin-top: .2rem;
+ height: 100%;
+}
+
+#status-messages button.clear img {
+ width: 2rem;
+}
+
+#status-messages .error {
+ color: red;
+}
+
+#status-messages .success {
+ color: green;
+}