-
Notifications
You must be signed in to change notification settings - Fork 48
Ports - Amy W #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Ports - Amy W #29
Changes from all commits
cc3d8d9
e61355a
e476031
4796a48
52411a3
2c6c0de
135b4d0
4253a5f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| <!DOCTYPE html> | ||
| <html> | ||
| <head> | ||
| <title>Trekking</title> | ||
| <meta charset="utf-8"> | ||
| <script src="https://code.jquery.com/jquery-3.3.1.js"></script> | ||
| <script type="text/javascript" src="index.js"></script> | ||
| <script src="https://unpkg.com/axios/dist/axios.min.js"></script> | ||
| <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> | ||
| <link rel="stylesheet" href="styles.css"> | ||
| <link href="https://fonts.googleapis.com/css?family=Nunito&display=swap" rel="stylesheet"> | ||
| </head> | ||
|
|
||
| <body> | ||
| <section id="status-message"></section> | ||
|
|
||
| <main> | ||
| <section id="list-trips" class="current-trips"> | ||
| <h1>Trek</h1> | ||
| <button id="load" type="button" class="btn btn-primary">See all Trips</button> | ||
| <ul id="trip-list"></ul> | ||
| </section> | ||
|
|
||
| <section class="trip"> | ||
| <section class="selected-trip"> | ||
| <h1 id="trip-section" class="hide-reservation">Trip Details</h1> | ||
| <ul id="trip-details"></ul> | ||
| </section> | ||
|
|
||
| <section id="new-reservation" class="hide-reservation"> | ||
| <h1>Add reservation to this trip</h1> | ||
| <form id="reservation-form"> | ||
| <div> | ||
| <label for="name">Name</label> | ||
| <input type="text" name="name" /> | ||
| </div> | ||
|
|
||
| <div> | ||
| <label for="email">Email</label> | ||
| <input type="text" name="email" /> | ||
| </div> | ||
|
|
||
| <input type="submit" name="add-reservation" value="Reserve" class="btn btn-primary"/> | ||
| </form> | ||
| </section> | ||
| </section> | ||
| </main> | ||
| </body> | ||
| </html> | ||
|
|
||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| const URL = 'https://trektravel.herokuapp.com/trips'; | ||
|
|
||
| const reportStatus = (message) => { | ||
| $('#status-message').html(message); | ||
| }; | ||
|
|
||
| const reportError = (message, errors) => { | ||
| let content = `<p>${message}</p>` | ||
| content += "<ul>"; | ||
| for (const field in errors) { | ||
| for (const problem of errors[field]) { | ||
| content += `<li>${field}: ${problem}</li>`; | ||
| } | ||
| } | ||
| content += "</ul>"; | ||
| 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(`<li>Trip ID: ${response.data.id}</li>`); | ||
| tripDetails.append(`<li>Name: ${response.data.name}</li>`); | ||
| tripDetails.append(`<li>Continent: ${response.data.continent}</li>`); | ||
| tripDetails.append(`<li>About: ${response.data.about}</li>`); | ||
| tripDetails.append(`<li>Category: ${response.data.category}</li>`); | ||
| tripDetails.append(`<li>Duration: ${response.data.weeks} weeks</li>`); | ||
| tripDetails.append(`<li>Cost: ${response.data.cost}</li>`); | ||
|
|
||
| $('#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); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Every time you click on trips, this attaches a new event handler to the form. This means if I click on a few trips a few times and then fill out and submit the form, several submit event handlers will fire and I'll get added to the trip multiple times. Take a look at it in dev tools with the network tab open. You'll see the problem. Instead you should clear all the event handlers from the form before attaching a new one. |
||
| }; | ||
|
|
||
| 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(`<li><a href="#" onclick="return showTripDetails(event, ${trip.id});">${trip.name}</a></li>`); | ||
| }); | ||
| }) | ||
| .catch((error) => { | ||
| reportStatus(`Encountered an error while loading trips: ${error.message}`); | ||
| console.log(error); | ||
| }); | ||
| }; | ||
|
|
||
| $(document).ready(() => { | ||
| $('#load').click(listTrips); | ||
| }); | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nicely done