diff --git a/dist/index.html b/dist/index.html index b873b1e..09eeb56 100644 --- a/dist/index.html +++ b/dist/index.html @@ -2,19 +2,156 @@ - My JavaScript App + BackTREK + +
- +

BackTREK

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

Add a Trip!

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
+
+
+
+ + +
+ +
+

Trips!

+ + + + + + + + + + + + +
NameCategoryContinentWeeksCostID
+
+ +
+
+

-

+

+ + + + + + + + - + + + + + + diff --git a/src/app.js b/src/app.js index e7af594..7c2a0b7 100644 --- a/src/app.js +++ b/src/app.js @@ -6,8 +6,156 @@ import _ from 'underscore'; import './css/foundation.css'; import './css/style.css'; +import Trip from './app/models/trip'; +import Reservation from './app/models/reservation'; +import TripList from './app/collections/trip_list'; + console.log('it loaded!'); +const tripList = new TripList(); +let tripTemplate; +let atripTemplate; +let trip; + +const render = function render(tripList) { + const $tripList = $('#trip-list'); + $tripList.empty(); + tripList.forEach((trip) => { + $tripList.append(tripTemplate(trip.attributes)); + }); +}; + +const seeTrip = function seeTrip(id){ + trip = tripList.get(id); + trip.fetch({success: events.getTrip}); +} + +const updateStatusMessageWith = (message) => { + $('#status-messages ul').empty(); + $('#status-messages ul').append(`
  • ${message}
  • `); + $('#status-messages').show(); +} + +const tripFields = ['name', 'continent', 'about', 'category', 'weeks', 'cost']; +const rezFields = ['name', 'age', 'email']; +const events = { + showTrips() { + $('#trips-table').toggle({'display': 'block'}); + }, + showNewForm() { + $('#new-form').toggle({'display': 'block'}); + }, + getTrip(trip) { + const $onetrip = $('.onetrip'); + $onetrip.empty(); + $onetrip.append(atripTemplate(trip.attributes)); + }, + makeReservation(event){ + event.preventDefault(); + const rezData = {}; + rezFields.forEach( (field) => { + const val = $(`#rezform input[name=${field}]`).val(); + if (val != '') { + rezData[field] = val; + } + }); + const reservation = new Reservation(rezData); + + if (reservation.isValid()) { + const tripID = $(event.currentTarget.attributes.atripid).val(); + console.log(tripID) + reservation.urlRoot = `${(new Trip()).urlRoot}${tripID}/reservations`; + reservation.save({}, { + success: events.successfullSave, + error: events.failedSave, + }); + } else { + updateStatusMessageWith('reservation is invalid'); + } + }, + successfullSave(reservation, response) { + $('#rezform.input').val(''); + updateStatusMessageWith('reservation added!') + }, + failedSave(reservation, response) { + updateStatusMessageWith('reservation failed!'); + reservation.destroy(); + }, + addTrip(event) { + event.preventDefault(); + const tripData = {}; + tripFields.forEach( (field) => { + const val = $(`#newtrip input[name=${field}]`).val(); + if (val != '') { + tripData[field] = val; + } + }); + const trip = new Trip(tripData); + + if (trip.isValid()) { + + trip.save({}, { + success: events.successfullTripSave, + error: events.failedTripSave, + }); + } else { + + updateStatusMessageWith('Trip was invalid.'); + } + + }, + successfullTripSave(trip, response) { + $('#newtrip.input').val(''); + updateStatusMessageWith('Trip added!') + }, + failedTripSave(trip, response) { + updateStatusMessageWith('Trip failed!'); + trip.destroy(); + }, + sortTrips(event) { + $('.current-sort-field').removeClass('current-sort-field'); + $(this).addClass('current-sort-field'); + + + let 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(); + } + } + }); + }, + +}; + $(document).ready( () => { - $('main').html('

    Hello World!

    '); + tripTemplate = _.template($('#trip-template').html()); + atripTemplate = _.template($('#atrip-template').html()); + $('#load').on('click', function() { + events.showTrips(); + }); + tripList.on('update', render, tripList); + tripList.fetch(); + + $('#trips-table').on('click', '.trip', function() { + let tripID = $(this).attr('atrip-id'); + seeTrip(tripID); + }) + $('#newtripform').on('click', function() { + events.showNewForm(); + }); + + $('.sort').click(events.sortTrips); + tripList.on('sort', render, tripList); + + $('#newtrip').submit(events.addTrip); + $(document).on('submit', '#rezform', events.makeReservation); + // $('main').html('

    Hello World!

    '); }); diff --git a/src/app/collections/trip_list.js b/src/app/collections/trip_list.js new file mode 100644 index 0000000..a887cf2 --- /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..3ce94ee --- /dev/null +++ b/src/app/models/reservation.js @@ -0,0 +1,11 @@ +import Backbone from 'backbone'; + +const Reservation = Backbone.Model.extend({ + initialize: function(attributes) { + }, + validate: function(attributes) { + const errors = {}; + const rezFields = ['name', 'age', 'email']; + } +}); +export default Reservation; diff --git a/src/app/models/trip.js b/src/app/models/trip.js new file mode 100644 index 0000000..8afa22e --- /dev/null +++ b/src/app/models/trip.js @@ -0,0 +1,8 @@ +import Backbone from 'backbone'; + +const Trip = Backbone.Model.extend({ + urlRoot: 'https://ada-backtrek-api.herokuapp.com/trips/', +}); + + +export default Trip; diff --git a/src/css/style.css b/src/css/style.css index b7b2d44..80dd369 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -1,2 +1,65 @@ /* Your styles go here! */ +* { + padding: 0; + margin: 0; +} +.trips { + overflow: scroll; +} +#trips-table { + display: none; +} + + +#new-form { + display: none; +} + +.active { + display: block; +} + +th.sort { + cursor: pointer; +} + +.current-sort-field { + background-color: darkgrey; + color: white; +} + + +#status-messages { + background-color: #dfdfdf; + + + 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; +}