Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
91cdae8
Add html doc and scripts for JS, jQuery, axios
valgidzi Nov 21, 2018
e59dd99
Add js doc
valgidzi Nov 21, 2018
c02b806
Section for current trips list
valgidzi Nov 21, 2018
ac9ab06
loadTrips function with get request for all trips
valgidzi Nov 21, 2018
13ba345
Section for status message
valgidzi Nov 21, 2018
a131ac8
Create reportStatus method, invoke in loadPets for UI feedback
valgidzi Nov 21, 2018
ee7210d
Rename loadTrips as getAllTrips
valgidzi Nov 22, 2018
99c403c
Trip detail container
valgidzi Nov 22, 2018
e7af612
Add stylesheet with basic grid layout
valgidzi Nov 22, 2018
d30d539
Link to CSS
valgidzi Nov 22, 2018
9e14517
Change id on get trips button
valgidzi Nov 22, 2018
6a0ec8d
Wrap trip list names in button tag, add id
valgidzi Nov 22, 2018
48dbe36
getTripDetail function with get request for single trip - first draft…
valgidzi Nov 22, 2018
81f8c03
Change trip list button id value to integer only
valgidzi Nov 23, 2018
c31debd
Update getTripDetail to take id parameter, add to request URL
valgidzi Nov 23, 2018
092d730
Event handling function to get id from trip that was clicked
valgidzi Nov 23, 2018
c3d8bfd
ul styling
valgidzi Nov 23, 2018
1694346
Add trip info to trip detail section
valgidzi Nov 23, 2018
1672728
Refactor get request methods
valgidzi Nov 24, 2018
0c008d0
Remove extra get request
valgidzi Nov 24, 2018
75dfa58
Removed unused variable
valgidzi Nov 24, 2018
71eb979
Refactor handleGetResponse function, add element parameter
valgidzi Nov 24, 2018
2789c07
Refactor handleGetResponse info display
valgidzi Nov 24, 2018
e0e5ffc
Refactor trip detail html with forEach
valgidzi Nov 24, 2018
ff5c980
Rename get request methods
valgidzi Nov 25, 2018
3d9937f
Rename get response method
valgidzi Nov 25, 2018
03680fb
Refactor get response methods
valgidzi Nov 25, 2018
8bbfc0a
Merge refactor-get-methods branch into master
valgidzi Nov 25, 2018
ef37562
Create res form in html doc
valgidzi Nov 25, 2018
eae1da8
reserveTrip function sends post requests
valgidzi Nov 25, 2018
1ecaf28
Move res form fields to js
valgidzi Nov 25, 2018
c163c64
appendResForm function
valgidzi Nov 25, 2018
936fc67
Adjust grid layout for res form
valgidzi Nov 25, 2018
4bcd733
appendResForm takes id and stores in hidden form field
valgidzi Nov 25, 2018
4644f2e
Fix reserveTrip post request endpoint and params
valgidzi Nov 25, 2018
58a4d69
Reset res form after response
valgidzi Nov 25, 2018
21057b6
Link to bootstrap, move scripts to body
valgidzi Nov 25, 2018
247c7ef
Style load-all-trips button
valgidzi Nov 25, 2018
861ee74
Move trip details and res form to same section
valgidzi Nov 25, 2018
685f4e9
Move detail and form headers to js
valgidzi Nov 25, 2018
e4e7fb2
Remove grid rows
valgidzi Nov 25, 2018
56c21c3
Change visible header text
valgidzi Nov 25, 2018
df33531
Style buttons
valgidzi Nov 25, 2018
7ae7f03
Center form, adjust header sizes
valgidzi Nov 25, 2018
e633f02
Button styling and body spacing
valgidzi Nov 25, 2018
5c504e8
UI feedback and error message format, style, content
valgidzi Nov 25, 2018
5f69bc3
Change res success message, form title
valgidzi Nov 25, 2018
66f678c
Refactor get request functions with callbacks
valgidzi Nov 25, 2018
c2e73b0
Refactor reserveTrip method
valgidzi Nov 26, 2018
99ba418
Condition to check and handle response status 204
valgidzi Nov 26, 2018
8df49ba
Move 204 status handling to noContentError function
valgidzi Nov 26, 2018
8a40dbf
Move .catch error handling to displayError function
valgidzi Nov 26, 2018
0fcfee9
Add form-errors section
valgidzi Nov 26, 2018
1b56f8f
displayFormErrors and capitalize functions
valgidzi Nov 26, 2018
b0bf5f8
Empty form errors section after new click events, change html tags
valgidzi Nov 26, 2018
cce6ef4
appendResForm takes trip object instead of id, add trip name to form …
valgidzi Nov 26, 2018
1db71f6
Add div and scroll overflow for trip-info
valgidzi Nov 27, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions index.css
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;
}
36 changes: 36 additions & 0 deletions index.html
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>
141 changes: 141 additions & 0 deletions index.js
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());
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice helper method!


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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice ternary!

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolons in the above two lines

element.empty();
callback(tripData, element);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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.`)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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}.`)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be a const. I like this line! very readable about what's going on.

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"/>`)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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);
});