Добавили карточку товара и список товаров, создали новые данные в db.json. Установили в проект иконки и изображения новых товаров, создали функцию getProducts для получения товаров с бекенда
@@ -2,24 +2,51 @@
|
||||
"products": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Sneakers Red & White 2025",
|
||||
"brand": "NIKE",
|
||||
"price": 38.0,
|
||||
"imageUrl": "./src/assets/images/sneakers-image.jpg"
|
||||
"name": "Breed Dry Dog Food",
|
||||
"price": 100,
|
||||
"imageUrl": "./src/assets/images/products/dog-food.svg"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Sneakers Red & White 2025",
|
||||
"brand": "NIKE",
|
||||
"price": 38.0,
|
||||
"imageUrl": "./src/assets/images/sneakers-image.jpg"
|
||||
"name": "CANON EOS DSLR Camera",
|
||||
"price": 360,
|
||||
"imageUrl": "./src/assets/images/products/camera.svg"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Sneakers Red & White 2025",
|
||||
"brand": "NIKE",
|
||||
"price": 38.0,
|
||||
"imageUrl": "./src/assets/images/sneakers-image.jpg"
|
||||
"name": "ASUS FHD Gaming Laptop",
|
||||
"price": 700,
|
||||
"imageUrl": "./src/assets/images/products/laptop.svg"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Curology Product Set ",
|
||||
"price": 500,
|
||||
"imageUrl": "./src/assets/images/products/curoset.svg"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Kids Electric Car",
|
||||
"price": 960,
|
||||
"imageUrl": "./src/assets/images/products/car.svg"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "Jr. Zoom Soccer Cleats",
|
||||
"price": 1160,
|
||||
"imageUrl": "./src/assets/images/products/soccer.svg"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "GP11 Shooter USB Gamepad",
|
||||
"price": 660,
|
||||
"imageUrl": "./src/assets/images/products/gamepad.svg"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "Quilted Satin Jacket",
|
||||
"price": 660,
|
||||
"imageUrl": "./src/assets/images/products/jacket.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
import styles from './App.module.scss'
|
||||
import React from 'react'
|
||||
|
||||
/* HEADER ICONS */
|
||||
import CartIcon from './assets/icons/cart.svg'
|
||||
import UserIcon from './assets/icons/user.svg'
|
||||
import WishlistIcon from './assets/icons/wishlist.svg'
|
||||
import LoopIcon from './assets/icons/loop.svg'
|
||||
|
||||
/* PRODUCT CARD ICONS */
|
||||
import WishIcon from './assets/icons/wish.svg'
|
||||
|
||||
const Header = () => {
|
||||
return (
|
||||
<header className={styles.header}>
|
||||
@@ -44,10 +49,56 @@ const Header = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const ProductCard = ({ name, price, imageUrl }) => {
|
||||
return (
|
||||
<div className={styles.product}>
|
||||
<div className={styles.image}>
|
||||
<img src={imageUrl} alt='' />
|
||||
<div className={styles.buttons}>
|
||||
<button>
|
||||
<img src={WishIcon} alt='' />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
<h4>{name}</h4>
|
||||
<div className={styles.stats}>
|
||||
<span>${price}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const ProductList = () => {
|
||||
const [products, setProducts] = React.useState([])
|
||||
|
||||
const getProducts = async () => {
|
||||
const response = await fetch('http://localhost:8000/products')
|
||||
const data = await response.json()
|
||||
setProducts(data)
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
getProducts()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<ul className={styles.list}>
|
||||
{products.map(product => (
|
||||
<li>
|
||||
<ProductCard {...product} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Header />
|
||||
<ProductList />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@use './assets/styles/variables' as *;
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
max-width: 1170px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@@ -62,3 +62,61 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* PRODUCT LIST */
|
||||
.list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
list-style: none;
|
||||
padding-top: 60px;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
/* PRODUCT CARD */
|
||||
|
||||
.product {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
width: 270px;
|
||||
|
||||
.image {
|
||||
background-color: #f5f5f5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 35px;
|
||||
height: 250px;
|
||||
position: relative;
|
||||
|
||||
.buttons {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
|
||||
button {
|
||||
display: flex;
|
||||
outline: 0;
|
||||
border: 0;
|
||||
border-radius: 50%;
|
||||
padding: 10px;
|
||||
background-color: white;
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.stats {
|
||||
span {
|
||||
font-size: 16px;
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<svg width="18" height="20" viewBox="0 0 18 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17 3.57143H2.33333L3.66667 19H14.3333L15.6667 3.57143H1M9 7.42857V15.1429M12.3333 7.42857L11.6667 15.1429M5.66667 7.42857L6.33333 15.1429M6.33333 3.57143L7 1H11L11.6667 3.57143" stroke="black" stroke-width="1.56" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 375 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="18" height="16" viewBox="0 0 18 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5 1C2.7912 1 1 2.73964 1 4.88594C1 6.61852 1.7 10.7305 8.5904 14.8873C8.71383 14.961 8.85552 15 9 15C9.14448 15 9.28617 14.961 9.4096 14.8873C16.3 10.7305 17 6.61852 17 4.88594C17 2.73964 15.2088 1 13 1C10.7912 1 9 3.35511 9 3.35511C9 3.35511 7.2088 1 5 1Z" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 454 B |
|
After Width: | Height: | Size: 246 KiB |
|
After Width: | Height: | Size: 628 KiB |
|
After Width: | Height: | Size: 204 KiB |
|
After Width: | Height: | Size: 186 KiB |
|
After Width: | Height: | Size: 143 KiB |
|
After Width: | Height: | Size: 394 KiB |
|
After Width: | Height: | Size: 165 KiB |
|
After Width: | Height: | Size: 406 KiB |
|
Before Width: | Height: | Size: 23 KiB |