Skip to content

Commit

Permalink
commit for fe chat
Browse files Browse the repository at this point in the history
  • Loading branch information
MykolaButylkov committed Jul 28, 2023
1 parent e31354b commit 046178a
Show file tree
Hide file tree
Showing 13 changed files with 279 additions and 106 deletions.
41 changes: 32 additions & 9 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,42 @@
import { FC, useState, useEffect } from 'react';

import './App.scss';

import { Header } from './pages/components/Header';
import { HomePage } from './pages/HomePage';
import { PhonesPage } from './pages/PhonesPage';
import { Footer } from './pages/components/Footer';
import { getPhones } from './api/phone';
import { Phone } from './types/Phone';
// import { ProductDetailsPage } from './pages/ProductDetailsPage';

const App = () => (
<div className="App">
<Header />
<HomePage />
<PhonesPage />
{/* <ProductDetailsPage /> */}
<Footer />
</div>
);
const App: FC = () => {
const [phones, setPhones] = useState<Phone[]>([]);

async function loadedPhones() {
try {
const result = await getPhones();

setPhones(result);
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
}

useEffect(() => {
loadedPhones();
}, []);

return (
<div className="App">
<Header />
<HomePage phones={phones} />
<PhonesPage phones={phones} />
{/* <ProductDetailsPage /> */}
<Footer />
</div>
);
};

export default App;
2 changes: 1 addition & 1 deletion src/api/phone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ import { Phone } from '../types/Phone';
import { client } from '../utils/fetchClient';

export const getPhones = () => {
return client.get<Phone[]>('/products.json');
return client.get<Phone[]>('/_new/products.json');
};
53 changes: 15 additions & 38 deletions src/pages/HomePage.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
/* eslint-disable jsx-a11y/anchor-is-valid */
import React, { useState, useEffect } from 'react';
import React from 'react';

import { ProductsSlider } from './components/ProductsSlider';
import '../styles/styles.scss';

import { PreviewSlider } from './components/PreviewSlider';
// import { ProductCard } from './components/ProductCard';
import { getPhones } from '../api/phone';
import { Phone } from '../types/Phone';
import { ProductCard } from './components/ProductCard';

export const HomePage: React.FC = () => {
const [phones, setPhones] = useState<Phone[]>([]);
type Props = {
phones: Phone[];
};

export const HomePage: React.FC<Props> = ({ phones }) => {
const hotPricePhones = [...phones].sort(
(a: Phone, b: Phone) => +a.fullPrice - +b.fullPrice,
);

const brandNewModels = [...phones].sort(
(a: Phone, b: Phone) => +a.year - +b.year,
);

const images = [
{ imgUrl: 'images/BannerHomePage.png', id: '01' },
Expand All @@ -30,21 +37,6 @@ export const HomePage: React.FC = () => {
// { id: '8', value: <ProductCard /> },
// ];

async function loadedPhones() {
try {
const result = await getPhones();

setPhones(result);
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
}

useEffect(() => {
loadedPhones();
}, []);

return (
<>
<div className="home-page">
Expand All @@ -65,16 +57,7 @@ export const HomePage: React.FC = () => {
<h1 className="hot-prices__title">
Hot prices
</h1>
<ProductsSlider>
{phones.map(product => {
return (
<ProductCard
key={product.id}
product={product}
/>
);
})}
</ProductsSlider>
<ProductsSlider phones={hotPricePhones} />
</div>

<div className="home-page__shop-by-category shop-by-category">
Expand Down Expand Up @@ -126,13 +109,7 @@ export const HomePage: React.FC = () => {
<h1 className="brand-new__title">
Brand new models
</h1>
{/* <ProductsSlider>
{products.map(product => (
<div key={product.id}>
{product.value}
</div>
))}
</ProductsSlider> */}
<ProductsSlider phones={brandNewModels} />
</div>
</div>

Expand Down
87 changes: 79 additions & 8 deletions src/pages/PhonesPage.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,75 @@
import { FC } from 'react';
import { FC, useState } from 'react';
import Breadcrumbs from './components/Breadcrumbs';
// import { ProductsList } from './components/ProductsList';
import { ProductsList } from './components/ProductsList';
// eslint-disable-next-line import/no-cycle
import CustomSelect from './components/CustomSelect';
import { Phone } from '../types/Phone';

import '../styles/styles.scss';

export const PhonesPage: FC = () => {
type Props = {
phones: Phone[];
};

export enum SortByOptions {
AGE = 'age',
NAME = 'name',
PRICE = 'price',
}

export const PhonesPage: FC<Props> = ({ phones }) => {
const [selectedOptions, setSelectedOptions] = useState({
sortBy: 'age',
itemsShow: '16',
});

const breadcrumbItems = [
{ text: 'Home', link: '/' },
{ text: 'Phones', link: '/phones' },
];

const sortByOptions = ['age', 'name', 'price'];
const itemsOnPageOptions = ['4', '8', '16', 'all'];

function getVisiblePhones(arr: Phone[]) {
let result: Phone[] = [];

switch (selectedOptions.sortBy) {
case SortByOptions.AGE:
result = arr.sort((a, b) => a.year - b.year);
break;
case SortByOptions.NAME:
result = arr.sort((a, b) => a.name.localeCompare(b.name));
break;
case SortByOptions.PRICE:
result = arr.sort((a, b) => a.price - b.price);
break;

default:
break;
}

switch (selectedOptions.itemsShow) {
case '4':
result = result.filter((_, index) => index < 4);
break;
case '8':
result = result.filter((_, index) => index < 8);

break;
case '16':
result = result.filter((_, index) => index < 16);
break;
case 'all':
default:
return result;
}

return result;
}

const visiblePhones = getVisiblePhones(phones);

return (
<div className="phones-page">
<Breadcrumbs items={breadcrumbItems} />
Expand All @@ -17,7 +78,12 @@ export const PhonesPage: FC = () => {
<div className="phones-page__filter filter">
<div className="filter__container">
<h2 className="filter__title">Sort by</h2>
<select
<CustomSelect
options={sortByOptions}
defaultOption="Select an option"
onChange={setSelectedOptions}
/>
{/* <select
className="filter__selector"
name="sort-by"
id="sort"
Expand All @@ -41,11 +107,16 @@ export const PhonesPage: FC = () => {
>
Cheapest
</option>
</select>
</select> */}
</div>
<div className="filter__container">
<h2 className="filter__title">Items on page</h2>
<select
<CustomSelect
options={itemsOnPageOptions}
defaultOption="Select an option"
onChange={setSelectedOptions}
/>
{/* <select
className="filter__selector"
name="items-on-page"
id="sort"
Expand All @@ -70,10 +141,10 @@ export const PhonesPage: FC = () => {
>
ALL
</option>
</select>
</select> */}
</div>
</div>
{/* <ProductsList /> */}
<ProductsList products={visiblePhones} />
</div>
);
};
64 changes: 64 additions & 0 deletions src/pages/components/CustomSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
/* eslint-disable jsx-a11y/no-static-element-interactions */
import {
Dispatch, FC, SetStateAction, useState,
} from 'react';
import classNames from 'classnames';
// eslint-disable-next-line import/no-cycle
import { SortByOptions } from '../PhonesPage';
import '../../styles/styles.scss';

type Props = {
options: string[],
defaultOption: string,
onChange: Dispatch<SetStateAction<{ sortBy: string; itemsShow: string; }>>;
};

const CustomSelect: FC<Props> = ({ options, defaultOption, onChange }) => {
const [isOpen, setIsOpen] = useState(false);
const [selectedOption, setSelectedOption] = useState(defaultOption);

const toggleDropdown = () => {
setIsOpen(!isOpen);
};

const handleOptionClick = (option: string) => {
setSelectedOption(option);
setIsOpen(false);
if (onChange) {
if (SortByOptions.AGE === option
|| SortByOptions.NAME === option
|| SortByOptions.PRICE === option) {
onChange((prev) => ({ ...prev, sortBy: option }));
} else {
onChange((prev) => ({ ...prev, itemsShow: option }));
}
}
};

return (
<div className="custom-select" onClick={toggleDropdown}>
<div className="selected-option">{selectedOption}</div>
{isOpen && (
<ul className={classNames(
'options',
{ 'options--opened': isOpen },
)}
>
{options.map((option: string) => (
<li
// className=
key={option}
onClick={() => handleOptionClick(option)}
>
{option}
</li>
))}
</ul>
)}
</div>
);
};

export default CustomSelect;
6 changes: 3 additions & 3 deletions src/pages/components/ProductCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ export const ProductCard: FC<Props> = ({ product }) => {
return (
<div className="product-card" key={product.id}>
<img
src={product.imageUrl}
src={product.image}
alt="Phone"
className="product-card__phone-img"
/>
<h2 className="product-card__title">
{/* Apple iPhone Xs 64GB Silver (iMT9G2FS/A) */}
{product.name}
</h2>
<p className="product-card__price">$799</p>
<p className="product-card__price product-card__price--discount">$899</p>
<p className="product-card__price">{`${product.price}$`}</p>
<p className="product-card__price product-card__price--discount">{`${product.fullPrice}$`}</p>
<dl className="product-card__description-phone description-phone">
<dt className="description-phone--title">Screen</dt>
<dd className="description-phone--value">5.8” OLED</dd>
Expand Down
28 changes: 12 additions & 16 deletions src/pages/components/ProductsList.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
import { FC } from 'react';
// import { ProductCard } from './ProductCard';
import '../../styles/styles.scss';
import { Phone } from '../../types/Phone';
import { ProductCard } from './ProductCard';

export const ProductsList: FC = () => {
type Props = {
products: Phone[],
};

export const ProductsList: FC<Props> = ({ products }) => {
return (
<ul className="products-list">
<li className="products-list__item">
{/* <ProductCard /> */}
</li>
<li className="products-list__item">
{/* <ProductCard /> */}
</li>
<li className="products-list__item">
{/* <ProductCard /> */}
</li>
<li className="products-list__item">
{/* <ProductCard /> */}
</li>
<li className="products-list__item">
{/* <ProductCard /> */}
</li>
{products.map(product => (
<li className="products-list__item" key={product.id}>
<ProductCard product={product} />
</li>
))}
</ul>
);
};
Loading

0 comments on commit 046178a

Please sign in to comment.