Commit a5e05842 authored by anton's avatar anton

second_lesson-1

parent 5299eb97
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}
......@@ -3,18 +3,19 @@ import "./BuildControl.css";
interface Props {
type: IngredientNames;
hadlerLess: () => void;
hadlerMore: () => void;
disabled: boolean;
handleLess: () => void;
handleMore: () => void;
}
export function BuildControl({ type, hadlerLess, hadlerMore }: Props) {
export function BuildControl({ type, disabled, handleLess, handleMore }: Props) {
return (
<div className="BuildControl">
<div className="Label">{type}</div>
<button className="Less" onClick={hadlerLess}>
<button className="Less" onClick={handleLess} disabled={disabled}>
Less
</button>
<button className="More" onClick={hadlerMore}>
<button className="More" onClick={handleMore}>
More
</button>
</div>
......
......@@ -8,3 +8,31 @@
margin: auto;
padding: 10px 0;
}
.OrderButton {
background-color: #dad735;
outline: none;
cursor: pointer;
border: 1px solid #966909;
color: #966909;
font-family: inherit;
font-size: 1.2em;
padding: 15px 30px;
box-shadow: 2px 2px 2px #966909;
}
.OrderButton:hover,
.OrderButton:active {
background-color: #a0db41;
border: 1px solid #966909;
color: #966909;
}
.OrderButton:disabled {
background-color: #c7c6c6;
cursor: not-allowed;
border: 1px solid #ccc;
color: #888888;
}
.OrderButton:not(:disabled) {
animation: enable 0.3s linear;
}
import { IngredientNames, Ingredients } from "@/interfaces/burger-interface";
import "./BuildControls.css";
import { BuildControl } from "@/components/BuildControls/BuildControl/BuildControl";
import { Dispatch, SetStateAction } from "react";
interface Props {
ingredients: Ingredients;
totalPrice: number;
hadlerLess: (key: IngredientNames) => void;
hadlerMore: (key: IngredientNames) => void;
purchasable: boolean;
handleLess: (key: IngredientNames) => void;
handleMore: (key: IngredientNames) => void;
setIsOpen: Dispatch<SetStateAction<boolean>>;
}
export function BuildControls({ ingredients, totalPrice, hadlerLess, hadlerMore }: Props) {
export function BuildControls({
ingredients,
totalPrice,
purchasable,
handleLess,
handleMore,
setIsOpen,
}: Props) {
const ingrKeys = Object.keys(ingredients) as (keyof Ingredients)[];
return (
......@@ -19,10 +29,14 @@ export function BuildControls({ ingredients, totalPrice, hadlerLess, hadlerMore
<BuildControl
key={key + i}
type={key}
hadlerLess={() => hadlerLess(key)}
hadlerMore={() => hadlerMore(key)}
disabled={!ingredients[key]}
handleLess={() => handleLess(key)}
handleMore={() => handleMore(key)}
/>
))}
<button className="OrderButton" disabled={!purchasable} onClick={() => setIsOpen(true)}>
ORDER NOW
</button>
</div>
);
}
import { IngredientNames, Ingredients } from "@/interfaces/burger-interface";
interface Props {
ingredients: Ingredients;
price: number;
}
export function OrderSummary({ ingredients, price }: Props) {
const ingredientSummary = Object.keys(ingredients).map((igKey) => {
return (
<li key={igKey}>
<span style={{ textTransform: "capitalize" }}>{igKey}</span>:{" "}
{ingredients[igKey as IngredientNames]}
</li>
);
});
return (
<>
<h3>Your order</h3>
<p>A delicious burger with the following ingredients:</p>
<ul>{ingredientSummary}</ul>
<p>
<strong>Total Price: {price}</strong>
</p>
<p>Continue to checkout?</p>
</>
);
}
.Backdrop {
width: 100%;
height: 100%;
position: fixed;
z-index: 100;
left: 0;
top: 0;
background-color: rgba(0, 0, 0, 0.5);
}
import { Dispatch, SetStateAction } from "react";
import "@/components/UI/Backdrop/Backdrop.css";
interface Props {
setIsOpen: Dispatch<SetStateAction<boolean>>;
}
export const Backdrop = ({ setIsOpen }: Props) => {
return <div className="Backdrop" onClick={() => setIsOpen(false)}></div>;
};
.Modal {
position: fixed;
z-index: 500;
background-color: white;
width: 70%;
border: 1px solid #ccc;
box-shadow: 1px 1px 1px black;
padding: 16px;
left: 15%;
top: 30%;
box-sizing: border-box;
transition: all 0.3s ease-out;
color: black;
}
@media (min-width: 600px) {
.Modal {
width: 500px;
left: calc(50% - 250px);
}
}
import { Dispatch, ReactNode, SetStateAction } from "react";
import { Backdrop } from "@/components/UI/Backdrop/Backdrop";
import "./Modal.css";
interface Props {
isOpen: boolean;
children: ReactNode;
setIsOpen: Dispatch<SetStateAction<boolean>>;
}
export const Modal = ({ isOpen, children, setIsOpen }: Props) => {
// return isOpen ? (
// <>
// <Backdrop setIsOpen={setIsOpen} />
// <div className="Modal">{children}</div>
// </>
// ) : null;
return (
<div style={{ display: isOpen ? "block" : "none" }}>
<Backdrop setIsOpen={setIsOpen} />
<div className="Modal">{children}</div>
</div>
);
};
import { BuildControls } from "@/components/BuildControls/BuildControls";
import { Burger } from "@/components/Burger/Burger";
import { OrderSummary } from "@/components/Burger/OrderSummary/OrderSummary";
import { Modal } from "@/components/UI/Modal/Modal";
import { IngredientNames, IngredientPrices, Ingredients } from "@/interfaces/burger-interface";
import { useState } from "react";
export function BurgerBuilder() {
const [isOpen, setIsOpen] = useState<boolean>(false);
const [purchasable, setPurchasable] = useState(false);
const [totalPrice, setTotalPrice] = useState<number>(IngredientPrices.cheese);
const [ingredients, setIngredients] = useState<Ingredients>({
salad: 0,
......@@ -12,28 +16,44 @@ export function BurgerBuilder() {
meat: 0,
});
const hadlerLess = (ingKey: IngredientNames) => {
setIngredients((prevState) => ({
...prevState,
[ingKey]: prevState[ingKey] !== 0 ? prevState[ingKey] - 1 : 0,
}));
const updatePurchasable = (newIngredients: Ingredients) => {
const values = Object.values(newIngredients).reduce((acc, el) => acc + el, 0);
setPurchasable(!!values);
};
const handleLess = (ingKey: IngredientNames) => {
const newIngredients = {
...ingredients,
[ingKey]: ingredients[ingKey] !== 0 ? ingredients[ingKey] - 1 : 0,
};
setIngredients(newIngredients);
updatePurchasable(newIngredients);
};
const hadlerMore = (ingKey: IngredientNames) => {
setIngredients((prevState) => ({
...prevState,
[ingKey]: prevState[ingKey] + 1,
}));
const handleMore = (ingKey: IngredientNames) => {
const newIngredients = {
...ingredients,
[ingKey]: ingredients[ingKey] + 1,
};
setIngredients(newIngredients);
updatePurchasable(newIngredients);
};
return (
<>
<Burger ingredients={ingredients} />
<BuildControls
ingredients={ingredients}
hadlerLess={hadlerLess}
hadlerMore={hadlerMore}
totalPrice={totalPrice}
purchasable={purchasable}
handleLess={handleLess}
handleMore={handleMore}
setIsOpen={setIsOpen}
/>
<Modal isOpen={isOpen} setIsOpen={setIsOpen}>
<OrderSummary ingredients={ingredients} price={totalPrice} />
</Modal>
</>
);
}
......@@ -6,63 +6,10 @@
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
flex: 1;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment