diff --git a/index.html b/index.html new file mode 100644 index 00000000..a07196c1 --- /dev/null +++ b/index.html @@ -0,0 +1,52 @@ + + + + Trekking + + + + + + + + + + +
+ +
+
+

Trek

+ + +
+ +
+
+

Trip Details

+
    +
    + +
    +

    Add reservation to this trip

    +
    +
    + + +
    + +
    + + +
    + + +
    +
    +
    +
    + + + + + diff --git a/index.js b/index.js new file mode 100644 index 00000000..8fe5f19d --- /dev/null +++ b/index.js @@ -0,0 +1,117 @@ +const URL = 'https://trektravel.herokuapp.com/trips'; + +const reportStatus = (message) => { + $('#status-message').html(message); +}; + +const reportError = (message, errors) => { + let content = `

    ${message}

    ` + content += ""; + reportStatus(content); +}; + +const showTripDetails = (event, tripId) => { + const tripDetails = $('#trip-details'); + tripDetails.empty(); + + event.preventDefault(); + + $('#trip-section').removeClass().addClass('show-reservation'); + + // trip details + axios.get(`${URL}/${tripId}`) + .then((response) => { + reportStatus(`Successfully loaded details for ${response.data.name} trip`); + tripDetails.append(`
  • Trip ID: ${response.data.id}
  • `); + tripDetails.append(`
  • Name: ${response.data.name}
  • `); + tripDetails.append(`
  • Continent: ${response.data.continent}
  • `); + tripDetails.append(`
  • About: ${response.data.about}
  • `); + tripDetails.append(`
  • Category: ${response.data.category}
  • `); + tripDetails.append(`
  • Duration: ${response.data.weeks} weeks
  • `); + tripDetails.append(`
  • Cost: ${response.data.cost}
  • `); + + $('#new-reservation').removeClass().addClass('show-reservation'); + }) + .catch((error) => { + reportStatus(`Encountered an error while loading trip: ${error.message}`); + console.log(error); + }); + + // reservation form + const readFormData = () => { + const parsedFormData = {}; + + const nameFromForm = $(`#reservation-form input[name="name"]`).val(); + parsedFormData.name = nameFromForm ? nameFromForm : undefined; + + const emailFromForm = $(`#reservation-form input[name="email"]`).val(); + parsedFormData.email = emailFromForm ? emailFromForm : undefined; + + return parsedFormData; + }; + + const clearForm = () => { + $(`#reservation-form input[name="name"]`).val(''); + $(`#reservation-form input[name="email"]`).val(''); + } + + // create new reservation + const createReservation = (event) => { + event.preventDefault(); + + const reservationData = readFormData(); + console.log(reservationData); + + reportStatus('Sending reservation data...'); + + axios.post(`${URL}/${tripId}/reservations`, reservationData) + .then((response) => { + reportStatus(`Successfully added a reservation for ${response.data.name}!`); + clearForm(); + }) + .catch((error) => { + console.log(error.response); + if (error.response.data && error.response.data.errors) { + reportError( + `Encountered an error: ${error.message}`, + error.response.data.errors + ); + } else { + reportStatus(`Encountered an error: ${error.message}`); + } + }); + }; + $('#reservation-form').submit(createReservation); +}; + +const listTrips = () => { + reportStatus('Loading trips...'); + + const tripList = $('#trip-list'); + tripList.empty(); + + $('#load').removeClass().addClass('hide-reservation'); + + // list all trips + axios.get(URL) + .then((response) => { + reportStatus(`Successfully loaded ${response.data.length} trips`); + response.data.forEach((trip) => { + tripList.append(`
  • ${trip.name}
  • `); + }); + }) + .catch((error) => { + reportStatus(`Encountered an error while loading trips: ${error.message}`); + console.log(error); + }); +}; + +$(document).ready(() => { + $('#load').click(listTrips); +}); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..48e341a0 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3 @@ +{ + "lockfileVersion": 1 +} diff --git a/styles.css b/styles.css new file mode 100644 index 00000000..ae494173 --- /dev/null +++ b/styles.css @@ -0,0 +1,36 @@ +.hide-reservation { + display: none; +} + +.show-reservation { + display: block; +} + +body { + font-family: 'Nunito', sans-serif; + margin: 2em; +} + +main { + display: grid; + grid-template-columns: repeat(2, 1fr); + grid-gap: 10px; + grid-auto-rows: minmax(100px, auto); + } + +.list-trips { + grid-column: 1; +} + +.trip { + grid-column: 2; +} + +#trip-details { + list-style-type: none; +} + +ul { + font-size: 1.25em; +} +