diff --git a/dist/index.html b/dist/index.html index b873b1e..08b4f8f 100644 --- a/dist/index.html +++ b/dist/index.html @@ -4,17 +4,136 @@ My JavaScript App +
- +

Wanderlust Expeditions:

+

Choose Your Own Adventure

+
-
+
+ +
+ +
    +
+
+ + +
+
+ +

+

+
+
+ +
+ +
+ + +
+ +
+ +
+
+ + + + + + + + + + + + +
NameContinentCategoryWeeksPrice
+
+
+ +
- + + + + + + + + diff --git a/src/app.js b/src/app.js index e7af594..ee17c6c 100644 --- a/src/app.js +++ b/src/app.js @@ -6,8 +6,193 @@ import _ from 'underscore'; import './css/foundation.css'; import './css/style.css'; -console.log('it loaded!'); +// models and collections +import Trip from './app/models/trip'; +// import Reservation from './app/models/reservation'; +import TripList from './app/collections/trip_list'; + +const TRIP_FIELDS = ['name', 'continent', 'category', 'weeks', 'price']; +const RES_FIELDS = ['name', 'email']; + +let allTripsTemplate; +let showDetailsTemplate; +let statusMessageTemplate; + +// Render Methods + +const renderAll = function renderAll(tripList) { + const tripListElement = $('#trips-list'); + tripListElement.empty(); + $('th.sort').removeClass('current-sort-field'); + $(`th.sort.${ tripList.comparator }` ).addClass('current-sort-field'); + + tripList.on('update', renderAll); + tripList.on('sort', renderAll); + + tripList.forEach((trip) => { + let tripsHTML = allTripsTemplate(trip.attributes); + if (trip.id < 34) { + tripListElement.append( $(tripsHTML) ); + } + }); // for each +}; // renderAll function + +// error messages + +const reportStatus = function(status, message) { + console.log(`Reporting ${ status } message: ${ message } `); + const generatedHTML = statusMessageTemplate({ + status: status, + message: message, + }); + + $('#status-messsages ul').append(generatedHTML); + $('status-messages').show() +} + +const tripsApiErrorHandler = function(model, response) { + model.destroy(); + + if (response.responseJSON['errors']) { + const errors = response.responseJSON['errors']; + for (const field in errors) { + for (const problem of errors[field]) { + reportStatus('error', ` ${ field }: ${ problem }`); + } // for problem + } // error + + } else { + reportStatus('error', 'Could not save trip'); + console.log('Error response from server:') + console.log(response); + } // end else +} //handler + +const renderDetails = function renderDetails(id) { + const tripDetails = $('#trip-details'); + tripDetails.empty(); + const oneTrip = new Trip({id: id}); + oneTrip.fetch({}).done(() => { + tripDetails.append(showDetailsTemplate(oneTrip.attributes)); + }); +}; // renderDetails + +const makeReservation = function makeReservation(bookTripID, reservationFormData) { + let reserveURL = 'https://trektravel.herokuapp.com/trips/' + bookTripID + '/reservations'; + $.post(reserveURL, reservationFormData); +} + +const readAddTripForm = function readAddTripForm() { + const addTripData = {}; + TRIP_FIELDS.forEach( (field) => { + const inputElement = $(`add-trip-form input[name="${ field }"]`); + addTripData[field] = inputElement.val(); + }); + return addTripData; +}; // read form function + + +const clearForm = function clearForm() { + $('#add-trip-form input[name]').val(''); +}; + + +// Document Ready $(document).ready( () => { - $('main').html('

Hello World!

'); -}); + + + allTripsTemplate = _.template($('#all-trips-template').html() ); + showDetailsTemplate = _.template($('#show-details-template').html() ); + statusMessageTemplate = _.template($('#status-message-template').html() ); + + $('#individual-trip').hide(); + $('#all-trips').hide(); + $('#reserve-trip').hide(); + $('#add-trip').hide(); + $('#status-messages').hide(); + + const tripList = new TripList(); + + tripList.on('sort', renderAll); + + //Events + + // show add trip form + + $('#create-trip').on('click', function() { + console.log("You clicked to see the add trip form"); + $('#add-trip').show(); + }); + + // add a new trip + + $('#add-trip-form').on('submit', (event) => { + event.preventDefault(); + + $('#individual-trip').hide(); + const newTrip = new Trip(readAddTripForm); + tripList.add(newTrip); + newTrip.save({}, { + success: clearForm, + error: tripsApiErrorHandler + }); + $('#status-messages').show + }); + + // make reservations + + $('#reservation-form').on('submit', (event) => { + event.preventDefault(); + const bookTripID = $(event.target).attr('data-id'); + let reservationFormData = + $('#reservation-form').serialize(); + makeReservation(reservationFormData); + }) //end book trip + + // show trip reservation form + $('#trip-details').on('click', 'h4', function() { + console.log("You clicked to see the res form"); + console.log(this); + const bookTripID = $(this).attr('data-id'); + $('#reservation-form').attr("data-id", bookTripID); + $('#reserve-trip').show(); + }) + + + // show trip details + $('#trips-list').on('click', '.trips', (event) => { + const tripID = $(event.target).attr('data-id'); + $('#individual-trip').show(); + renderDetails(tripID); + window.scrollTo(0, 0); + }); + + // show all the trips + + const allTrips = $('#load-trips'); + allTrips.on('click', () => { + + tripList.fetch(); + $('#all-trips').show(); + }) + + // Clear error messages + $('#status-messages button.clear').on('click', (event) => { + $('#status-messages ul').html(''); + $('#status-messages').hide + }) + + // Sort Fields + TRIP_FIELDS.forEach((field) => { + const headerElement = $(`.sort.${ field }`); + + headerElement.on('click', () => { + console.log(`Sorting by ${ field }`); + tripList.comparator = field; + tripList.sort(); + + }); // click event handler + }); // fields for each + +}); // end document ready diff --git a/src/app/collections/trip_list.js b/src/app/collections/trip_list.js new file mode 100644 index 0000000..da7cf87 --- /dev/null +++ b/src/app/collections/trip_list.js @@ -0,0 +1,9 @@ +import Backbone from 'backbone'; +import Trip from '../models/trip'; + +const TripList = Backbone.Collection.extend({ +model: Trip, +url: 'https://ada-backtrek-api.herokuapp.com/trips' +}); + +export default TripList; diff --git a/src/app/models/reservation.js b/src/app/models/reservation.js new file mode 100644 index 0000000..c910bda --- /dev/null +++ b/src/app/models/reservation.js @@ -0,0 +1,15 @@ +// Defining the Model + +// import Backbone from 'backbone'; +// +// const Reservation = Backbone.Model.extend({ +// +// url: function() { +// console.log(this); +// return 'https://ada-backtrek-api.herokuapp.com/trips/' + this.get("id") + '/reservations'; +// } +// }); //end const Rervation +// +// export default Reservation; + +// https://ada-backtrek-api.herokuapp.com/trips/1/reservations diff --git a/src/app/models/trip.js b/src/app/models/trip.js new file mode 100644 index 0000000..0eb47ab --- /dev/null +++ b/src/app/models/trip.js @@ -0,0 +1,71 @@ +// Defining the Model + +import Backbone from 'backbone'; + +const Trip = Backbone.Model.extend({ + + + urlRoot: 'https://ada-backtrek-api.herokuapp.com/trips/', + + validate: function(attributes) { + const errors = {}; + const CONTINENTS = ['Asia', 'Africa', 'Australasia', 'Europe', 'South America', 'North America', 'asia', 'africa', 'australasia', 'europe', 'south america', 'north america'] + if (!attributes.name) { + errors['name'] = [' cannot be blank.']; + } //end name attribute + + if (!attributes.category) { + errors.category = [' cannot be blank'] + } + + if (!attributes.continent) { + errors.continent = [' cannot be blank']; + } + + if (!CONTINENTS.includes(attributes.continent)) { + errors.continent = [' is not a valid continent.']; + } + + if (!attributes.weeks) { + errors.weeks = [' cannot be blank']; + } else if (Number(attributes.weeks)) { + this.set("weeks", Number(attributes.weeks)); + } else if (!Number(attributes.weeks)){ + errors.weeks = [`"${ attributes.weeks }" is not a number`]; + } + + if (!attributes.cost) { + errors.cost = [' cannot be blank']; + } else if (Number(attributes.cost)) { + this.set("cost", Number(attributes.cost)); + } else if (!Number(attributes.cost)){ + errors.cost = [`"${ attributes.cost }" is not a number`]; + } + + if (Object.keys(errors).length < 1) { + return false; + } + + console.log("Client Side Validation Failures"); + console.log(errors); + return errors; + + }, //end validate + +}); //end const Trip + +export default Trip; + + + + + // urlRoot: 'https://ada-backtrek-api.herokuapp.com/trips/', +// url: function() { +// console.log(this); +// return 'https://ada-backtrek-api.herokuapp.com/trips/' + this.get("id"); +// } + + + +// +// urlRoot = 'https://ada-backtrek-api.herokuapp.com/trips' diff --git a/src/css/style.css b/src/css/style.css index b7b2d44..582c265 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -1,2 +1,61 @@ /* Your styles go here! */ +.current-sort-field { + color: blue; +} + +#reservation-form { + border: 10px solid purple; +} + +h1 h2 { + text-align: center; + /*border: 2px solid red;*/ +} + +h3 { + padding: 8%; + text-align: center; +} + +h4 { + display: block; + text-align: center; + width: 100%; +} + +nav { + text-align: center; +} + +#individual-trip { + border: 2px solid blue; +} + +#all-trips { + /*border: 2px solid green;*/ +} +.trip-details { + /*border: 2px solid blue;*/ + margin: 10px; + padding: 10px; +} + +#trips { + margin: 10px; +} + +/*#book-trip-form { + border: 2px solid green; + margin: 10px; +}*/ + +#weeks { + text-align: center; +} + +/*.show-trip-form { + border: 2px solid black; + display: block; + margin: 10px; +}*/