Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
75 changes: 70 additions & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,72 @@
import './App.scss';
import { Routes, Route } from 'react-router-dom';
import { Frame } from './components/Frame';
import { HomePage } from './modules/HomePage';
import { ProductsPage } from './modules/ProductsPage';
import phones from '../public/api/phones.json';
import tablets from '../public/api/tablets.json';
import accessories from '../public/api/accessories.json';
import products from '../public/api/products.json';
import { ProductPage } from './modules/ProductPage';
import { useContext } from 'react';
import { AddToFavContext } from './contexts/AddToFavContext';
import { NotFoundPage } from './modules/NotFoundPage';
import { CartPage } from './modules/CartPage/CartPage';

export const App = () => (
<div className="App">
<h1>Product Catalog</h1>
</div>
);
export const App = () => {
const phonesForCat = products.filter(
product => product.category === 'phones',
);
const tabletsForCat = products.filter(
product => product.category === 'tablets',
);
const accessoriesForCat = products.filter(
product => product.category === 'accessories',
);

const { fav } = useContext(AddToFavContext);

return (
<Routes>
<Route path="/" element={<Frame />}>
<Route index element={<HomePage products={products} />} />
<Route path="phones">
<Route
index
element={
<ProductsPage products={phonesForCat} title="Mobile phones" />
}
/>
<Route path=":product" element={<ProductPage products={phones} />} />
</Route>

<Route path="tablets">
<Route
index
element={<ProductsPage products={tabletsForCat} title="Tablets" />}
/>
<Route path=":product" element={<ProductPage products={tablets} />} />
</Route>
<Route path="accessories">
<Route
index
element={
<ProductsPage products={accessoriesForCat} title="Accessories" />
}
/>
<Route
path=":product"
element={<ProductPage products={accessories} />}
/>
</Route>
<Route
path="favourites"
index
element={<ProductsPage products={fav} title="Favourites" />}
/>
<Route path="cart" element={<CartPage />} />
<Route path="*" element={<NotFoundPage />} />
</Route>
</Routes>
);
};
106 changes: 106 additions & 0 deletions src/components/Footer/Footer.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
@import '../../style/main';

.footer {
background-color: $header-footer-bg-color;
height: $footer-height-desktop-tablet;
box-shadow: 0 -1px 0 0 $shadow-color;

@include on-mobile {
height: $footer-height-mobile;
}

&__content {
@include page-grid;

height: $footer-height-desktop-tablet;
align-content: center;

@include on-mobile {
height: $footer-height-mobile;
row-gap: 32px;
}
}

&__logo {
display: flex;
background-image: url(/img/header/logo.svg);
background-size: cover;
background-repeat: no-repeat;

height: 32px;
width: 89px;

&__container {
align-items: center;
}
}

&__to-top {
font-family: inherit;
margin: 0;
padding: 0;
display: flex;
justify-self: end;
font-weight: 600;
font-size: 12px;
letter-spacing: 4%;
text-decoration: none;
color: $secondary-color;
width: 118px;
height: 32px;
line-height: 32px;

background-image: url(/img/footer/slider-button-default.svg);
background-size: 32px;
background-position: right;
background-repeat: no-repeat;

@include on-mobile {
justify-self: center;
}
}

&__logo__container,
&__nav,
&__to-top {
border: none;
background-color: inherit;
cursor: pointer;
grid-column: span 8;
align-self: center;

@include on-tablet {
grid-column: span 4;
}
}
}

.nav {
&__list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
justify-content: space-between;

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

&__item {
display: flex;
}

&__link {
text-decoration: none;
color: $secondary-color;
font-weight: 700;
font-size: 12px;
line-height: 11px;
letter-spacing: 4%;
text-transform: uppercase;
justify-self: end;
}
}
67 changes: 67 additions & 0 deletions src/components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import footer from './Footer.module.scss';

import { useContext } from 'react';
import { Link } from 'react-router-dom';
import cn from 'classnames';
import { ScrollToSectContext } from '../../contexts/ScrollToSectContext';

export const Footer = () => {
const { scrollToSect } = useContext(ScrollToSectContext);

return (
<footer className={footer.footer}>
<div className="frame">
<div className="container">
<div className={footer.footer__content}>
<div className={footer.footer__logo__container}>
<Link
to="/"
className={footer.footer__logo}
onClick={() => scrollToSect('top')}
></Link>
</div>

<nav className={cn(footer.footer__nav, footer.nav)}>
<ul className={footer.nav__list}>
<li className={footer.nav__item}>
<Link
to="https://github.com/PolianskyiDmytro/react_phone-catalog"
target="_blank"
className={footer.nav__link}
>
Github
</Link>
</li>
<li className={footer.nav__item}>
<Link
to="https://polianskyidmytro.github.io/PolianskyiDmytroCV/"
target="_blank"
className={footer.nav__link}
>
Contacts
</Link>
</li>
<li className={footer.nav__item}>
<Link
to="https://regulatoryinfo.apple.com/regulatorydata"
target="_blank"
className={footer.nav__link}
>
rights
</Link>
</li>
</ul>
</nav>
<button
type="button"
className={footer['footer__to-top']}
onClick={() => scrollToSect('top')}
>
Back to top
</button>
</div>
</div>
</div>
</footer>
);
};
1 change: 1 addition & 0 deletions src/components/Footer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Footer';
19 changes: 19 additions & 0 deletions src/components/Frame/Frame.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@import '../../style/main';

.main {
box-sizing: border-box;
margin: 0;
padding: 0;
min-height: calc(100vh - $header-height-desktop - $footer-height-desktop-tablet);
background-color: $main-bg-color;

@include on-tablet {
min-height: calc(
100vh - $header-height-tablet-mobile - $footer-height-desktop-tablet
);
}

@include on-mobile {
min-height: calc(100vh - $header-height-tablet-mobile - $footer-height-mobile);
}
}
39 changes: 39 additions & 0 deletions src/components/Frame/Frame.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import frame from './Frame.module.scss';
import { Outlet } from 'react-router-dom';
import { Header } from '../Header';
import { Footer } from '../Footer';
import { Menu } from '../Menu/Menu';
import { useEffect, useState } from 'react';

export const Frame = () => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const media = window.matchMedia('(max-width: 639px)');
const [isMobile, setIsMobile] = useState(media.matches);

useEffect(() => {
const handler = () => setIsMobile(media.matches);

media.addEventListener('change', handler);

return () => media.removeEventListener('change', handler);
}, []);

return (
<div id="top">
<Header isMenuOpen={isMenuOpen} setIsMenuOpen={setIsMenuOpen} />

{isMenuOpen && isMobile ? (
<Menu setIsMenuOpen={setIsMenuOpen} />
) : (
<>
<main className={frame.main}>
<div className="frame">
<Outlet />
</div>
</main>
<Footer />
</>
)}
</div>
);
};
1 change: 1 addition & 0 deletions src/components/Frame/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Frame';
Loading
Loading