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
+
+
+
+
+
+
+
+
+ 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 += "";
+ for (const field in errors) {
+ for (const problem of errors[field]) {
+ content += `- ${field}: ${problem}
`;
+ }
+ }
+ 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;
+}
+