Skip to content
89 changes: 89 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Get Outta Here</title>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/css/foundation.min.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main>
<header>
<h1>Trek</h1>
</header>

<button class="hollow button" id="trips-button">See All Trips</button>
<!-- <button class="hollow button" id="create-trip-button">Create a Trip</button> -->
<p class="status-message"></p>

<section class="data grid-container">
<section class="all-trips display-none">
<h2>All Trips</h2>
<div id="trip-list"></div>
</section>

<aside class="trip-details">
<section class="details display-none" id="details"></section>

<section class="reserve-form display-none" id="reserve">
<h2>Reserve Trip</h2>
<form id="reserve-form">
<div class="grid-container">
<label for="name">Your Name:</label>
<input type="text" name="name" />
</div>
<div class="grid-container">
<label for="email">Your Email:</label>
<input type="email" name="email" />
</div>
<div id="trip-reservation-num"></div>
<div class="reserve">
<input class="hollow button" type="submit" name="reserve" value="Reserve" />
</div>
</form>
</section>
<p id="reservation-status"></p>

<section class="trip-creation display-none">
<h2>Create New Trip</h2>
<form id="new-trip-form">
<div class="grid-container">
<label for="name">Trip Name:</label>
<input type="text" name="name" />
</div>
<div class="grid-container">
<label for="continent">Continent:</label>
<input type="text" name="continent" />
</div>
<div class="grid-container">
<label for="category">Category:</label>
<input type="text" name="category" />
</div>
<div class="grid-container">
<label for="weeks">Weeks:</label>
<input type="text" name="weeks" />
</div>
<div class="grid-container">
<label for="cost">Cost:</label>
<input type="text" name="cost" />
</div>
<div class="grid-container">
<label for="about">About:</label>
<textarea name="about" rows="8" cols="80"></textarea>
</div>
<div class="create">
<input class="hollow button" type="submit" name="create" value="Create" />
</div>
</form>
</section>
<p id="creation-status"></p>
</aside>
</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>
205 changes: 205 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
// Constant API url
const URL = 'https://ada-backtrek-api.herokuapp.com/trips'

// Status Message Handling
const reportStatus = (message) => {
$('.status-message').html(message)
}

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

// Load All Trips
const loadTrips = (event) => {
$('.all-trips').removeClass('display-none');

const tripList = $('#trip-list');
tripList.empty(); // empty out the list each time so there aren't duplilcates

reportStatus('Loading trips! Please wait...')

axios.get(URL) // returns a promise
.then((response) => {
response.data.forEach((trip) => {
tripList.append(`<p id="${trip.id}">${trip.name}</p>`);
});
reportStatus('Trips loaded!')
})
.catch((error) => {
reportStatus(`${error.message}`)
});
}

// Load Trip Details
const loadDetails = function(event) {
const tripDetails = $('#details');
const tripResNum = $('#trip-reservation-num')
tripDetails.empty();
tripResNum.empty();

let trip = event.target.id

$('.trip-creation').removeClass('display-none');
$('.details').removeClass('display-none');
$('.reserve-form').removeClass('display-none');

$('input').removeClass('highlight') // removes and previous error outlining from form

$('#reservation-status').html('');
$('#reservation-status').removeClass('status-message'); // removes previous reservation status if new trip selected

reportStatus('Loading trip details! Please wait...')

axios.get(`${URL}\\${trip}`) // returns a promise
.then((response) => {
let tripData = response.data
tripDetails.append(
`<h2>Trip Details</h2>
<h3>Name: ${tripData.name}</h3>
<p>Continent: ${tripData.continent}</p>
<p>Category: ${tripData.category}</p>
<p>Weeks: ${tripData.weeks}</p>
<p>Cost: ${tripData.cost}</p>
<p>About: <br/> ${tripData.about}</p>`);

tripResNum.append(
`<p id="${tripData.id}">${tripData.name}</p>`
);

reportStatus('Trip details loaded!')
})

.catch((error) => {
console.log(error);
reportStatus(`${error.message}`)
});

}

// Reserve Trip
const FORM_FIELDS = ['name', 'email'];
const inputField = name => $(`#reserve-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('');
});
}

const reserveTrip = (event) => {
event.preventDefault();

$('p:first-of-type').removeClass('status-message');
$('#reservation-status').addClass('status-message');

const tripID = $('#trip-reservation-num p').attr('id');
const tripData = readFormData();

reportStatus('Making reservation...');

axios.post(`${URL}\\${tripID}\\reservations`, tripData)
.then((response) => {
$('input').removeClass('highlight')
reportStatus(`Successfully made a reservation!`);
clearForm();
})
.catch((error) => {
console.log(error.response);

$('#reserve-form input').addClass('highlight')

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

// Create Trip
const CREATE_FORM_FIELDS = ['name', 'continent', 'category', 'weeks', 'cost' ];
const createInputField = name => $(`#new-trip-form input[name="${name}"]`);

const readCreateFormData = () => {
const getCreateInput = name => {
const inputCreateForm = createInputField(name).val();
return inputCreateForm ? inputCreateForm : undefined;
};

const createFormData = {};
CREATE_FORM_FIELDS.forEach((field) => {
createFormData[field] = getCreateInput(field);
});

return createFormData;
}

const createClearForm = () => {

Choose a reason for hiding this comment

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

Seems to be an unused function

$(`#new-trip-form textarea"]`).val(''); // clears textarea value
CREATE_FORM_FIELDS.forEach((field) => {
inputField(field).val('');
});
}

const createTrip = (event) => {
event.preventDefault();

$('p:first-of-type').removeClass('status-message');
$('#reservation-status').removeClass('status-message');
$('#creation-status').addClass('status-message');

const createTripData = readCreateFormData();
reportStatus('Creating a trip...');

axios.post(URL, createTripData)
.then((response) => {
$('input').removeClass('highlight')
reportStatus(`Successfully made a new trip!`);
clearForm();
})
.catch((error) => {
console.log(error.response);

$('#new-trip-form input').addClass('highlight')

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(() => {
$('#trips-button').click(loadTrips);
$('#trip-list').on('click', 'p', loadDetails);
$('#reserve-form').submit(reserveTrip);
$('#new-trip-form').submit(createTrip);
});
54 changes: 54 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
header {
border-bottom: 1px solid;
}

h1, h2 {
padding-left: 5%;
}

h2, .all-trips p, .details p {
border-bottom: 1px solid;
}

h3, p, .reserve, .create {
text-align: center;
}

p:last-of-type {
border-bottom: none;
}

.display-none, span {
display: none;
}

.grid-container {
display: grid;
grid-gap: 20px;
grid-template-columns: auto auto;
}

.details, .reserve-form, .all-trips {
border: 1px solid;
margin-bottom: 3rem;
}

.details p {
text-align: left;
font-weight: bold;
padding: 0 10px;
}

.highlight {
border: 2px solid red;
}

.button {
margin: 2.5%;
border-radius: 5px;
}

#trip-reservation-num p {
font-size: 2rem;
margin-bottom: 0;
}