Skip to content

Commit

Permalink
Merge pull request #6 from fed1v/module5-task2
Browse files Browse the repository at this point in the history
  • Loading branch information
keksobot authored Nov 11, 2024
2 parents 93187b6 + ef5fd7c commit 68b6e0f
Show file tree
Hide file tree
Showing 22 changed files with 662 additions and 452 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {Offer} from '../../types/offer.ts';
import {PlaceCardFavorite} from '../place-card/place-card-favorite.tsx';
import {FavoritePlaceCard} from './favorite-place-card.tsx';

type FavoritesListProps = {
offers: Offer[];
}

export function FavoritesList({offers}: FavoritesListProps) {
export function FavoritePlaceCardList({offers}: FavoritesListProps) {
const cities = Array.from(new Set(offers.map((offer) => offer.city.name))).toSorted();

return (
Expand All @@ -28,7 +28,7 @@ export function FavoritesList({offers}: FavoritesListProps) {
offers
.filter((offer) => offer.city.name === city)
.map((offer) => (
<PlaceCardFavorite
<FavoritePlaceCard
key={offer.id}
{...offer}
imageSrc={offer.previewImage}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type PlaceCardFavoriteProps = {
isPremium: boolean;
}

export function PlaceCardFavorite({id, title, type, imageSrc, price, isPremium}: PlaceCardFavoriteProps) {
export function FavoritePlaceCard({id, title, type, imageSrc, price, isPremium}: PlaceCardFavoriteProps) {
const offerUrl = AppRoute.Offer.replace(':id', id);

return (
Expand All @@ -21,14 +21,14 @@ export function PlaceCardFavorite({id, title, type, imageSrc, price, isPremium}:
</div>}

<div className="favorites__image-wrapper place-card__image-wrapper">
<a href="#">
<Link to={offerUrl}>
<img
className="place-card__image"
src={imageSrc}
width="150" height="110"
alt="Place image"
/>
</a>
</Link>
</div>

<div className="favorites__card-info place-card__info">
Expand Down
45 changes: 45 additions & 0 deletions src/components/header/header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {Link} from 'react-router-dom';
import {AppRoute} from '../../consts.ts';

export function Header() {
return (
<header className="header">
<div className="container">
<div className="header__wrapper">
<div className="header__left">
<Link to={AppRoute.Main} className="header__logo-link">
<img
className="header__logo"
src="img/logo.svg"
alt="6 cities logo"
width={81}
height={41}
/>
</Link>
</div>
<nav className="header__nav">
<ul className="header__nav-list">
<li className="header__nav-item user">
<a
className="header__nav-link header__nav-link--profile"
href="#"
>
<div className="header__avatar-wrapper user__avatar-wrapper"></div>
<span className="header__user-name user__name">
[email protected]
</span>
<span className="header__favorite-count">3</span>
</a>
</li>
<li className="header__nav-item">
<a className="header__nav-link" href="#">
<span className="header__signout">Sign out</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</header>
);
}
3 changes: 2 additions & 1 deletion src/components/map/map.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import leaflet from 'leaflet';
import 'leaflet/dist/leaflet.css';
import {City, Offer} from '../../types/offer.ts';
import {Offer} from '../../types/offer.ts';
import {useEffect, useRef} from 'react';
import {useMap} from './use-map.ts';
import {Nullable} from 'vitest';
import {City} from '../../types/city.ts';

type MapProps = {
city: City;
Expand Down
2 changes: 1 addition & 1 deletion src/components/map/use-map.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {MutableRefObject, useEffect, useRef, useState} from 'react';
import {City} from '../../types/offer.ts';
import {Nullable} from 'vitest';
import leaflet from 'leaflet';
import {City} from '../../types/city.ts';

export function useMap(mapRef: MutableRefObject<HTMLElement | null>, city: City) {
const [map, setMap] = useState<Nullable<leaflet.Map>>(null);
Expand Down
39 changes: 0 additions & 39 deletions src/components/offers-list/offers-list.tsx

This file was deleted.

69 changes: 69 additions & 0 deletions src/components/place-card/place-card-list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {Offer} from '../../types/offer.ts';
import {PlaceCard} from './place-card.tsx';
import {Nullable} from 'vitest';
import {PlaceCardType} from '../../consts.ts';

type GeneralPlaceCardListCommonProps = {
offers: Offer[];
onActiveItemChange?: (id: Nullable<string>) => void;
imageWidth: number;
imageHeight: number;
className: string;
placeCardType: PlaceCardType;
};

function GeneralPlaceCardList({
offers,
onActiveItemChange,
imageWidth,
imageHeight,
className,
placeCardType,
}: GeneralPlaceCardListCommonProps) {
return (
<div className={className}>
{
offers.map((offer) => (
<PlaceCard
key={offer.id}
{...offer}
imageSrc={offer.previewImage}
width={imageWidth}
height={imageHeight}
placeCardType={placeCardType}
onActiveItemChange={onActiveItemChange}
/>
))
}
</div>
);
}

type PlaceCardListProps = {
offers: Offer[];
onActiveItemChange?: (id: Nullable<string>) => void;
}

export function CityPlaceCardList(props: PlaceCardListProps) {
return (
<GeneralPlaceCardList
{...props}
imageWidth={260}
imageHeight={200}
className="cities__places-list places__list tabs__content"
placeCardType={PlaceCardType.City}
/>
);
}

export function NearPlaceCardList(props: PlaceCardListProps) {
return (
<GeneralPlaceCardList
{...props}
imageWidth={260}
imageHeight={200}
className="near-places__list places__list"
placeCardType={PlaceCardType.Near}
/>
);
}
104 changes: 65 additions & 39 deletions src/components/place-card/place-card.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Link} from 'react-router-dom';
import {AppRoute} from '../../consts.ts';
import {AppRoute, PlaceCardType} from '../../consts.ts';
import {Nullable} from 'vitest';

type PlaceCardProps = {
id: string;
Expand All @@ -8,59 +9,84 @@ type PlaceCardProps = {
imageSrc: string;
price: number;
isPremium: boolean;
onMouseEnter: (id: string) => void;
onMouseLeave: (id: string) => void;
width: number;
height: number;
onActiveItemChange?: (id: Nullable<string>) => void;
placeCardType: PlaceCardType;
}

export function PlaceCard({id, title, type, imageSrc, price, isPremium, onMouseEnter, onMouseLeave}: PlaceCardProps) {
export function PlaceCard({
id,
title,
type,
imageSrc,
price,
isPremium,
width,
height,
onActiveItemChange,
placeCardType,
}: PlaceCardProps) {
const offerUrl = AppRoute.Offer.replace(':id', id);

let classNamePrefix: string = '';

if (placeCardType === PlaceCardType.City) {
classNamePrefix = 'cities';
} else if (placeCardType === PlaceCardType.Near) {
classNamePrefix = 'near-places';
}

return (
<article
className="cities__card place-card"
onMouseEnter={() => onMouseEnter(id)}
onMouseLeave={() => onMouseLeave(id)}
className={`${classNamePrefix}__card place-card`}
onMouseEnter={() => onActiveItemChange?.(id)}
onMouseLeave={() => onActiveItemChange?.(null)}
>
{isPremium &&
<div className="place-card__mark">
<span>Premium</span>
</div>}

<div className="cities__image-wrapper place-card__image-wrapper">
<a href="#">
<img
className="place-card__image"
src={imageSrc} width="260" height="200"
alt="Place image"
/>
</a>
</div>
<div className="place-card__info">
<div className="place-card__price-wrapper">
<div className="place-card__price">
<b className="place-card__price-value">&euro;{price}</b>
<span className="place-card__price-text">&#47;&nbsp;night</span>
</div>
<button className="place-card__bookmark-button button" type="button">
<svg className="place-card__bookmark-icon" width="18" height="19">
<use xlinkHref="#icon-bookmark"></use>
</svg>
<span className="visually-hidden">To bookmarks</span>
</button>
<Link to={offerUrl}>
<div className={`${classNamePrefix}__image-wrapper place-card__image-wrapper`}>
<a href="#">
<img
className="place-card__image"
src={imageSrc} width={width} height={height}
alt="Place image"
/>
</a>
</div>
<div className="place-card__rating rating">
<div className="place-card__stars rating__stars">
<span style={{width: '80%'}}></span>
<span className="visually-hidden">Rating</span>

<div className="place-card__info">
<div className="place-card__price-wrapper">
<div className="place-card__price">
<b className="place-card__price-value">&euro;{price}</b>
<span className="place-card__price-text">&#47;&nbsp;night</span>
</div>

<button className="place-card__bookmark-button button" type="button">
<svg className="place-card__bookmark-icon" width="18" height="19">
<use xlinkHref="#icon-bookmark"></use>
</svg>
<span className="visually-hidden">To bookmarks</span>
</button>
</div>
</div>
<h2 className="place-card__name">
<Link to={offerUrl}>

<div className="place-card__rating rating">
<div className="place-card__stars rating__stars">
<span style={{width: '80%'}}></span>
<span className="visually-hidden">Rating</span>
</div>
</div>
<h2 className="place-card__name">
{title}
</Link>
</h2>
<p className="place-card__type">{type}</p>
</div>
</h2>
<p className="place-card__type">{type}</p>
</div>
</Link>

</article>
);
}
39 changes: 39 additions & 0 deletions src/components/reviews/review-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {Review} from '../../types/review.ts';

type ReviewItemProps = {
review: Review;
}

export function ReviewItem({review}: ReviewItemProps) {
return (
<li className="reviews__item">
<div className="reviews__user user">
<div className="reviews__avatar-wrapper user__avatar-wrapper">
<img
className="reviews__avatar user__avatar"
src={review.user.avatarUrl}
width={54}
height={54}
alt="Reviews avatar"
/>
</div>
<span className="reviews__user-name">{review.user.name}</span>
</div>

<div className="reviews__info">
<div className="reviews__rating rating">
<div className="reviews__stars rating__stars">
<span style={{width: '80%'}}/>
<span className="visually-hidden">Rating</span>
</div>
</div>
<p className="reviews__text">
{review.comment}
</p>
<time className="reviews__time" dateTime="2019-04-24">
{review.date}
</time>
</div>
</li>
);
}
Loading

0 comments on commit 68b6e0f

Please sign in to comment.