diff --git a/package-lock.json b/package-lock.json index 8197e6f22..94217b93a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "react-hotel", "version": "0.1.0", "dependencies": { + "moment": "^2.29.4", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "^5.0.1" @@ -11681,6 +11682,14 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "engines": { + "node": "*" + } + }, "node_modules/mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", diff --git a/package.json b/package.json index e3e1562a7..f81c28013 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { + "moment": "^2.29.4", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "^5.0.1" diff --git a/src/App.js b/src/App.js index 953c98560..191027226 100644 --- a/src/App.js +++ b/src/App.js @@ -1,13 +1,28 @@ import React from "react"; - +import TouristInfoCards from "./TouristInfoCards"; import Bookings from "./Bookings"; +import Restaurant from "./Restaurant" +import Bookings2 from "./Bookings2"; +import Footer from "./Footer"; import "./App.css"; const App = () => { + const address = [ + "123 Fake Street, London, E1 4UD", + "hello@fakehotel.com", + "0123 456789", + ]; + return (
CYF Hotel
+ +
+

Hotel Management System

+ +
+
); }; diff --git a/src/BookingTable.jsx b/src/BookingTable.jsx new file mode 100644 index 000000000..dabd7dbe4 --- /dev/null +++ b/src/BookingTable.jsx @@ -0,0 +1,45 @@ +import React from 'react'; +import moment from 'moment'; + +const BookingTable = ({bookings}) => { + return ( + + + + + + + + + + + + + + + + + {bookings.map((booking) => { + const checkInDate = moment(booking.checkInDate); + const checkOutDate = moment(booking.checkOutDate); + const nights = checkOutDate.diff(checkInDate, 'days'); + return ( + + + + + + + + + + + ); +})}; + +
IDTitleFirst NameSurnameEmailRoom IDCheck In DateCheck Out DateNights
{booking.id}{booking.title}{booking.firstName}{booking.surname}{booking.email}{booking.roomId}{booking.checkInDate}{booking.checkOutDate}{nights}
+ ); +}; + +export default BookingTable; + diff --git a/src/Bookings.js b/src/Bookings.js index e0d911b13..afd4e82ef 100644 --- a/src/Bookings.js +++ b/src/Bookings.js @@ -1,18 +1,45 @@ -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 "./SearchResults.jsx"; +import FakeBookings from "./data/fakeBookings.json"; +import SearchButton from "./SearchButton.jsx"; const Bookings = () => { - const search = searchVal => { - console.info("TO DO!", searchVal); + const [bookings, setBookings] = useState(FakeBookings); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + + const search = (searchVal) => { + setIsLoading (true); + setError(null); + setTimeout(() => { + fetch(`https://cyf-react.glitch.me/customers/${searchVal}`) + .then((response) => response.json()) + .then((data) => { + setIsLoading(false); + setBookings(data); + }) + .catch((error) => { + setIsLoading(false); + setError(error.message); + }); + }, 5000); }; return (
- {/* */} + {isLoading ? ( +

Loading data...

+ ) : error ? ( +

Error: {error}

+ ) : ( + <> + + + + )}
); diff --git a/src/Bookings2.jsx b/src/Bookings2.jsx new file mode 100644 index 000000000..0e479cc2f --- /dev/null +++ b/src/Bookings2.jsx @@ -0,0 +1,28 @@ +import React, {useEffect, useState} from 'react'; +import BookingTable from './BookingTable'; +// import bookingsData from './data/fakeBookings.json'; + +const Bookings2 = () => { + const [bookings, setBookings] = useState([]); + + useEffect(() => { + fetch('https://cyf-react.glitch.me') + .then (response => response.json()) + .then (data => {setBookings(data); + }) + .catch(error => { + console.error('Error fetching bookings:', error); + }); + }, []); + + return ( +
+

CYF Hotel Bookings

+ +
+ ); +}; + + + +export default Bookings2; \ No newline at end of file diff --git a/src/CustomerProfile.jsx b/src/CustomerProfile.jsx new file mode 100644 index 000000000..742deee76 --- /dev/null +++ b/src/CustomerProfile.jsx @@ -0,0 +1,33 @@ + +import React, {useState, useEffect} from "react"; + +const CustomerProfile = ({ id }) => { + const [customerData, setCustomerData] = useState(null); + +useEffect(() => { + if (id) { + fetch(`https://cyf-react.glitch.me/customers/${id}`) + .then((response) => response.json()) + .then((data) => setCustomerData(data)); + } + }, [id]); + + return ( +
+ {customerData ? ( +
+

Customer Profile: {id}

+ +
+ ) : ( +

Loading customer profile...

+ )} +
+ ); +}; + +export default CustomerProfile; \ No newline at end of file diff --git a/src/Footer.jsx b/src/Footer.jsx new file mode 100644 index 000000000..5b44b4bff --- /dev/null +++ b/src/Footer.jsx @@ -0,0 +1,15 @@ +import React from "react"; + +const Footer = ({ address }) => { + return ( + + ); +}; + +export default Footer; \ No newline at end of file diff --git a/src/Header.jsx b/src/Header.jsx new file mode 100644 index 000000000..85ec23ffd --- /dev/null +++ b/src/Header.jsx @@ -0,0 +1,14 @@ +import React from "react"; + +const Header = () => { + return ( +
+
+

Search Bookings

+ image of Rome +
+
+ ); + }; + +export default Header; \ No newline at end of file diff --git a/src/Order.jsx b/src/Order.jsx new file mode 100644 index 000000000..0ea58eed4 --- /dev/null +++ b/src/Order.jsx @@ -0,0 +1,20 @@ +import React, {useState} from "react"; +import RestaurantButton from "./RestaurantButton"; + +const Order = ({orderType}) => { +const [orders, setOrders] = useState(0); + + const orderOne = () => { + setOrders(orders + 1); + } + return ( +
+ + {orderType} + +
+ ); +}; + + export default Order; + diff --git a/src/Restaurant.js b/src/Restaurant.js deleted file mode 100644 index ecb2b43a2..000000000 --- a/src/Restaurant.js +++ /dev/null @@ -1,17 +0,0 @@ -import React from "react"; - -const Restaurant = () => { - const pizzas = 0; - return ( -
-

Restaurant Orders

- -
- ); -}; - -export default Restaurant; diff --git a/src/Restaurant.jsx b/src/Restaurant.jsx new file mode 100644 index 000000000..5749323d5 --- /dev/null +++ b/src/Restaurant.jsx @@ -0,0 +1,23 @@ +import React from "react"; +import Order from "./Order"; + +const Restaurant = () => { + return ( +
+

Restaurant Orders

+ +
+ ); +}; + + export default Restaurant; \ No newline at end of file diff --git a/src/RestaurantButton.jsx b/src/RestaurantButton.jsx new file mode 100644 index 000000000..42d80a962 --- /dev/null +++ b/src/RestaurantButton.jsx @@ -0,0 +1,11 @@ +import React from "react"; + +const RestaurantButton = ({ handleClick }) => { + return ( + + ); +}; + +export default RestaurantButton; \ No newline at end of file diff --git a/src/Search.js b/src/Search.js index 7bd5871c0..d58de504e 100644 --- a/src/Search.js +++ b/src/Search.js @@ -1,29 +1,36 @@ -import React from "react"; +import React, { useState } from "react"; +import SearchButton from "./SearchButton"; +import Header from "./Header"; + + const Search = () => { + const [searchInput, setSearchInput] = useState(""); + + function handleSearchInput(event) { + const inputValue = event.target.value; + setSearchInput(inputValue); + console.log(inputValue); + + const handleSubmit = (event) => { + event.preventDefault(); + search(searchInput); + }; + return ( -
-
-

Search Bookings

-
+
+ < Header/>
-
- - -
+ < SearchButton/>
-
+
); }; +}; export default Search; diff --git a/src/SearchButton.jsx b/src/SearchButton.jsx new file mode 100644 index 000000000..07efd0290 --- /dev/null +++ b/src/SearchButton.jsx @@ -0,0 +1,16 @@ +import React from "react"; + +const SearchButton = () => { + return (
+ + +
+ ); +} + +export default SearchButton; \ No newline at end of file diff --git a/src/SearchResults.jsx b/src/SearchResults.jsx new file mode 100644 index 000000000..cf2acfc11 --- /dev/null +++ b/src/SearchResults.jsx @@ -0,0 +1,62 @@ +import React, {useState} from "react"; +import CustomerProfile from "./CustomerProfile"; + +const BookingRow = ({ booking }) => { + const { id, title, firstName, surname, email, roomId, checkInDate, checkOutDate } = booking; +const [selected, setSelected] = useState(false); + +const handleRowClick = () => { + setSelected(!selected); +}; + +const rowClassName = selected ? "selected" : ""; + + return ( + + {id} + {title} + {firstName} + {surname} + {email} + {roomId} + {checkInDate} + {checkOutDate} + + + ); +}; +const SearchResults = ({ results }) => { + const [selectedCustomerId, setSelectedCustomerId] = useState(null); + + const handleShowProfile = (customerId) => { + setSelectedCustomerId(customerId); + }; + + + return ( +
+ + + + + + + + + + + + + + + {results.map(booking => ( + + ))} + +
IDTitleFirst NameSurnameEmailRoom IDCheck-in DateCheck-out Date
+ +
+ ); +}; + +export default SearchResults; \ No newline at end of file diff --git a/src/TouristInfoCards.jsx b/src/TouristInfoCards.jsx new file mode 100644 index 000000000..bf6358fe3 --- /dev/null +++ b/src/TouristInfoCards.jsx @@ -0,0 +1,37 @@ +import React from "react"; + +const TouristInfoCards = () => { + return ( +
+
+ Glasgow +
+ Go somewhere +

Glasgow

+

Experience the vibrant cultural scene and architectural beauty of Glasgow.

+ Visit Glasgow +
+
+
+ Manchester +
+ Go somewhere +

Manchester

+

Discover the rich history, music, and sports culture of Manchester.

+ Visit Manchester +
+
+
+ London +
+ Go somewhere +

London

+

Explore the iconic landmarks, world-class museums, and diverse attractions of London.

+ Visit London +
+
+
+ ); +}; + +export default TouristInfoCards; \ No newline at end of file diff --git a/src/data/fakeBookings.json b/src/data/fakeBookings.json index 2997792ea..fe51488c7 100644 --- a/src/data/fakeBookings.json +++ b/src/data/fakeBookings.json @@ -1,52 +1 @@ -[ - { - "id": 1, - "title": "Mr", - "firstName": "John", - "surname": "Doe", - "email": "johndoe@doe.com", - "roomId": 2, - "checkInDate": "2017-11-21", - "checkOutDate": "2017-11-23" - }, - { - "id": 2, - "title": "Doctor", - "firstName": "Sadia", - "surname": "Begum", - "email": "begum_sadia@sadia.org", - "roomId": 1, - "checkInDate": "2018-02-15", - "checkOutDate": "2018-02-28" - }, - { - "id": 3, - "title": "Prince", - "firstName": "Henry", - "surname": "Wales", - "email": "harry@wales.com", - "roomId": 5, - "checkInDate": "2018-03-01", - "checkOutDate": "2018-04-09" - }, - { - "id": 4, - "title": "Dame", - "firstName": "Judi", - "surname": "Dench", - "email": "Judi@dench.co.uk", - "roomId": 6, - "checkInDate": "2017-12-25", - "checkOutDate": "2018-01-03" - }, - { - "id": 5, - "title": "Madam", - "firstName": "Anuradha", - "surname": "Selvam", - "email": "anu@selvam.net", - "roomId": 3, - "checkInDate": "2017-08-30", - "checkOutDate": "2017-10-02" - } -] +[] diff --git a/src/index.css b/src/index.css index 4607bb217..6b06d7dc0 100644 --- a/src/index.css +++ b/src/index.css @@ -3,6 +3,11 @@ body { padding: 0; font-family: sans-serif; } +.card-body { + display:inline; + grid-template-columns: repeat(1, 3fr); + grid-gap: 40px; +} .search-wrapper { border-top: 1px solid #e9ecef; @@ -24,3 +29,13 @@ body { .search-row input { margin-right: 10px; } + +.imageOfRome { + width: 400px; + height: auto; +} + +.selected { + background-color: rgb(65, 155, 207); + color: black; +} \ No newline at end of file