More progress
This commit is contained in:
parent
3d8c60ee00
commit
de88224b30
19 changed files with 1249 additions and 61 deletions
|
@ -16,6 +16,7 @@ module.exports = {
|
|||
"warn",
|
||||
{ allowConstantExport: true }
|
||||
],
|
||||
"react/prop-types": ["off"]
|
||||
"react/prop-types": ["off"],
|
||||
"no-unused-vars": ["warn"]
|
||||
}
|
||||
}
|
||||
|
|
11
package.json
11
package.json
|
@ -7,15 +7,18 @@
|
|||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
|
||||
"test": "jest",
|
||||
"test": "vitest",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.14.2"
|
||||
"react-router-dom": "6.4.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@types/react": "^18.2.15",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"@vitejs/plugin-react": "^4.0.3",
|
||||
|
@ -23,6 +26,8 @@
|
|||
"eslint-plugin-react": "^7.32.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.3",
|
||||
"vite": "^4.4.5"
|
||||
"jsdom": "^22.1.0",
|
||||
"vite": "^4.4.5",
|
||||
"vitest": "^0.33.0"
|
||||
}
|
||||
}
|
||||
|
|
1094
pnpm-lock.yaml
generated
1094
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
BIN
public/images/Chef2.jpg
Normal file
BIN
public/images/Chef2.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 MiB |
11
src/App.jsx
Normal file
11
src/App.jsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { Footer } from "./components/Footer"
|
||||
import { Header } from "./components/Header"
|
||||
import { Main } from "./components/Main"
|
||||
|
||||
export const App = () => (
|
||||
<>
|
||||
<Header />
|
||||
<Main />
|
||||
<Footer />
|
||||
</>
|
||||
)
|
10
src/App.test.jsx
Normal file
10
src/App.test.jsx
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { render, screen } from "@testing-library/react"
|
||||
import { describe, expect } from "vitest"
|
||||
import { BookingForm } from "./components/BookingForm.jsx"
|
||||
|
||||
describe("Renders the BookingForm heading", () => {
|
||||
const availableTimes = ["17:00"]
|
||||
render(<BookingForm availableTimes={availableTimes} />)
|
||||
const headingElement = screen.getByText("Choose date")
|
||||
expect(headingElement).toBeInTheDocument()
|
||||
})
|
21
src/components/About.jsx
Normal file
21
src/components/About.jsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
import "../styles/About.css"
|
||||
|
||||
export const About = () => (
|
||||
<section className="about row">
|
||||
<article>
|
||||
<h2>Little Lemon</h2>
|
||||
<p>
|
||||
Little Lemon was opened in 1995 by two Italian brothers, Adrian
|
||||
and Mario. The brothers saw the opportunity for a great
|
||||
Mediterranean restaurant, and were inspired to bring the flavors
|
||||
of their hometown in Italy to the people of Chicago. The two
|
||||
brothers continue to oversee the Little Lemon restaurant even
|
||||
now, nearly thirty years later.
|
||||
</p>
|
||||
</article>
|
||||
<section>
|
||||
<img src="/images/Chef.jpg" alt="Mario" />{" "}
|
||||
<img src="/images/Chef2.jpg" alt="Adrian" />
|
||||
</section>
|
||||
</section>
|
||||
)
|
|
@ -1,16 +1,8 @@
|
|||
import { useState } from "react"
|
||||
import "../styles/BookingForm.css"
|
||||
|
||||
export const BookingForm = () => {
|
||||
export const BookingForm = ({ availableTimes, dispatch }) => {
|
||||
const [date, setDate] = useState(new Date().toISOString().slice(0, 10))
|
||||
const [availableTimes] = useState([
|
||||
"17:00",
|
||||
"18:00",
|
||||
"19:00",
|
||||
"20:00",
|
||||
"21:00",
|
||||
"22:00"
|
||||
])
|
||||
const [time, setTime] = useState(availableTimes[0])
|
||||
const [guests, setGuests] = useState(1)
|
||||
const [occasion, setOccasion] = useState("None")
|
||||
|
@ -26,16 +18,21 @@ export const BookingForm = () => {
|
|||
<label htmlFor="res-date">Choose date</label>
|
||||
<input
|
||||
value={date}
|
||||
onChange={(event) => setDate(event.target.value)}
|
||||
required
|
||||
onChange={(event) => {
|
||||
setDate(event.target.value)
|
||||
dispatch(event.target.value)
|
||||
}}
|
||||
type="date"
|
||||
id="res-date"
|
||||
/>
|
||||
|
||||
<label htmlFor="res-time">Choose time</label>
|
||||
<label htmlFor="time">Choose time</label>
|
||||
<select
|
||||
value={time}
|
||||
required
|
||||
onChange={(event) => setTime(event.target.value)}
|
||||
id="res-time"
|
||||
id="time"
|
||||
>
|
||||
{availableTimes.map((time) => (
|
||||
<option key={time}>{time}</option>
|
||||
|
@ -45,6 +42,7 @@ export const BookingForm = () => {
|
|||
<label htmlFor="guests">Number of guests</label>
|
||||
<input
|
||||
type="number"
|
||||
required
|
||||
min="1"
|
||||
max="10"
|
||||
id="guests"
|
||||
|
@ -66,7 +64,7 @@ export const BookingForm = () => {
|
|||
<input
|
||||
type="submit"
|
||||
className="submit"
|
||||
value="Make Your reservation"
|
||||
value="Confirm reservation"
|
||||
/>
|
||||
</form>
|
||||
)
|
||||
|
|
|
@ -9,7 +9,7 @@ export const Footer = () => (
|
|||
<a href="#">Home</a>
|
||||
<a href="#">About</a>
|
||||
<a href="#">Menu</a>
|
||||
<Link to="/book">Reservations</Link>
|
||||
<Link to="/book">Reserve a table</Link>
|
||||
<a href="#">Order Online</a>
|
||||
<a href="#">Login</a>
|
||||
</section>
|
||||
|
|
45
src/components/Main.jsx
Normal file
45
src/components/Main.jsx
Normal file
|
@ -0,0 +1,45 @@
|
|||
import { Route } from "react-router-dom"
|
||||
import { Routes } from "react-router-dom"
|
||||
import { HomePage } from "../routes/HomePage"
|
||||
import { BookingPage } from "../routes/BookingPage"
|
||||
import { useReducer } from "react"
|
||||
|
||||
export const Main = () => {
|
||||
const initializeTimes = () => [
|
||||
"17:00",
|
||||
"18:00",
|
||||
"19:00",
|
||||
"20:00",
|
||||
"21:00",
|
||||
"22:00"
|
||||
]
|
||||
|
||||
const updateTimes = (times, date) => {
|
||||
console.log(times, date)
|
||||
return times
|
||||
}
|
||||
|
||||
const [availableTimes, dispatch] = useReducer(
|
||||
updateTimes,
|
||||
initializeTimes()
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<main>
|
||||
<Routes>
|
||||
<Route index element={<HomePage />} />
|
||||
<Route
|
||||
path="/book"
|
||||
element={
|
||||
<BookingPage
|
||||
availableTimes={availableTimes}
|
||||
dispatch={dispatch}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
}
|
|
@ -7,6 +7,7 @@ const Star = () => (
|
|||
height="24"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 16 16"
|
||||
aria-label="Star"
|
||||
>
|
||||
<path d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z" />
|
||||
</svg>
|
||||
|
|
|
@ -27,10 +27,10 @@ a {
|
|||
|
||||
main {
|
||||
display: flex;
|
||||
margin: auto;
|
||||
color: white;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
hr {
|
||||
|
|
24
src/main.jsx
24
src/main.jsx
|
@ -1,27 +1,13 @@
|
|||
import "./index.css"
|
||||
import React from "react"
|
||||
import ReactDOM from "react-dom/client"
|
||||
import { Root } from "./routes/Root.jsx"
|
||||
import {
|
||||
createBrowserRouter,
|
||||
RouterProvider,
|
||||
Route,
|
||||
createRoutesFromElements
|
||||
} from "react-router-dom"
|
||||
import { HomePage } from "./routes/HomePage"
|
||||
import { BookingPage } from "./routes/BookingPage"
|
||||
|
||||
const router = createBrowserRouter(
|
||||
createRoutesFromElements(
|
||||
<Route path="/" element={<Root />}>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/book" element={<BookingPage />} />
|
||||
</Route>
|
||||
)
|
||||
)
|
||||
import { BrowserRouter } from "react-router-dom"
|
||||
import { App } from "./App"
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
<React.StrictMode>
|
||||
<RouterProvider router={router} />
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</React.StrictMode>
|
||||
)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { BookingForm } from "../components/BookingForm"
|
||||
import "../styles/BookingPage.css"
|
||||
|
||||
export const BookingPage = () => (
|
||||
export const BookingPage = ({ availableTimes, dispatch }) => (
|
||||
<section className="booking">
|
||||
<h1>Book a Table</h1>
|
||||
<hr />
|
||||
<BookingForm />
|
||||
<BookingForm availableTimes={availableTimes} dispatch={dispatch} />
|
||||
</section>
|
||||
)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { About } from "../components/About"
|
||||
import { Jumbo } from "../components/Jumbo"
|
||||
import { Specials } from "../components/Specials"
|
||||
import { Testimonials } from "../components/Testimonials"
|
||||
|
@ -7,5 +8,6 @@ export const HomePage = () => (
|
|||
<Jumbo />
|
||||
<Specials />
|
||||
<Testimonials />
|
||||
<About />
|
||||
</>
|
||||
)
|
||||
|
|
34
src/styles/About.css
Normal file
34
src/styles/About.css
Normal file
|
@ -0,0 +1,34 @@
|
|||
.about {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
color: black;
|
||||
position: relative;
|
||||
height: 18rem;
|
||||
}
|
||||
|
||||
.about h2 {
|
||||
font-size: 3rem;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
color: var(--primary-1);
|
||||
}
|
||||
|
||||
.about article {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.about img {
|
||||
height: 15rem;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.about img:first-child {
|
||||
top: 0;
|
||||
right: 5rem;
|
||||
}
|
||||
|
||||
.about img {
|
||||
top: 2rem;
|
||||
right: 10rem;
|
||||
}
|
|
@ -5,8 +5,9 @@
|
|||
background-color: #495e57;
|
||||
padding: 1rem;
|
||||
border-radius: 1rem;
|
||||
height: 100%;
|
||||
gap: 1rem;
|
||||
width: 70%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.booking h1 {
|
||||
|
|
8
tests/setup.js
Normal file
8
tests/setup.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { expect, afterEach } from "vitest"
|
||||
import { cleanup } from "@testing-library/react"
|
||||
import matchers from "@testing-library/jest-dom/matchers"
|
||||
|
||||
expect.extend(matchers)
|
||||
afterEach(() => {
|
||||
cleanup()
|
||||
})
|
|
@ -1,7 +1,12 @@
|
|||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import { defineConfig } from "vite"
|
||||
import react from "@vitejs/plugin-react"
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
test: {
|
||||
globals: true,
|
||||
environment: "jsdom",
|
||||
setupFiles: "./tests/setup.js"
|
||||
}
|
||||
})
|
||||
|
|
Reference in a new issue