Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion src/App.scss
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
// not empty
@import './styles/utils/mixins';
@import './styles/utils/variables';

.App {
min-height: 100vh;
display: flex;
flex-direction: column;
}

.section {
padding: 0;
margin: 0;
}

.container {
@include content-padding-inline;
}
13 changes: 12 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import { Outlet } from 'react-router-dom';
import './App.scss';
import { Header } from './components/Header';
import { Footer } from './components/Footer';

export const App = () => (
<div className="App">
<h1>Product Catalog</h1>
<Header />

<main className="section">
<div className="container">
<Outlet />
</div>
</main>

<Footer />
</div>
);
86 changes: 86 additions & 0 deletions src/Root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import {
Navigate,
Route,
HashRouter as Router,
Routes,
} from 'react-router-dom';
import { App } from './App';
import { HomePage } from './components/HomePage';
import { ProductsProvider } from './contexts/products/ProductsStore';
import { CatalogPage } from './components/CatalogPage';
import { ProductDetailsPage } from './components/ProductDetails';
import { PhonesProvider } from './contexts/phones';
import { TabletsProvider } from './contexts/tablets/TabletsStore';
import { AccessoriesProvider } from './contexts/accessories';
import { ScrollToTop } from './components/ScrollTotop';
import { CartPage } from './components/CartPage/CartPage';
import { CartProvider } from './contexts/cart';
import { FavoritesPage } from './components/FavoritesPage';
import { compose } from './utils/compose';
import { FavoritesProvider } from './contexts/favorites';

const Providers = compose([
CartProvider,
ProductsProvider,
PhonesProvider,
TabletsProvider,
AccessoriesProvider,
FavoritesProvider,
]);

export const Root = () => (
<Router>
<ScrollToTop />

<Providers>
<Routes>
<Route path="/" element={<App />}>
<Route index element={<HomePage />} />
<Route path="home" element={<Navigate to="/" replace />} />

<Route path="phones">
<Route
index
element={<CatalogPage category="phones" title="Phones" />}
/>
<Route
path=":itemId"
element={<ProductDetailsPage category="phones" title="Phones" />}
/>
</Route>
<Route path="tablets">
<Route
index
element={<CatalogPage category="tablets" title="Tablets" />}
/>
<Route
path=":itemId"
element={
<ProductDetailsPage category="tablets" title="Tablets" />
}
/>
</Route>
<Route path="accessories">
<Route
index
element={
<CatalogPage category="accessories" title="Accessories" />
}
/>
<Route
path=":itemId"
element={
<ProductDetailsPage
category="accessories"
title="Accessories"
/>
}
/>
</Route>
<Route path="favorites" element={<FavoritesPage />}></Route>
<Route path="cart" element={<CartPage />}></Route>
</Route>
</Routes>
</Providers>
</Router>
);
100 changes: 100 additions & 0 deletions src/components/CartPage/CartItem.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
@import '../../styles/utils/variables';
@import '../../styles/utils/mixins';

.cartItem {
display: flex;
width: 100%;
flex-direction: row;
padding: 24px;
gap: 24px;
justify-content: space-between;
align-items: center;
background-color: $surface-color-1;

@include on-mobile {
flex-direction: column;
}

&__productInfo {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
gap: 24px;
}

&__img {
width: 80px;
height: 80px;
}

&__img img {
width: 100%;
height: 100%;
object-fit: contain;
}

&__name {
font-weight: 600;
font-size: 16px;
color: #F1F2F9;
}

&__priceSettings {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
gap: 24px;

@include on-mobile {
gap: 0;
width: 100%;
}
}

&__quantityBox {
display: flex;
flex-direction: row;
gap: 14px;
align-items: center;
}

&__quantityBtn {
display: flex;
width: 32px;
height: 32px;
background-color: $surface-color-2;
align-items: center;
justify-content: center;
border: $box-shadow-settings;

&:hover {
background-color: $icons-hover-color;
}
}

&__quantityBtn img {
margin: 0;
padding: 0;
object-fit: contain;
}

&__btnOff {
background-color: $surface-color-1;
}

&__quantityBox p {
font-weight: 600;
font-size: 14px;
color: #F1F2F9;
}

&__price {
font-weight: 800;
font-size: 22px;
text-align: right;
padding-left: 29px;
color: #F1F2F9;
}
}
72 changes: 72 additions & 0 deletions src/components/CartPage/CartItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { CartItem } from '../../contexts/cart';
import { useCart } from '../../hooks/useCart';
import styles from './CartItem.module.scss';
import close from '../../images/Icons/close-btn-gray.png';
import plus from '../../images/Icons/plus-white.svg';
import minusWhite from '../../images/Icons/minus-white.svg';
import minusGray from '../../images/Icons/minus-gray.svg';
import classNames from 'classnames';
import { NavLink } from 'react-router-dom';

type Props = {
cartItem: CartItem;
};

export const CartItemCard: React.FC<Props> = ({ cartItem }) => {
const { removeFromCart, updateCart } = useCart();

const price = cartItem.product.price * cartItem.quantity;

return (
<div className={styles.cartItem}>
<div className={styles.cartItem__productInfo}>
<button
className={styles.cartItem__removeBtn}
onClick={() => removeFromCart(cartItem.product)}
>
<img src={close} alt="" />
</button>
<NavLink
to={`/${cartItem.product.category}/${cartItem.product.itemId}`}
className={styles.cartItem__img}
>
<img src={cartItem.product.image} alt="" />
</NavLink>

<NavLink
to={`/${cartItem.product.category}/${cartItem.product.itemId}`}
className={styles.cartItem__name}
>
{cartItem.product.name}
</NavLink>
</div>

<div className={styles.cartItem__priceSettings}>
<div className={styles.cartItem__quantityBox}>
<button
disabled={cartItem.quantity === 1}
className={classNames(styles.cartItem__quantityBtn, {
[styles.cartItem__btnOff]: cartItem.quantity === 1,
})}
onClick={() => updateCart(cartItem, '-')}
>
{cartItem.quantity > 1 ? (
<img src={minusWhite} alt="" />
) : (
<img src={minusGray} alt="" />
)}
</button>
<p className={styles.quantity}>{cartItem.quantity}</p>
<button
className={styles.cartItem__quantityBtn}
onClick={() => updateCart(cartItem, '+')}
>
<img src={plus} alt="" />
</button>
</div>

<h3 className={styles.cartItem__price}>${price}</h3>
</div>
</div>
);
};
Loading
Loading