Skip to content
This repository was archived by the owner on Feb 9, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5f3d928
1. Extract the search button in its own component
nsaimk Jul 4, 2023
7d3a582
2. Extract the header in its own component
nsaimk Jul 4, 2023
326d851
Necessary changes for style
nsaimk Jul 4, 2023
304855e
3. Create and use a new component to show info cards
nsaimk Jul 4, 2023
c2f9714
4. Create a Footer component
nsaimk Jul 4, 2023
476fb2e
5. Create a table to show hotel bookings
nsaimk Jul 4, 2023
636f5dd
6. Show more bookings in the table
nsaimk Jul 4, 2023
f2b13f1
7. Calculate and show the number of nights for each booking
nsaimk Jul 4, 2023
b78a169
8. Render the Restaurant component
nsaimk Jul 4, 2023
ae42da8
9. Preparing to add more pizzas
nsaimk Jul 4, 2023
49dbb78
10. Add more pizzas
nsaimk Jul 4, 2023
c65a0fa
11. Extract the Add button to its own component
nsaimk Jul 5, 2023
7c03349
12. Extract pizza order to its own Order component
nsaimk Jul 5, 2023
d8988f6
13. Render more orders
nsaimk Jul 5, 2023
3c7ae05
14. Passing bookings from a state variable
nsaimk Jul 5, 2023
3d07d04
MISSING - 15
nsaimk Jul 5, 2023
34d6f5f
16. Load bookings remotely
nsaimk Jul 6, 2023
31b18d8
17. Storing the search input in a state
nsaimk Jul 6, 2023
43302d1
18. Triggering search when submitting the form
nsaimk Jul 6, 2023
a218a15
19. Implementing the search functionality
nsaimk Jul 6, 2023
4792827
20. Display a customer profile - step 1
nsaimk Jul 6, 2023
1e9f8d6
21. Display a customer profile - step 2
nsaimk Jul 7, 2023
b40ef44
22. Show a loading message
nsaimk Jul 11, 2023
e5d80c8
23. Show an error message
nsaimk Jul 11, 2023
710c624
24. Create a new booking
nsaimk Jul 11, 2023
b581ec0
fetch url is updated, gets from vercel instead of glitch
nsaimk Feb 12, 2024
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
Binary file removed InfoCard.png
Binary file not shown.
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
"name": "react-hotel",
"version": "0.1.0",
"private": true,
"proxy": "https://hotel-db-zeta.vercel.app",
"dependencies": {
"moment": "^2.29.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "^5.0.1"
Expand Down
63 changes: 63 additions & 0 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,66 @@ tr {
.card {
width: 18rem;
}

/* My changes */

.App-header img{
width: 25px;
}

table{
border-bottom: 1px solid rgb(194, 194, 195);
}

.new-booking{
border: 0.5px solid rgb(184, 183, 183);
padding: 25px;
}
.new-booking button{
background-color: rgb(215, 213, 74);
}
.highlighted0{

Choose a reason for hiding this comment

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

What elements are using these classes? if the styles are the same, one css class is enough.

if you want to style particular item in a list of item, you can try below class
li:nth-child(odd) // item with odd index
li:nth-child(even) // item with even indexx
li:nth-child(2) // All

  • elements that are second child of their parent

    https://www.dofactory.com/css/ref/selectors

  • background-color: red;
    }
    .highlighted1{
    background-color: red;
    }
    .highlighted2{
    background-color: rgb(64, 0, 255);
    }
    .highlighted3{
    background-color: red;
    }
    .highlighted4{
    background-color: red;
    }
    .highlighted5{
    background-color: red;
    }
    .highlighted6{
    background-color: red;
    }
    .highlighted7{
    background-color: red;
    }
    .highlighted8{
    background-color: red;
    }
    .highlighted9{
    background-color: red;
    }
    .highlighted10{
    background-color: red;
    }
    .highlighted{
    background-color: red;
    }
    .highlighted{
    background-color: red;
    }
    .highlighted{
    background-color: red;
    }
    .highlighted{
    background-color: red;
    }
    14 changes: 13 additions & 1 deletion src/App.js
    Original file line number Diff line number Diff line change
    Expand Up @@ -2,12 +2,24 @@ import React from "react";

    import Bookings from "./Bookings";
    import "./App.css";
    import Heading from "./components/Heading";
    import TouristInfoCards from "./components/TouristInfoCards";
    import Footer from "./components/Footer";
    import Restaurant from "./Restaurant"

    const App = () => {
    const footerInfo = [
    "123 Fake Street, London, E1 4UD",
    "hello@fakehotel.com",
    "0123 456789",
    ];
    return (
    <div className="App">
    <header className="App-header">CYF Hotel</header>
    <Heading />
    <TouristInfoCards />
    <Bookings />
    <Restaurant />
    <Footer footerInfo={footerInfo} />
    </div>
    );
    };
    Expand Down
    106 changes: 101 additions & 5 deletions src/Bookings.js
    Original file line number Diff line number Diff line change
    @@ -1,18 +1,114 @@
    import React from "react";
    import React, { useState, useEffect } from "react";
    import Search from "./Search.js";
    // import SearchResults from "./SearchResults.js";
    // import FakeBookings from "./data/fakeBookings.json";
    import SearchResults from "./components/SearchResults.jsx";

    const Bookings = () => {
    const search = searchVal => {
    const [bookings, setBookings] = useState([]);
    const [error, setError] = useState(null);
    const [newBooking, setNewBooking] = useState({
    title: "",
    firstName: "",
    surname: "",
    email: "",
    roomId: "",
    checkInDate: "",
    checkOutDate: "",
    });

    useEffect(() => {
    fetch("https://hotel-db-zeta.vercel.app")
    .then((res) => {
    if (!res.ok) {
    throw new Error("Error fetching bookings data");
    }
    return res.json();
    })
    .then((data) => {
    console.log("data::: ", data)
    setBookings(data);
    })
    .catch((error) => {
    setError(error.message);
    });
    }, []);

    Choose a reason for hiding this comment

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

    Nice use of dependencies array in useEffect


    const search = (searchVal) => {
    console.info("TO DO!", searchVal);
    setBookings(
    bookings.filter((row) => {
    return (
    row.firstName.includes(searchVal) || row.surname.includes(searchVal)
    );
    })
    );
    };


    const handleChange = (e) => {
    setNewBooking({ ...newBooking, [e.target.name]: e.target.value });

    Choose a reason for hiding this comment

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

    A short and clear way to update the booking, Nice one

    };

    const handleSubmit = (e) => {
    e.preventDefault();
    setBookings((bookings) => [...bookings, newBooking]);
    };

    return (
    <div className="App-content">
    <div className="container">
    <Search search={search} />
    {/* <SearchResults results={FakeBookings} /> */}
    {/* {error ? (
    <p className="error-message">{error}</p>
    ) : (
    <SearchResults results={bookings} />
    )} */}
    <SearchResults results={bookings} />
    <form className="new-booking">
    <h4>Add a New Booking</h4>
    <input
    placeholder="Title"
    name="title"
    value={newBooking.title}
    onChange={handleChange}
    ></input>
    <input
    placeholder="First Name"
    name="firstName"
    value={newBooking.firstName}
    onChange={handleChange}
    ></input>
    <input
    placeholder="Surname"
    name="surname"
    value={newBooking.surname}
    onChange={handleChange}
    ></input>
    <input
    placeholder="Email"
    name="email"
    value={newBooking.email}
    onChange={handleChange}
    ></input>
    <input
    placeholder="Room Id"
    name="roomId"
    value={newBooking.roomId}
    onChange={handleChange}
    ></input>
    <input
    placeholder="Check In Date"
    name="checkInDate"
    value={newBooking.checkInDate}
    onChange={handleChange}
    ></input>
    <input
    placeholder="Check Out Date"
    name="checkOutDate"
    value={newBooking.checkOutDate}
    onChange={handleChange}
    ></input>
    <button onClick={handleSubmit}>Submit</button>
    </form>
    </div>
    </div>
    );
    Expand Down
    10 changes: 5 additions & 5 deletions src/Restaurant.js
    Original file line number Diff line number Diff line change
    @@ -1,14 +1,14 @@
    import React from "react";
    import Order from "./components/Order";

    const Restaurant = () => {
    const pizzas = 0;
    return (
    <div>
    <div style={{ marginTop: '120px' }}>
    <h3>Restaurant Orders</h3>
    <ul>
    <li>
    Pizzas: {pizzas} <button className="btn btn-primary">Add</button>
    </li>
    <Order orderType="Pizza" />
    <Order orderType="Kebab" />
    <Order orderType="Baklava" />
    </ul>
    </div>
    );
    Expand Down
    23 changes: 19 additions & 4 deletions src/Search.js
    Original file line number Diff line number Diff line change
    @@ -1,23 +1,38 @@
    import React from "react";
    import React, { useState } from "react";
    import SearchButton from "./components/SearchButton";

    const Search = (props) => {
    const [searchInput, setSearchInput] = useState("");

    const handleSearchInput = (event) => {
    setSearchInput(event.target.value);
    console.log(searchInput);
    };

    const submitHandler = (event) => {
    event.preventDefault();
    props.search(searchInput);
    }

    const Search = () => {
    return (
    <div className="search">
    <div className="page-header">
    <h4 className="text-left">Search Bookings</h4>
    </div>
    <div className="row search-wrapper">
    <div className="col">
    <form className="form-group search-box">
    <form className="form-group search-box" onSubmit={submitHandler}>
    <label htmlFor="customerName">Customer name</label>
    <div className="search-row">
    <input
    type="text"
    id="customerName"
    className="form-control"
    placeholder="Customer name"
    value={searchInput}
    onChange={handleSearchInput}
    />
    <button className="btn btn-primary">Search</button>
    <SearchButton />
    </div>
    </form>
    </div>
    Expand Down
    52 changes: 52 additions & 0 deletions src/components/AddBookingForm.jsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,52 @@
    import React, { useState } from 'react';

    const AddBookingForm = ({ onAddBooking }) => {
    const [newBooking, setNewBooking] = useState({
    title: '',
    firstName: '',
    surname: '',
    email: '',
    roomId: '',
    checkInDate: '',
    checkOutDate: '',
    });

    const handleChange = (e) => {
    setNewBooking({ ...newBooking, [e.target.name]: e.target.value });
    };

    const handleSubmit = async (e) => {
    e.preventDefault();
    try {
    const response = await fetch('http://localhost:3001/bookings', {
    method: 'POST',
    headers: {
    'Content-Type': 'application/json',
    },
    body: JSON.stringify(newBooking),
    });
    const data = await response.json();
    onAddBooking(data); // Update the bookings state with the new data
    setNewBooking({
    title: '',
    firstName: '',
    surname: '',
    email: '',
    roomId: '',
    checkInDate: '',
    checkOutDate: '',
    });
    } catch (error) {
    console.error('Error adding booking:', error);
    }
    };

    return (
    <form className="new-booking" onSubmit={handleSubmit}>
    {/* Input fields for booking data */}
    {/* Submit button */}
    </form>
    );
    };

    export default AddBookingForm;
    27 changes: 27 additions & 0 deletions src/components/CustomerProfile.jsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    import React, { useEffect, useState } from "react";

    const CustomerProfile = ({ id }) => {
    const [customerInfo, setCustomerInfo] = useState("");
    useEffect(() => {
    fetch(`https://hotel-db-zeta.vercel.app/${id}`)
    .then((res) => {
    return res.json();
    })
    .then((data) => {
    console.log(data.rows[0])
    setCustomerInfo(data.rows[0]);
    });
    }, [id]);

    Choose a reason for hiding this comment

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

    Nice one, only the id change will trigger the useEffect

    return (
    <div>
    <h3>Customer {id} profile</h3>
    <ul>
    <li>Customer Email: {customerInfo.email}</li>
    <li>VIP: {customerInfo.vip ? "Yes" : "No"}</li>
    <li>Phone: {customerInfo.phoneNumber}</li>
    </ul>
    </div>
    );
    };

    export default CustomerProfile;
    Loading