Last active
September 9, 2023 14:48
-
-
Save QuocCao-dev/69e11c9a4b35ecbfa3c75eeea3d953b1 to your computer and use it in GitHub Desktop.
Solution menu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState } from "react"; | |
import Categories from "./Categories"; | |
import Menus from "./Menus"; | |
const menu = [ | |
{ | |
id: 1, | |
title: "buttermilk pancakes", | |
category: "breakfast", | |
price: 15.99, | |
img: "./images/item-1.jpeg", | |
desc: `I'm baby woke mlkshk wolf bitters live-edge blue bottle, hammock freegan copper mug whatever cold-pressed `, | |
}, | |
{ | |
id: 2, | |
title: "diner double", | |
category: "lunch", | |
price: 13.99, | |
img: "./images/item-2.jpeg", | |
desc: `vaporware iPhone mumblecore selvage raw denim slow-carb leggings gochujang helvetica man braid jianbing. Marfa thundercats `, | |
}, | |
{ | |
id: 3, | |
title: "godzilla milkshake", | |
category: "shakes", | |
price: 6.99, | |
img: "./images/item-3.jpeg", | |
desc: `ombucha chillwave fanny pack 3 wolf moon street art photo booth before they sold out organic viral.`, | |
}, | |
{ | |
id: 4, | |
title: "country delight", | |
category: "breakfast", | |
price: 20.99, | |
img: "./images/item-4.jpeg", | |
desc: `Shabby chic keffiyeh neutra snackwave pork belly shoreditch. Prism austin mlkshk truffaut, `, | |
}, | |
{ | |
id: 5, | |
title: "egg attack", | |
category: "lunch", | |
price: 22.99, | |
img: "./images/item-5.jpeg", | |
desc: `franzen vegan pabst bicycle rights kickstarter pinterest meditation farm-to-table 90's pop-up `, | |
}, | |
{ | |
id: 6, | |
title: "oreo dream", | |
category: "shakes", | |
price: 18.99, | |
img: "./images/item-6.jpeg", | |
desc: `Portland chicharrones ethical edison bulb, palo santo craft beer chia heirloom iPhone everyday`, | |
}, | |
{ | |
id: 7, | |
title: "bacon overflow", | |
category: "breakfast", | |
price: 8.99, | |
img: "./images/item-7.jpeg", | |
desc: `carry jianbing normcore freegan. Viral single-origin coffee live-edge, pork belly cloud bread iceland put a bird `, | |
}, | |
{ | |
id: 8, | |
title: "american classic", | |
category: "lunch", | |
price: 12.99, | |
img: "./images/item-8.jpeg", | |
desc: `on it tumblr kickstarter thundercats migas everyday carry squid palo santo leggings. Food truck truffaut `, | |
}, | |
{ | |
id: 9, | |
title: "quarantine buddy", | |
category: "shakes", | |
price: 16.99, | |
img: "./images/item-9.jpeg", | |
desc: `skateboard fam synth authentic semiotics. Live-edge lyft af, edison bulb yuccie crucifix microdosing.`, | |
}, | |
{ | |
id: 10, | |
title: "hủ tiếu", | |
category: "dinner", | |
price: 16.99, | |
img: "./images/item-9.jpeg", | |
desc: `skateboard fam synth authentic semiotics. Live-edge lyft af, edison bulb yuccie crucifix microdosing.`, | |
}, | |
]; | |
const categories = menu.map((item) => item.category); | |
const uniqueCategories = ["all", ...new Set(categories)]; | |
const filterMenusByCategory = (category: string) => { | |
if (category === "all") return menu; | |
return menu.filter((item) => item.category === category); | |
}; | |
function App() { | |
const [selectedCategory, setSelectedCategory] = useState("all"); | |
const handleSelectedCategory = (category: string) => | |
setSelectedCategory(category); | |
const filteredMenus = filterMenusByCategory(selectedCategory); | |
return ( | |
<main> | |
<section className="menu section"> | |
<div className="title"> | |
<h2>our menu</h2> | |
<div className="underline"></div> | |
</div> | |
<Categories | |
categories={uniqueCategories} | |
selectedCategory={selectedCategory} | |
onSelectCategory={handleSelectedCategory} | |
/> | |
<Menus menus={filteredMenus} /> | |
</section> | |
</main> | |
); | |
} | |
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Props = { | |
categories: string[]; | |
selectedCategory: string; | |
onSelectCategory: (category: string) => void; | |
}; | |
const Categories = ({ | |
categories, | |
selectedCategory, | |
onSelectCategory, | |
}: Props) => { | |
const handleSelectCategory = (category: string) => () => { | |
onSelectCategory(selectedCategory === category ? "all" : category); | |
}; | |
return ( | |
<div className="btn-container"> | |
{categories.map((category, index) => { | |
return ( | |
<button | |
type="button" | |
className={`filter-btn ${ | |
selectedCategory === category && "active" | |
}`} | |
key={index} | |
onClick={handleSelectCategory(category)} | |
> | |
{category} | |
</button> | |
); | |
})} | |
</div> | |
); | |
}; | |
export default Categories; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
=============== | |
Variables | |
=============== | |
*/ | |
:root { | |
/* dark shades of primary color*/ | |
--clr-primary-1: hsl(205, 86%, 17%); | |
--clr-primary-2: hsl(205, 77%, 27%); | |
--clr-primary-3: hsl(205, 72%, 37%); | |
--clr-primary-4: hsl(205, 63%, 48%); | |
/* primary/main color */ | |
--clr-primary-5: hsl(205, 78%, 60%); | |
/* lighter shades of primary color */ | |
--clr-primary-6: hsl(205, 89%, 70%); | |
--clr-primary-7: hsl(205, 90%, 76%); | |
--clr-primary-8: hsl(205, 86%, 81%); | |
--clr-primary-9: hsl(205, 90%, 88%); | |
--clr-primary-10: hsl(205, 100%, 96%); | |
/* darkest grey - used for headings */ | |
--clr-grey-1: hsl(209, 61%, 16%); | |
--clr-grey-2: hsl(211, 39%, 23%); | |
--clr-grey-3: hsl(209, 34%, 30%); | |
--clr-grey-4: hsl(209, 28%, 39%); | |
/* grey used for paragraphs */ | |
--clr-grey-5: hsl(210, 22%, 49%); | |
--clr-grey-6: hsl(209, 23%, 60%); | |
--clr-grey-7: hsl(211, 27%, 70%); | |
--clr-grey-8: hsl(210, 31%, 80%); | |
--clr-grey-9: hsl(212, 33%, 89%); | |
--clr-grey-10: hsl(210, 36%, 96%); | |
--clr-white: #fff; | |
--clr-gold: #c59d5f; | |
--clr-red-dark: hsl(360, 67%, 44%); | |
--clr-red-light: hsl(360, 71%, 66%); | |
--clr-green-dark: hsl(125, 67%, 44%); | |
--clr-green-light: hsl(125, 71%, 66%); | |
--clr-black: #222; | |
--transition: all 0.3s linear; | |
--spacing: 0.1rem; | |
--radius: 0.25rem; | |
--light-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); | |
--dark-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); | |
--max-width: 1170px; | |
--fixed-width: 620px; | |
} | |
/* | |
=============== | |
Global Styles | |
=============== | |
*/ | |
*, | |
::after, | |
::before { | |
margin: 0; | |
padding: 0; | |
box-sizing: border-box; | |
} | |
body { | |
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, | |
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; | |
background: var(--clr-grey-10); | |
color: var(--clr-grey-1); | |
line-height: 1.5; | |
font-size: 0.875rem; | |
} | |
ul { | |
list-style-type: none; | |
} | |
a { | |
text-decoration: none; | |
} | |
h1, | |
h2, | |
h3, | |
h4 { | |
letter-spacing: var(--spacing); | |
text-transform: capitalize; | |
line-height: 1.25; | |
margin-bottom: 0.75rem; | |
} | |
h1 { | |
font-size: 3rem; | |
} | |
h2 { | |
font-size: 2rem; | |
} | |
h3 { | |
font-size: 1.25rem; | |
} | |
h4 { | |
font-size: 0.875rem; | |
} | |
p { | |
margin-bottom: 1.25rem; | |
color: var(--clr-grey-5); | |
} | |
@media screen and (min-width: 800px) { | |
h1 { | |
font-size: 4rem; | |
} | |
h2 { | |
font-size: 2.5rem; | |
} | |
h3 { | |
font-size: 1.75rem; | |
} | |
h4 { | |
font-size: 1rem; | |
} | |
body { | |
font-size: 1rem; | |
} | |
h1, | |
h2, | |
h3, | |
h4 { | |
line-height: 1; | |
} | |
} | |
/* global classes */ | |
/* section */ | |
.section { | |
width: 90vw; | |
margin: 0 auto; | |
max-width: var(--max-width); | |
} | |
@media screen and (min-width: 992px) { | |
.section { | |
width: 95vw; | |
} | |
} | |
/* | |
=============== | |
Menu | |
=============== | |
*/ | |
.menu { | |
padding: 5rem 0; | |
} | |
.title { | |
text-align: center; | |
margin-bottom: 2rem; | |
} | |
.underline { | |
width: 5rem; | |
height: 0.25rem; | |
background: var(--clr-gold); | |
margin-left: auto; | |
margin-right: auto; | |
} | |
.btn-container { | |
margin-bottom: 4rem; | |
display: flex; | |
justify-content: center; | |
} | |
.filter-btn { | |
background: transparent; | |
border-color: transparent; | |
font-size: 1rem; | |
text-transform: capitalize; | |
margin: 0 0.5rem; | |
letter-spacing: 1px; | |
padding: 0.375rem 0.75rem; | |
color: var(--clr-gold); | |
cursor: pointer; | |
transition: var(--transition); | |
border-radius: var(--radius); | |
} | |
.filter-btn:hover { | |
background: var(--clr-gold); | |
color: var(--clr-white); | |
} | |
.filter-btn.active { | |
background: var(--clr-gold); | |
color: var(--clr-white); | |
} | |
.section-center { | |
width: 90vw; | |
margin: 0 auto; | |
max-width: 1170px; | |
display: grid; | |
gap: 3rem 2rem; | |
justify-items: center; | |
} | |
.menu-item { | |
display: grid; | |
gap: 1rem 2rem; | |
max-width: 25rem; | |
} | |
.photo { | |
object-fit: cover; | |
height: 200px; | |
width: 100%; | |
border: 0.25rem solid var(--clr-gold); | |
border-radius: var(--radius); | |
display: block; | |
} | |
.item-info header { | |
display: flex; | |
justify-content: space-between; | |
border-bottom: 0.5px dotted var(--clr-grey-5); | |
} | |
.item-info h4 { | |
margin-bottom: 0.5rem; | |
} | |
.price { | |
color: var(--clr-gold); | |
} | |
.item-text { | |
margin-bottom: 0; | |
padding-top: 1rem; | |
} | |
@media screen and (min-width: 768px) { | |
.menu-item { | |
grid-template-columns: 225px 1fr; | |
gap: 0 1.25rem; | |
max-width: 40rem; | |
} | |
.photo { | |
height: 175px; | |
} | |
} | |
@media screen and (min-width: 1200px) { | |
.section-center { | |
width: 95vw; | |
grid-template-columns: 1fr 1fr; | |
} | |
.photo { | |
height: 150px; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment