Project overview:
Project shows: Uses functional components in which the parent App() component calls child components, and child components call other nested child components.
– Parent component ‘function App() { calls child<Components /> }’ uses ‘root.render(…)’ in same file
– Child component ‘function Menu() { calls child <component /> }’
– Parent and child components as well as the root.render(…) are in the same index.js file. There are no export or import of components. No App.js file is used.
Code:
<!DOCTYPE html>
<html lang=“en”>
<head>
<meta charset=“utf-8” />
<link rel=“icon” href=“%PUBLIC_URL%/favicon.ico” />
<meta name=“viewport” content=“width=device-width, initial-scale=1” />
<meta name=“theme-color” content=“#000000” />
<meta
name=“description”
content=“Web site created using create-react-app”
/>
<link rel=“apple-touch-icon” href=“%PUBLIC_URL%/logo192.png” />
<!–
manifest.json provides metadata used when your web app is installed on a
user’s mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
–>
<link rel=“manifest” href=“%PUBLIC_URL%/manifest.json” />
<!–
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike “/favicon.ico” or “favicon.ico”, “%PUBLIC_URL%/favicon.ico” will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
–>
<title>Fast React Pizza Co.</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id=“root”></div>
<!–
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
–>
</body>
</html>
import React from “react”;
import ReactDOM from “react-dom/client”;
import “./index.css”;
const pizzaData = [
{
name: “Focaccia”,
ingredients: “Bread with italian olive oil and rosemary”,
price: 6,
photoName: “pizzas/focaccia.jpg”,
soldOut: false,
},
{
name: “Pizza Margherita”,
ingredients: “Tomato and mozarella”,
price: 10,
photoName: “pizzas/margherita.jpg”,
soldOut: false,
},
{
name: “Pizza Spinaci”,
ingredients: “Tomato, mozarella, spinach, and ricotta cheese”,
price: 12,
photoName: “pizzas/spinaci.jpg”,
soldOut: false,
},
{
name: “Pizza Funghi”,
ingredients: “Tomato, mozarella, mushrooms, and onion”,
price: 12,
photoName: “pizzas/funghi.jpg”,
soldOut: false,
},
{
name: “Pizza Salamino”,
ingredients: “Tomato, mozarella, and pepperoni”,
price: 15,
photoName: “pizzas/salamino.jpg”,
soldOut: true,
},
{
name: “Pizza Prosciutto”,
ingredients: “Tomato, mozarella, ham, aragula, and burrata cheese”,
price: 18,
photoName: “pizzas/prosciutto.jpg”,
soldOut: false,
},
];
function App() {
return (
<div className=“container”>
<h1>Hello React!!!!</h1>
<Header />
<Menu />
<Footer />
</div>
);
}
function Header() {
//const style = { color: “red”, fontSize: “48px”, textTransform: “uppercase” };
const style = {};
return (
<header className=“header”>
<h1 style={style}>Fast React Pizza Co.</h1>
</header>
);
}
function Menu() {
const pizzas = pizzaData;
const numPizzas = pizzas.length;
return (
<main className=“menu”>
<h2>Our menu</h2>
{/*<p>
Authentic Italian cuisine. 6 creative dishes to choose from. All from
our stone oven, all organic, all delicious
</p>*/}
{numPizzas > 0 ? (
<>
<p>
Authentic Italian cuisine. 6 creative dishes to choose from. All
from our stone oven, all organic, all delicious
</p>
<ul className=“pizzas”>
{pizzaData.map((pizza) => (
<Pizza pizzaObj={pizza} key={pizza.name} />
))}
</ul>
</>
) : (
<p>We’re still working on our menu. Please come back later :)</p>
)}
{/*<Pizza
name=”Pizza Spinaci”
ingredients=”Tomato, mozarella, spinach, and ricotta cheese”
photoName=”pizzas/spinaci.jpg”
price={10}
/>
<Pizza
name=”Pizza Funghi”
ingredients=”Tomato, mushrooms”
price={12}
photoName=”pizzas/funghi.jpg”
/>*/}
</main>
);
}
function Pizza({ pizzaObj }) {
//if (pizzaObj.soldOut) return null;
return (
<li className={`pizza ${pizzaObj.soldOut ? “sold-out” : “”}`}>
<img src={pizzaObj.photoName} alt={pizzaObj.name} />
<div>
<h3>{pizzaObj.name}</h3>
<p>{pizzaObj.ingredients}</p>
<span>{pizzaObj.soldOut ? “SOLD OUT” : pizzaObj.price}</span>
</div>
</li>
);
}
function Footer() {
const hour = new Date().getHours();
const openHour = 12;
const closeHour = 22;
const isOpen = hour >= openHour && hour <= closeHour;
console.log(isOpen);
//if (hour >= openHour && hour <= closeHour) alert(“we’re currently open!”);
//else alert(“Sorry we’re closed”);
return (
<footer className=“footer”>
{isOpen ? (
<Order closeHour={closeHour} openHour={openHour} />
) : (
<p>
We’re happy to welcome you between {openHour}:00 and {closeHour}:00.
</p>
)}
</footer>
);
//return React.createElement(“footer”, null, “We’re currently open!”);
}
function Order({ closeHour, openHour }) {
return (
<div className=“order”>
<p>
We’re open from {openHour}:00 till {closeHour}:00. Come visit us or
order online.
</p>
<button className=“btn”>Order</button>
</div>
);
}
// React v18
const root = ReactDOM.createRoot(document.getElementById(“root”));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// React before 18
// React.render(<App />, document.getElementBiTd(“root”));
import React from “react”;
import ReactDOM from “react-dom/client”;
import “./index.css”;
const pizzaData = [
{
name: “Focaccia”,
ingredients: “Bread with italian olive oil and rosemary”,
price: 6,
photoName: “pizzas/focaccia.jpg”,
soldOut: false,
},
{
name: “Pizza Margherita”,
ingredients: “Tomato and mozarella”,
price: 10,
photoName: “pizzas/margherita.jpg”,
soldOut: false,
},
{
name: “Pizza Spinaci”,
ingredients: “Tomato, mozarella, spinach, and ricotta cheese”,
price: 12,
photoName: “pizzas/spinaci.jpg”,
soldOut: false,
},
{
name: “Pizza Funghi”,
ingredients: “Tomato, mozarella, mushrooms, and onion”,
price: 12,
photoName: “pizzas/funghi.jpg”,
soldOut: false,
},
{
name: “Pizza Salamino”,
ingredients: “Tomato, mozarella, and pepperoni”,
price: 15,
photoName: “pizzas/salamino.jpg”,
soldOut: true,
},
{
name: “Pizza Prosciutto”,
ingredients: “Tomato, mozarella, ham, aragula, and burrata cheese”,
price: 18,
photoName: “pizzas/prosciutto.jpg”,
soldOut: false,
},
];
function App() {
return (
<div className=“container”>
<h1>Hello React!!!!</h1>
<Header />
<Menu />
<Footer />
</div>
);
}
function Header() {
//const style = { color: “red”, fontSize: “48px”, textTransform: “uppercase” };
const style = {};
return (
<header className=“header”>
<h1 style={style}>Fast React Pizza Co.</h1>
</header>
);
}
function Menu() {
const pizzas = pizzaData;
const numPizzas = pizzas.length;
return (
<main className=“menu”>
<h2>Our menu</h2>
{/*<p>
Authentic Italian cuisine. 6 creative dishes to choose from. All from
our stone oven, all organic, all delicious
</p>*/}
{numPizzas > 0 ? (
<>
<p>
Authentic Italian cuisine. 6 creative dishes to choose from. All
from our stone oven, all organic, all delicious
</p>
<ul className=“pizzas”>
{pizzaData.map((pizza) => (
<Pizza pizzaObj={pizza} key={pizza.name} />
))}
</ul>
</>
) : (
<p>We’re still working on our menu. Please come back later :)</p>
)}
{/*<Pizza
name=”Pizza Spinaci”
ingredients=”Tomato, mozarella, spinach, and ricotta cheese”
photoName=”pizzas/spinaci.jpg”
price={10}
/>
<Pizza
name=”Pizza Funghi”
ingredients=”Tomato, mushrooms”
price={12}
photoName=”pizzas/funghi.jpg”
/>*/}
</main>
);
}
function Pizza({ pizzaObj }) {
//if (pizzaObj.soldOut) return null;
return (
<li className={`pizza ${pizzaObj.soldOut ? “sold-out” : “”}`}>
<img src={pizzaObj.photoName} alt={pizzaObj.name} />
<div>
<h3>{pizzaObj.name}</h3>
<p>{pizzaObj.ingredients}</p>
<span>{pizzaObj.soldOut ? “SOLD OUT” : pizzaObj.price}</span>
</div>
</li>
);
}
function Footer() {
const hour = new Date().getHours();
const openHour = 12;
const closeHour = 22;
const isOpen = hour >= openHour && hour <= closeHour;
console.log(isOpen);
//if (hour >= openHour && hour <= closeHour) alert(“we’re currently open!”);
//else alert(“Sorry we’re closed”);
return (
<footer className=“footer”>
{isOpen ? (
<Order closeHour={closeHour} openHour={openHour} />
) : (
<p>
We’re happy to welcome you between {openHour}:00 and {closeHour}:00.
</p>
)}
</footer>
);
//return React.createElement(“footer”, null, “We’re currently open!”);
}
function Order({ closeHour, openHour }) {
return (
<div className=“order”>
<p>
We’re open from {openHour}:00 till {closeHour}:00. Come visit us or
order online.
</p>
<button className=“btn”>Order</button>
</div>
);
}
// React v18
const root = ReactDOM.createRoot(document.getElementById(“root”));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// React before 18
// React.render(<App />, document.getElementBiTd(“root”));
@import url(“https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,300;0,400;0,500;1,300&display=swap”);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 62.5%;
}
body {
font-family: “Roboto Mono”, sans-serif;
color: #252525;
font-weight: 400;
background-color: #f7f2e9;
border-bottom: 1.6rem solid #edc84b;
min-height: 100vh;
padding: 3.2rem;
padding-bottom: 6rem;
}
.container {
max-width: 80rem;
margin: 0 auto;
display: flex;
flex-direction: column;
align-items: center;
gap: 4.8rem;
}
/* *************** */
.header {
align-self: stretch;
}
.header h1 {
/* Non-accessible color */
color: #edc84b;
/* color: #af8602; */
text-transform: uppercase;
text-align: center;
font-size: 5.2rem;
font-weight: 300;
letter-spacing: 3px;
position: relative;
width: 100%;
display: block;
}
.header h1::before,
.header h1::after {
display: block;
content: “”;
height: 3px;
width: 4rem;
background-color: #edc84b;
position: absolute;
top: calc(50% – 1px);
}
.header h1::before {
left: 0;
}
.header h1::after {
right: 0;
}
/* *************** */
.menu {
display: flex;
flex-direction: column;
align-items: center;
gap: 4rem;
}
.menu h2 {
display: inline-block;
padding: 1rem 0;
border-top: 2px solid currentColor;
border-bottom: 2px solid currentColor;
font-size: 2.4rem;
text-transform: uppercase;
letter-spacing: 3px;
font-weight: 500;
}
.menu > p {
font-size: 1.5rem;
text-align: center;
line-height: 1.6;
width: 80%;
}
.pizzas {
list-style: none;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 4.8rem;
}
.pizza {
display: flex;
gap: 3.2rem;
}
.pizza img {
width: 12rem;
aspect-ratio: 1;
align-self: start;
}
.pizza div {
display: flex;
flex-direction: column;
gap: 0.8rem;
padding: 0.4rem 0;
}
.pizza h3 {
font-size: 2rem;
font-weight: 400;
}
.pizza p {
font-size: 1.4rem;
font-weight: 300;
font-style: italic;
margin-bottom: auto;
}
.pizza span {
display: block;
font-size: 1.6rem;
}
.pizza.sold-out {
color: #888;
}
.pizza.sold-out img {
filter: grayscale();
opacity: 0.8;
}
/* *************** */
.footer {
font-size: 1.4rem;
}
.order {
display: flex;
flex-direction: column;
align-items: center;
gap: 2.4rem;
}
.btn {
color: inherit;
font-family: inherit;
border: none;
font-size: 1.4rem;
font-weight: 500;
background-color: #edc84b;
padding: 1.4rem 3.2rem;
cursor: pointer;
transition: all 0.2s;
}
.btn:hover {
background-color: #e9bb24;
}
/*
SPACING SYSTEM (px)
2 / 4 / 8 / 12 / 16 / 24 / 32 / 40 / 48 / 64 / 80 / 96 / 128
FONT SIZE SYSTEM (px)
10 / 12 / 14 / 16 / 18 / 20 / 24 / 30 / 36 / 44 /52 / 62 / 74 / 86 / 98
*/