From 4d66a8b2fd8e6251d9bc178f62987b2b7de2e686 Mon Sep 17 00:00:00 2001 From: ktvtk Date: Sun, 17 Nov 2024 16:50:45 +0500 Subject: [PATCH] hw 6.2 --- src/components/sorting/sorting.tsx | 46 +++++++++++++++++++++++++++ src/const.ts | 19 +++++------ src/pages/main-screen/main-screen.tsx | 41 ++++++++++++------------ src/types/sort-option.ts | 4 +++ 4 files changed, 81 insertions(+), 29 deletions(-) create mode 100644 src/components/sorting/sorting.tsx create mode 100644 src/types/sort-option.ts diff --git a/src/components/sorting/sorting.tsx b/src/components/sorting/sorting.tsx new file mode 100644 index 0000000..c4a33e2 --- /dev/null +++ b/src/components/sorting/sorting.tsx @@ -0,0 +1,46 @@ +import {JSX, useState} from 'react'; +import {sortOptions} from '../../const.ts'; +import {SortOption} from '../../types/sort-option.ts'; + +type SortingProps = { + onSortChange: (option: SortOption) => void; +}; + +export function Sorting({onSortChange} : SortingProps) : JSX.Element { + const [activeSortOption, setActiveSortOption] = useState('Popular'); + const [isOptionsVisible, setIsOptionsVisible] = useState(false); + + const handleOptionClick = (option: SortOption) => { + setActiveSortOption(option); + onSortChange(option); + setIsOptionsVisible(false); + }; + + const handleListOptionClick = () => { + setIsOptionsVisible(!isOptionsVisible); + }; + + return ( +
+ Sort by + + {activeSortOption} + + + + +
    + {sortOptions.map((option) => ( +
  • handleOptionClick(option)} + > + {option} +
  • + ))} +
+
+ ); +} diff --git a/src/const.ts b/src/const.ts index 2bfda5a..9d5ac96 100644 --- a/src/const.ts +++ b/src/const.ts @@ -1,5 +1,6 @@ import {Icon} from 'leaflet'; import {City} from './types/city.ts'; +import {SortOption} from './types/sort-option.ts'; export enum AppRoute { Main = '/', @@ -20,13 +21,13 @@ export enum PlaceType { } export const defaultCustomIcon = new Icon({ - iconUrl: 'https://assets.htmlacademy.ru/content/intensive/javascript-1/demo/interactive-map/pin.svg', + iconUrl: 'public/img/pin.svg', iconSize: [40, 40], iconAnchor: [20, 40], }); export const currentCustomIcon = new Icon({ - iconUrl: 'https://assets.htmlacademy.ru/content/intensive/javascript-1/demo/interactive-map/main-pin.svg', + iconUrl: 'public/img/pin-active.svg', iconSize: [40, 40], iconAnchor: [20, 40], }); @@ -35,13 +36,6 @@ export const minCommentLength = 50; export const maxCommentLength = 300; -export enum sortOptions { - Popular = 'Popular', - Increasing = 'Price: low to high', - Decreasing = 'Price: high to low', - Rating = 'Top rated first', -} - export const Paris: City = { name: 'Paris', location: { @@ -104,3 +98,10 @@ export const Cities : City[] = [ Hamburg, Dusseldorf ]; + +export const sortOptions : SortOption[] = [ + 'Popular', + 'Price: low to high', + 'Price: high to low', + 'Top rated first', +]; diff --git a/src/pages/main-screen/main-screen.tsx b/src/pages/main-screen/main-screen.tsx index 653dda4..f3640fd 100644 --- a/src/pages/main-screen/main-screen.tsx +++ b/src/pages/main-screen/main-screen.tsx @@ -7,6 +7,8 @@ import {useState} from 'react'; import {Map} from '../../components/map/map.tsx'; import {CitiesList} from '../../components/cities-list/cities-list.tsx'; import {useAppSelector} from '../../hooks'; +import {Sorting} from '../../components/sorting/sorting.tsx'; +import {SortOption} from '../../types/sort-option.ts'; export function MainScreen(): JSX.Element { @@ -14,16 +16,29 @@ export function MainScreen(): JSX.Element { const offers = useAppSelector((state) => state.offers).filter( (offer) => offer.city.name === activeCity.name, ); - const favoritesCount = offers.filter((offer) => offer.isFavorite).length; - const [activeOfferId, setActiveOfferId] = useState(null); - const selectedOffer = offers.find((offer) => offer.id === activeOfferId); - const placesFoundCaption = offers.length === 0 ? 'No places to stay available' : `${offers.length} places to stay in ${activeCity.name}`; + const [sortingOption, setSortingOption] = useState('Popular'); + const sortedOffers = [...offers].sort((a, b) => { + switch (sortingOption) { + case 'Price: low to high': + return a.price - b.price; + case 'Price: high to low': + return b.price - a.price; + case 'Top rated first': + return b.rating - a.rating; + default: + return 0; + } + }); + const handleSortChange = (option: SortOption) => { + setSortingOption(option); + }; + return (
@@ -69,22 +84,8 @@ export function MainScreen(): JSX.Element {

Places

{placesFoundCaption} -
- Sort by - - Popular - - - - -
    -
  • Popular
  • -
  • Price: low to high
  • -
  • Price: high to low
  • -
  • Top rated first
  • -
-
- + +