diff --git a/index.css b/index.css new file mode 100644 index 00000000..cb8274af --- /dev/null +++ b/index.css @@ -0,0 +1,42 @@ +body { + padding: 10px; + background-color: gainsboro; + text-align: center; +} + +main { + display: grid; + grid-template-columns: 1fr 1fr; +} + +ul { + list-style: none; +} + +.status-message { + font-weight: 600; + padding: 10px; + font-size: 1rem; +} + +.trip-list { + padding-top: 10px; +} + +.trip-info { + height: 50vh; + overflow: scroll; +} + +.current-trips { + grid-column: 1 / 2; +} + +.trip-detail { + grid-column: 2 / 3; +} + +#reserve-form { + text-align: center; + padding-top: 20px; +} diff --git a/index.html b/index.html new file mode 100644 index 00000000..0f17fc00 --- /dev/null +++ b/index.html @@ -0,0 +1,36 @@ + + + + + Trek + + + + +
+

Trek

+ +
+
+
+
+
+ + +
+ +
+
+
    +
    + +
    +
    +
    +
    + + + + + + diff --git a/index.js b/index.js new file mode 100644 index 00000000..19f71306 --- /dev/null +++ b/index.js @@ -0,0 +1,141 @@ +const URL = 'https://trektravel.herokuapp.com/trips' + +const reportStatus = (message) => { + $('.status-message').html(message); +}; + +const displayError = (error) => { + if (error.response === undefined) { + reportStatus(`${error.message}`) + } else { + reportStatus(`${error.message}: ${error.response.statusText}`); + } +} + +const displayFormErrors = (error) => { + const formErrors = error.response.data.errors + $('.form-errors').empty(); + for (const field in formErrors) { + for (const problem of formErrors[field]) { + $('.form-errors').append(`

    ${capitalize(field)}: ${problem}

    `); + } + } +}; + +const displayNoContentError = (response) => { + reportStatus(`Request failed with status code ${response.status}: ${response.statusText}.`); +}; + +const capitalize = (string) => { + return string.replace(/^\w/, c => c.toUpperCase()); +} + +const sendGetRequest = (id) => { + const buildGetRequest = () => { + reportStatus('Loading...'); + axios.get(URL + id) + .then((response) => { + if (response.status === 204) { + displayNoContentError(response); + } else { + let callback = response.data.length ? parseTripCollection : parseIndividualTrip + parseGetResponse(response, callback) + } + }) + .catch((error) => { + displayError(error); + }); + }; + return buildGetRequest; +}; + +const parseGetResponse = (response, callback) => { + let tripData = response.data + let element = callback === parseTripCollection ? $('#trip-list') : $('#trip-detail-list') + element.empty(); + callback(tripData, element); +}; + +const parseTripCollection = (tripData, element) => { + reportStatus(`Successfully loaded ${tripData.length} trips.`) + $('.form-errors').empty(); + tripData.forEach((trip) => { + element.append( + `
  • `); + }); +} + +const parseIndividualTrip = (tripData, element) => { + reportStatus(`Successfully loaded ${tripData.name}.`) + $('.form-errors').empty(); + element.append(`

    ${tripData.name}

    `); + const tripProperties = ['continent', 'category', 'weeks', 'cost'] + tripProperties.forEach((prop) => { + let header = capitalize(prop); + element.append( + `
  • ${header}: ${tripData[prop]}
  • ` + ) + }); + element.append(`

    ${tripData.about}

    `) + appendResForm(tripData); +} + +const appendResForm = (tripData) => { + $('#reserve-form').empty(); + $('#reserve-form').append( + `

    Make a reservation for ${tripData.name}

    + +
    + + +
    +
    + + +
    + `) +} + +const reserveTrip = (event) => { + event.preventDefault(); + reportStatus('Sending request...'); + + const resFormData = { + name: $('input[name="name"]').val(), + email: $('input[name="email"]').val(), + id: $('input[id="tripId"]').val() + }; + + const uri = URL + `/${resFormData.id}` + '/reservations' + + axios.post(uri, resFormData) + .then((response) => { + if (response.status === 204) { + displayNoContentError(response); + } else { + reportStatus(`Sucessfully reserved! Please save your reservation id: ${response.data.id}`); + $('.form-errors').empty(); + } + $('#reserve-form')[0].reset(); + }) + .catch((error) => { + displayError(error); + if (error.response.data.errors) { + displayFormErrors(error); + } + }); +}; + +$(document).ready(() => { + const getAllTrips = sendGetRequest('/'); + $('#load-all-trips').click(getAllTrips); + + $('ul').on('click', 'button', function(event) { + let id = '/' + $(this).attr('id'); + const getTripDetails = sendGetRequest(id); + getTripDetails(); + }); + + $('#reserve-form').submit(reserveTrip); +});