-
Notifications
You must be signed in to change notification settings - Fork 47
Val - Edges - Trek #34
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?
Changes from all commits
91cdae8
e59dd99
c02b806
ac9ab06
13ba345
a131ac8
ee7210d
99c403c
e7af612
d30d539
9e14517
6a0ec8d
48dbe36
81f8c03
c31debd
092d730
c3d8bfd
1694346
1672728
0c008d0
75dfa58
71eb979
2789c07
e0e5ffc
ff5c980
3d9937f
03680fb
8bbfc0a
ef37562
eae1da8
1ecaf28
c163c64
936fc67
4bcd733
4644f2e
58a4d69
21057b6
247c7ef
861ee74
685f4e9
e4e7fb2
56c21c3
df33531
7ae7f03
e633f02
5c504e8
5f69bc3
66f678c
c2e73b0
99ba418
8df49ba
8a40dbf
0fcfee9
1b56f8f
b0bf5f8
cce6ef4
1db71f6
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,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; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en" dir="ltr"> | ||
| <head> | ||
| <meta charset="utf-8"> | ||
| <title>Trek</title> | ||
| <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> | ||
| <link rel="stylesheet" href="index.css"> | ||
| </head> | ||
| <body> | ||
| <header> | ||
| <h1>Trek</h1> | ||
| <button type="button" class="btn btn-outline-info btn-lg" id="load-all-trips">Find your next adventure...</button> | ||
| </header> | ||
| <section class="status-message"></section> | ||
| <section class="form-errors"></section> | ||
| <main> | ||
| <section class="current-trips"> | ||
|
|
||
| <ul id="trip-list"></ul> | ||
| </section> | ||
|
|
||
| <section class="trip-detail"> | ||
| <div class="trip-info"> | ||
| <ul id="trip-detail-list"></ul> | ||
| </div> | ||
|
|
||
| <form id="reserve-form"> | ||
| </form> | ||
| </section> | ||
| </main> | ||
|
|
||
| <script src="https://code.jquery.com/jquery-3.3.1.js"></script> | ||
| <script src="https://unpkg.com/axios/dist/axios.min.js"></script> | ||
| <script type="text/javascript" src="index.js"></script> | ||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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(`<p>${capitalize(field)}: ${problem}</p>`); | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| 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 | ||
|
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. I like this code! It shows the depth of your knowledge about this response: if there is a non-zero length of data (it's an array) then it'll be a trip collection. I'm excited that it was so readable for me! |
||
| parseGetResponse(response, callback) | ||
| } | ||
|
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. nice detail and handling the different responses |
||
| }) | ||
| .catch((error) => { | ||
| displayError(error); | ||
| }); | ||
| }; | ||
| return buildGetRequest; | ||
|
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. I think this is super clever and a great way to work the functions and name them so they are both flexible and specific. Nicely done! |
||
| }; | ||
|
|
||
| const parseGetResponse = (response, callback) => { | ||
| let tripData = response.data | ||
| let element = callback === parseTripCollection ? $('#trip-list') : $('#trip-detail-list') | ||
|
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. Nice ternary! 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. Missing semicolons in the above two lines |
||
| element.empty(); | ||
| callback(tripData, element); | ||
|
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. This logic allows you to be flexible about exactly which action is happening at this time. Niiice. |
||
| }; | ||
|
|
||
| const parseTripCollection = (tripData, element) => { | ||
| reportStatus(`Successfully loaded ${tripData.length} trips.`) | ||
|
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. semicolon |
||
| $('.form-errors').empty(); | ||
| tripData.forEach((trip) => { | ||
| element.append( | ||
| `<li><button id="${trip.id}" class="btn btn-outline-secondary btn-block"> | ||
| ${trip.name}</button></li>`); | ||
| }); | ||
| } | ||
|
|
||
| const parseIndividualTrip = (tripData, element) => { | ||
| reportStatus(`Successfully loaded ${tripData.name}.`) | ||
|
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. semicolon |
||
| $('.form-errors').empty(); | ||
| element.append(`<h3>${tripData.name}</h3>`); | ||
| const tripProperties = ['continent', 'category', 'weeks', 'cost'] | ||
| tripProperties.forEach((prop) => { | ||
| let header = capitalize(prop); | ||
|
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. this can be a |
||
| element.append( | ||
| `<li>${header}: ${tripData[prop]}</li>` | ||
| ) | ||
| }); | ||
| element.append(`<p>${tripData.about}</p>`) | ||
| appendResForm(tripData); | ||
| } | ||
|
|
||
| const appendResForm = (tripData) => { | ||
| $('#reserve-form').empty(); | ||
| $('#reserve-form').append( | ||
| `<h4>Make a reservation for ${tripData.name}</h4> | ||
| <input type="hidden" id="tripId" name="tripId" value="${tripData.id}"> | ||
| <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-res" value="Submit"/>`) | ||
|
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. semicolon. Nicely done on this |
||
| } | ||
|
|
||
| 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); | ||
| }); | ||
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.
nice helper method!