Skip to content

Commit

Permalink
Merge pull request #8 from ktvtk/module6-task2
Browse files Browse the repository at this point in the history
  • Loading branch information
keksobot authored Nov 17, 2024
2 parents 28d50d8 + 4d66a8b commit 50675c1
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 29 deletions.
46 changes: 46 additions & 0 deletions src/components/sorting/sorting.tsx
Original file line number Diff line number Diff line change
@@ -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<SortOption>('Popular');
const [isOptionsVisible, setIsOptionsVisible] = useState<boolean>(false);

const handleOptionClick = (option: SortOption) => {
setActiveSortOption(option);
onSortChange(option);
setIsOptionsVisible(false);
};

const handleListOptionClick = () => {
setIsOptionsVisible(!isOptionsVisible);
};

return (
<form className="places__sorting" action="#" method="get">
<span className="places__sorting-caption">Sort by</span>
<span className="places__sorting-type" tabIndex={0} onClick={handleListOptionClick}>
{activeSortOption}
<svg className="places__sorting-arrow" width="7" height="4">
<use xlinkHref="#icon-arrow-select"></use>
</svg>
</span>
<ul className={`places__options places__options--custom ${isOptionsVisible ? 'places__options--opened' : ''}`}>
{sortOptions.map((option) => (
<li
key={option}
className={`places__option ${option === activeSortOption ? 'places__option--active' : ''}`}
tabIndex={0}
onClick={() => handleOptionClick(option)}
>
{option}
</li>
))}
</ul>
</form>
);
}
19 changes: 10 additions & 9 deletions src/const.ts
Original file line number Diff line number Diff line change
@@ -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 = '/',
Expand All @@ -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],
});
Expand All @@ -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: {
Expand Down Expand Up @@ -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',
];
41 changes: 21 additions & 20 deletions src/pages/main-screen/main-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,38 @@ 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 {
const activeCity = useAppSelector((state) => state.activeCity);
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<string | null>(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<SortOption>('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 (
<div className="page page--gray page--main">
Expand Down Expand Up @@ -69,22 +84,8 @@ export function MainScreen(): JSX.Element {
<section className="cities__places places">
<h2 className="visually-hidden">Places</h2>
<b className="places__found">{placesFoundCaption}</b>
<form className="places__sorting" action="#" method="get">
<span className="places__sorting-caption">Sort by</span>
<span className="places__sorting-type" tabIndex={0}>
Popular
<svg className="places__sorting-arrow" width="7" height="4">
<use xlinkHref="#icon-arrow-select"></use>
</svg>
</span>
<ul className="places__options places__options--custom places__options--opened">
<li className="places__option places__option--active" tabIndex={0}>Popular</li>
<li className="places__option" tabIndex={0}>Price: low to high</li>
<li className="places__option" tabIndex={0}>Price: high to low</li>
<li className="places__option" tabIndex={0}>Top rated first</li>
</ul>
</form>
<OffersList offers={offers} onChange={setActiveOfferId}/>
<Sorting onSortChange={handleSortChange}/>
<OffersList offers={sortedOffers} onChange={setActiveOfferId}/>
</section>
<div className="cities__right-section">
<Map
Expand Down
4 changes: 4 additions & 0 deletions src/types/sort-option.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type SortOption = 'Popular'
| 'Price: low to high'
| 'Price: high to low'
| 'Top rated first';

0 comments on commit 50675c1

Please sign in to comment.