diff --git a/.gitignore b/.gitignore index e43b0f98..50b414a7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ .DS_Store +node_modules +.eslintrc.json +package.json +package-lock.json +.vscode \ No newline at end of file diff --git a/images/map-background.jpg b/images/map-background.jpg new file mode 100644 index 00000000..a770f541 Binary files /dev/null and b/images/map-background.jpg differ diff --git a/index.html b/index.html new file mode 100644 index 00000000..5a4999b2 --- /dev/null +++ b/index.html @@ -0,0 +1,55 @@ + + + + + + + TREK + + + + + + + + +
+
+

Trek

+

Plan your next escape.

+
+ +
+
+ + +
+ + + +
+
+ + + \ No newline at end of file diff --git a/trek.css b/trek.css new file mode 100644 index 00000000..40515f20 --- /dev/null +++ b/trek.css @@ -0,0 +1,146 @@ +body { + font-family:"Karla", sans-serif; + background-image: url('images/map-background.jpg'); +} + +header h1, header h2 { + font-family: 'Yesteryear', cursive; + color:darkred; + text-shadow: 2px 2px white; + display:inline-block; + padding: 0 1em 0 1em; +} + +h1 { + font-size:4em; + border-right: 2px solid darkred; +} + +h2 { + font-size:2em; +} + +ul { + padding: 10px; + list-style-type: none; +} +header { + text-align:center; +} + + +article { + + width:80%; + margin:3em auto; + display:grid; + grid-template-rows: 1fr 1fr; + grid-template-columns: 2fr 2fr; +} + +main { + text-align:center; +} + +button, input[type="submit"] { + background-color:darkred; + color:white; + border:white 1px solid; + font-size:1.2em; + padding:10px; +} + +section, aside { + background-color: blanchedalmond; + border-radius: 20px; + padding:20px; + margin:1em; + box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.75); +} + +details { + text-align:justify; + max-height:100px; + overflow-y:scroll; + margin:1em; +} + +section>h3, aside>h3{ + color:darkred; + font-family: 'Yesteryear', cursive; + font-size:2em +} + +#trips-list { + grid-column:1/2; + grid-row:1/3; + margin-right:3em; +} + +#trips-list-container { + height:800px; + overflow-y:scroll; + padding:0; + margin:0; + border-top:solid 4px darkred; + border-bottom:solid 4px darkred; +} +#trip-details { + grid-column:2/3; + grid-row:1/2; + +} + +#reserve-trip { + grid-column:2/3; + grid-row:2/3; +} + +#reserve-trip input{ + margin: 10px 5px; +} + +#reserve-form .field{ + display:block; +} + +.hidden { + visibility:hidden; + display:none; +} + +.centered { + display:block; + margin: 20% auto; + font-size:2em; +} + +#trip-list-header { + margin: 0; + text-align: center; + color:darkred; + font-family: 'Yesteryear', cursive; + background-color:blanchedalmond; +} + + +#cost{ + font-size:2em; + font-weight:bold; + color:darkred; +} + +.selected { + color:white; + background-color:darkolivegreen; + padding:0.5em; +} + +.error { + color:red; +} + +.success { + color:green; +} + diff --git a/trek.js b/trek.js new file mode 100644 index 00000000..cedd6fcf --- /dev/null +++ b/trek.js @@ -0,0 +1,131 @@ +const listErrors = (errors) => { + let errorList = ''; + return errorList; +}; + +const showMessage = (elementID, status) => { + $(elementID).addClass(status); + $(elementID).removeClass('hidden'); +}; + +const handleReserveTrip = (tripID, continent) => { + const endpoint = `https://trektravel.herokuapp.com/trips/${tripID}/reservations`; + const name = $('#name-field').val(); + const email = $('#email-field').val(); + + axios.post(endpoint, { name, email,}) + .then((response) => { + $('#reserve-form')[0].reset(); + showMessage('#reserve-message','success'); + + const messageHTML = ( + `

Congrats, ${name}, you're going to ${continent}!

` + + `

Your reservation ID is ${response.data.id}.

` + ); + $('#reserve-message').html(messageHTML); + + }) + .catch((error) => { + showMessage('#reserve-message','error'); + $('#reserve-message').html(`

A problem occured: ${error.message}

`); + + if (error.response && error.response.data && error.response.data.errors) { + const errors = error.response.data.errors; + $('#reserve-message').append(listErrors(errors)); + } + }); +}; + +const changeSelected = (tripID) => { + $('.selected').removeClass('selected'); + $(`#trip-${tripID}`).addClass('selected'); +}; + +const displayTripDescription = (tripID) => { + axios.get(`https://trektravel.herokuapp.com/trips/${tripID}`) + .then((response) => { + $('#trip-details').append(`
${response.data.about}
`); + }) + .catch((error) => { + $('#trip-details').append(`

Failed to load trip details: ${error.message}

`); + }); +}; + +const displayReservationForm = (tripName) => { + $('#reserve-heading').text(`Reserve a Spot on ${tripName}`); + $('#reserve-message').empty(); + $('#reserve-trip').removeClass('hidden'); +}; + +const setReservationButtonHandler = (tripID, continent) => { + $('#reserve-button').off(); + $('#reserve-button').click((event) => { + event.preventDefault(); + handleReserveTrip(tripID, continent); + }); +}; + +const displayTripDetails = (trip) => { + const tripDetails = ( + `

${trip.name}

` + + `

Continent: ${trip.continent}

` + + `

Category: ${trip.category[0].toUpperCase() + trip.category.slice(1)}

` + + `

${trip.weeks} ${(trip.weeks === 1) ? 'week' : 'weeks'}

` + + `

$${trip.cost.toFixed(2)}

` + ); + $('#trip-details').removeClass('hidden'); + $('#trip-details').html(tripDetails); +}; +const buildTripClickHandler = (trip) => { + + const handler = () => { + changeSelected(trip.id); + displayTripDetails(trip); + displayTripDescription(trip.id); + displayReservationForm(trip.name); + setReservationButtonHandler(trip.id, trip.continent); + }; + return handler; +}; + +const moveButton = ()=>{ + $('#main-button').removeClass('centered'); + $('#main-button').text('Reload Trips'); +}; +const loadTrips = (tripData) => { + $('.selected').removeClass('selected'); + $('#trips-list').removeClass('hidden'); + $('#reserve-trip, #trip-details').addClass('hidden'); + $('#trip-details, #trips-list-container').empty(); + + for (const trip of tripData) { + $('#trips-list-container').append(`
  • ${trip.name}

  • `); + const handleTripClick = buildTripClickHandler(trip); + $(`#trip-${trip.id}`).click(() => { handleTripClick(); }); + } +}; + +const handleMainButtonClick = () => { + axios.get('https://trektravel.herokuapp.com/trips') + .then((response) => { + $('#status-message').empty(); + $('#status-message').addClass('hidden'); + moveButton(); + loadTrips(response.data); + }) + .catch((error) => { + $('#status-message').html(`Could not load trips: ${error.message}`); + showMessage('#status-message', error); + }); +}; + +$('document').ready(() => { + $('#main-button').click(() => { handleMainButtonClick(); }); + $('#reserve-button').click(() => { handleReserveTrip(); }); +});