https://github.com/marrcelp/demonstrating-api-integration-with-excursion-booking-app
A travel booking app that demonstrates API integration by fetching and managing excursion data 🌍✈️. Users can browse trips, place orders, and administrators can manage the excursions via a simple admin panel 🛒👨💻
https://github.com/marrcelp/demonstrating-api-integration-with-excursion-booking-app
api css fetch fetch-api html javascript rest-api
Last synced: about 1 year ago
JSON representation
A travel booking app that demonstrates API integration by fetching and managing excursion data 🌍✈️. Users can browse trips, place orders, and administrators can manage the excursions via a simple admin panel 🛒👨💻
- Host: GitHub
- URL: https://github.com/marrcelp/demonstrating-api-integration-with-excursion-booking-app
- Owner: marrcelp
- Created: 2025-03-26T21:14:02.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2025-03-26T21:25:29.000Z (about 1 year ago)
- Last Synced: 2025-03-26T22:28:14.509Z (about 1 year ago)
- Topics: api, css, fetch, fetch-api, html, javascript, rest-api
- Language: JavaScript
- Homepage: https://marrcelp.github.io/Demonstrating-API-Integration-with-Excursion-Booking-App/
- Size: 5.57 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README

# Find your perfect trip
See the live version of this project - [Find your perfect trip](https://marrcelp.github.io/Demonstrating-API-Integration-with-Excursion-Booking-App/).
The goal of this project is to showcase my understanding of REST API through an application that allows users to find the perfect weekend excursion. The excursion data is fetched from a fake API and displayed on the main page. Each trip includes a detailed description, as well as pricing for both adults and children.
Users can place an order by selecting the number of participants (adults and children), adding excursions to the cart, and then providing their contact information – name, surname, and email address. The submitted order, along with the entered details, is sent to the API, where the administrator can view all received orders.
The project also includes an admin panel that allows managing excursions – adding new ones and editing existing entries.
**Main features**:
- Displaying available excursions to the user by fetching data from the API (http://localhost:3000/excursions) – managing the excursion list.
- Allowing users to place an order by adding excursions to the cart and filling out all required, validated fields. The submitted order is then sent to the API (http://localhost:3000/orders) – managing orders.
- An admin panel that allows adding and editing excursions.
## 💡 Technologies




## 🔗 See also
Are you interested in **RWD** and **CSS**? See my other project [Responsive Layout Showcase](https://github.com/marrcelp/RWD_project-html-css).
## 💿 Installation
The project uses [npm](https://www.npmjs.com/). To install it, type into the terminal: `npm install`. To run the project, use the command: `npm start`. Start the fake API using json-server: `json-server --watch ./data/excursions.json`.
If you want to launch the client version, simply open http://localhost:8080/index.html in your browser.
The admin panel is available at: http://localhost:8080/admin.html.
## 🤔 Solutions provided in the project
- Fetching data from API:
To load excursions, I used the Fetch API to request data from a fake server and display it dynamically on the webpage.
The API requests are handled in the ExcursionsAPI class, ensuring a separation of concerns and making the code more modular and easier to maintain.
```
fetch(this.apiExcursions)
.then(resp => resp.json())
.then(data => { renderExcursions(data); })
.catch(err => console.error(err));
```
- Handling the cart system:
A cart system was implemented to allow users to add excursions to the cart, specify the number of adults and children, and calculate the total price.
The data is stored in an array (basket) and dynamically updated in the UI.
```
basket.push({
"id": excursion.id,
"city": excursion.city,
"priceForAdult": excursion.priceForAdult,
"priceForChild": excursion.priceForChild,
"adults": tripAdults,
"children": tripChildren
});
```
- Admin Panel for CRUD Operations:
The admin panel allows adding, editing, and deleting excursions. Data is sent and updated via POST and PUT methods, and all excursions are reloaded after any change to ensure the UI is updated.
```
fetch(this.apiExcursions, {
method: 'POST',
body: JSON.stringify(data),
headers: { 'Content-Type': 'application/json' }
});
```
| Issue | Solution | Example Code |
| ------------------------- | ----------------------------- | --- |
| Fetching and handling API data | Using the Fetch API for asynchronous data fetching | `fetch(url).then(resp => resp.json())` |
| Adding and updating the cart | Dynamically updating the cart with user input | `basket.push({ id, city, priceForAdult, adults, children })` |
| Admin panel functionality | Providing CRUD operations with real-time UI updates | `fetch(this.apiExcursions, { method: 'POST' })` |
- Client-side form validation:
I implemented basic client-side validation for the order form to ensure the user fills out all required fields before submitting. If validation fails, the user is alerted with the specific error.
```
if (required && value.length === 0) {
alert(`Field ${label} is required!`);
}
```
- Cloning prototype HTML elements:
To dynamically generate excursion list items and summary entries, I used a hidden HTML prototype element (with a --prototype class). This element is cloned, updated with specific data, and then appended to the DOM. This approach simplifies rendering, keeps the UI consistent, and avoids manually creating elements in JavaScript.
```
const liElCopy = liElement.cloneNode(true);
liElCopy.classList.remove('excursions__item--prototype');
tripTitle.textContent = excursion.city;
ulElement.appendChild(liElCopy);
```
## 💭 Conclusions for future projects
I would like to improve:
#### Handling API Errors More Gracefully:
Currently, errors from the API are logged in the console, but it would be better to display user-friendly error messages directly in the UI to guide users in case of issues like server downtime.
```
.catch(err => alert('There was an error fetching the data. Please try again later.'));
```
#### Optimizing State Management:
While the current approach of managing the cart system works, it would be beneficial to look into more advanced state management techniques such as Redux or React Context to improve scalability and maintainability of the application.
## 🙋♂️ Feel free to contact me
Write sth nice ;) Find me on:
[](https://www.linkedin.com/in/marcel-piaszczyk-200ba8181/)
[](mailto:marcel.piaszczyk@gmail.com)
## 👏 Special thanks
Thanks to my [Mentor - devmentor.pl](https://devmentor.pl/) – for providing me with this task and for code review.