Skip to content
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

Ampers: Nora Peters #20

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
68 changes: 68 additions & 0 deletions index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
body {
font-family: 'Roboto', sans-serif;
font-weight: 100;
}

button, .button {
margin: 0.5em;
background: linear-gradient(#F0F0F0, #7C7B7B);
color: #FFFFFF;
border-radius: 5px;
font-size: 0.85em;
padding: 0.8em;
cursor: pointer;
}

.container {
display: grid;
grid-template-columns: 1fr 1fr;
}

.hidden {
display: none;
}

.trip-detail h3 {
text-align: center;
}

.trip-detail-section {
margin-bottom: 0.5em;
}

.trip-detail-section, .reserve-trip{
border: .5px solid black;
padding: 0 1em 1em 1em;
}

.trips, span {
cursor: pointer;
margin-bottom: 1em;
}

.trips li {
padding: 0.5em;
padding-left: 0;
list-style-type: none;
}

#trip-form > div {
margin-bottom: 0.5em;
}

#reserve-trip-button {
margin-top: 1em;
}

.more {
background-color: lightgrey;
}

@media screen and (max-width: 630px) {
.container {
display: flex;
flex-direction: column-reverse;
}

.trips, .trip-detail-section {
}
56 changes: 56 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Trek</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<section id="status-message"></section>
<h1>Trek</h1>
<div>
<h3>Welcome To Trek</h3>
<h4>Your destination for planning a fabulous trip to... another destination.</h4>
</div>
<main>
<section class="buttons">
<button id="load">See ALL Trips</button>
<button id="asia">Asia</button>
<button id="africa">Africa</button>
<button id="antartica">Antartica</button>
<button id="australasia">Australasia</button>
<button id="europe">Europe</button>
<button id="north-amer">North America</button>
<button id="south-amer">South America</button>
</section>
<div class="container">
<div>
<ul class="trips hidden" id="trip-list"></ul>
</div>
<section class="hidden trip-detail">
<h3>Trip Details</h3>
<div id="trip-detail-section" class="trip-detail-section">
</div>
<div class="reserve-trip">
<h3>Reserve Trip</h3>
<form id="trip-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 class="button" type="submit" name="add-trip" value="Reserve Trip" />
</form>
</div>
</section>
</div>
</main>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="index.js"></script>
</body>
</html>
219 changes: 219 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
const URL = 'https://ada-backtrek-api.herokuapp.com/trips/';

// Report helpers
const reportStatus = (message) => {
$('#status-message').html(message);
}

const reportError = (message, errors) => {
let content = `<p>${message}</p><ul>`;
for (const field in errors) {
for (const problem of errors[field]) {
content += `<li>${field}: ${problem}</li>`;
}
}
content += "</ul>";
reportStatus(content);
};

//LOAD all/specific trips based on url params
const getTrips = (url) => {
const tripList = $('#trip-list');
tripList.show();
Copy link

Choose a reason for hiding this comment

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

This is just a random jQuery thing that I'm not too concerned about but: Since you're calling .show() on this element, jQuery actually puts an inline style on this element for style={display: block;} ... which is fine, except that it's awkward since there's a class on this called hidden that never gets removed... so it ends up looking like this:

<ul class="trips hidden" id="trip-list" style="display: block;"> ... </ul>

It's a little awkward to read class="hidden" and at the same time see it on the page because of the inline style.

Like I said, I'm not too worried about this... unless it introduces bugs later (what if you try to select on $('.hidden')?) It might make sense to conform to one style or the other (either removing the class hidden instead of using .show(), or in $(document).ready calling $('#trip-list').hide() right at the beginning

tripList.empty();

reportStatus('Loading trips, please wait...');

axios.get(url)
.then((response) => {
let header = $(`<h4>All Trips</h4>`)
tripList.append(header);

response.data.forEach((trip) => {
let item = $(`<li>${trip.name}</li>`).attr('id', `${trip.id}`);
tripList.append(item);
});

reportStatus(`Successfully loaded ${response.data.length} trips`)
})
.catch((error) => {
console.log(error);
reportStatus(`Error: ${error.message}`);
});
};

// GET ALL TRIPS
const loadTrips = () => {
getTrips(URL)
}
// GET ASIA
const asiaTrips = () => {
let url = (URL + '/continent?query=Asia')
getTrips(url)
}
// GET AFRICA
const africaTrips = () => {
let url = (URL + '/continent?query=Africa')
getTrips(url)
}
// GET Antartica
const antarticaTrips = () => {
let url = (URL + '/continent?query=Antartica')
getTrips(url)
}
// GET Australasia
const australasiaTrips = () => {
let url = (URL + '/continent?query=Australasia')
getTrips(url)
}
// GET EUROPE
const europeTrips = () => {
let url = (URL + '/continent?query=Europe')
getTrips(url)
}
// GET North America
const nAmericaTrips = () => {
let url = (URL + '/continent?query=North%20America')
getTrips(url)
}
// GET South America
const sAmericaTrips = () => {
let url = (URL + '/continent?query=South%20America')
getTrips(url)
}
Copy link

@tildeee tildeee Jun 1, 2018

Choose a reason for hiding this comment

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

These functions all end up feeling very similar! It might make sense to refactor them such that...

const getTripsByContinent = (continentName) => {
  getTrips( encodeURI( URL + '/continent?query=' + continentName ) );
}

Then lines 167-173 could look maybe more like

$('#asia').click( (event) => getTripsByContinent('Asia') );


// GET details for single trip
const getTripDetails = function getTripDetails(id) {

let tripDetail = $('#trip-detail-section');
tripDetail.empty();

axios.get(URL + id)
.then((response) => {
let data = response.data;
let name = $(`<h4><strong>Name:</strong> ${data.name}</h4>`).addClass(`${id}`);
Copy link

Choose a reason for hiding this comment

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

It might make more sense to set the id attr on this element instead of adding a class, because this value represents a unique identifier rather than a styling class?

let about = $(`<span><strong>Description:</strong> ${data.about.slice(0, 150)}</span>`).addClass("teaser");
let aboutFullText = $(`<span>${data.about.slice(150)}</span>`).addClass("moreinfo hidden").attr('id', 'info1');
Copy link

Choose a reason for hiding this comment

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

super neat solution, nice!

let more = $(`<span>...Read more</span>`).addClass("more").attr('target', 1);
let continent = $(`<p><strong>Continent:</strong> ${data.continent}</p>`);
let category = $(`<p><strong>Category:</strong> ${data.category}</p>`);
let weeks = $(`<p><strong>Weeks:</strong> ${data.weeks}</p>`);
let cost = $(`<p><strong>Cost:</strong> $${data.cost}</p>`);

tripDetail.append(name, about, aboutFullText, more, continent, category, weeks, cost);

reportStatus(`Successfully loaded details for ${response.data.name} trip`)
})
.catch((error) => {
console.log(error);
reportStatus(`Error: ${error.message}`);
});
}

// Form helpers
const FORM_FIELDS = ['name', 'email'];
const inputField = name => $(`#trip-form input[name="${name}"]`);

const readFormData = () => {
const getInput = name => {
const input = inputField(name).val();
return input ? input : undefined;
};

const formData = {};
FORM_FIELDS.forEach((field) => {
formData[field] = getInput(field);
});

return formData;
};

const clearForm = () => {
FORM_FIELDS.forEach((field) => {
inputField(field).val('');
});
}

// Reserve spot on trip
const reserveTrip = (event) => {
event.preventDefault();
// let id = Number($('#trip-detail-section h4')[0].classList[0]);
let id = $('.trip-detail-section h4').attr("class");

const tripData = readFormData();

reportStatus('Sending trip reservation data...');

axios.post((`${URL}${id}/reservations`), tripData)
.then((response) => {
clearForm();
reportStatus(`Successfully created trip reservation with ID ${response.data.trip_id}!`);
Copy link

Choose a reason for hiding this comment

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

response.data.trip_id refer to the ID of the trip, not the reservation itself. Funnily enough, the API doesn't give back a response with the reservation ID!

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

$(document).ready(() => {
$('#load').click(loadTrips);
$('#asia').click(asiaTrips);
$('#africa').click(africaTrips);
$('#antartica').click(antarticaTrips);
$('#australasia').click(australasiaTrips);
$('#europe').click(europeTrips);
$('#north-amer').click(nAmericaTrips);
$('#south-amer').click(sAmericaTrips);

$('#trip-list').on('click', 'li', function(event) {
let id = Number(event.target.id);
$("section").removeClass("hidden");
Copy link

Choose a reason for hiding this comment

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

this ends up working, but it might be more specific to use a more specific selector than 'section' since you have more than one section in your HTML

getTripDetails(id);
});

$('#trip-form').submit(reserveTrip);

$(".trip-detail-section").on('click', '.more', function(event) {
$(".moreinfo").removeClass("hidden");
$(".more").addClass("hidden");
});

//Failed attempts at reading input from a drop-down form to select specific continent...
// $('load-by-continent-form').submit(function() {
// console.log($("#load-by-continent-form").val());
// });

// $('#submit').on('click', function() {
// let continent = $( "#load-by-continent" ).val();
// loadTripsByContinent(continent);
// });

// $('#load-by-continent').submit(function() {
// let continent = $( "#load-by-continent" ).val();
// loadTripsByContinent(continent);
// });

//More failed attempts at making a toggle read more/less function
// $('.moreinfo').hide();
// $('.more').click(function (ev) {
// $(".more-info").removeClass("hidden");
// console.log(ev);
// let t = ev.target
// $('#info' + $(this).attr('target')).toggle(500, function(){
// $(t).html($(this).is(':visible')? 'I\'m done reading more' : 'Read more')
// });
// return false;
// });
// $(".more").toggle(function(){
// $(this).text("less..").siblings(".complete").show();
// }, function(){
// $(this).text("more..").siblings(".complete").hide();
// });
});