Skip to content

Commit

Permalink
Merge pull request #4 from GlebKochergin/module4-task1
Browse files Browse the repository at this point in the history
  • Loading branch information
keksobot authored Nov 5, 2024
2 parents 375dae3 + eb508e2 commit 1be603c
Show file tree
Hide file tree
Showing 32 changed files with 420 additions and 342 deletions.
50 changes: 0 additions & 50 deletions src/components/PlaceCard.tsx

This file was deleted.

30 changes: 0 additions & 30 deletions src/components/app/App.tsx

This file was deleted.

31 changes: 31 additions & 0 deletions src/components/app/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import { MainPage } from '../../pages/main-page.tsx';
import { LoginPage } from '../../pages/login-page.tsx';
import { OfferPage } from '../../pages/offer-page.tsx';
import { NotFoundPage } from '../../pages/not-found-page.tsx';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import { AppRoutesProps } from '../../props/app-routes-props.tsx';
import { Authorization } from '../authorization.tsx';
import { FavoritesPage } from '../../pages/favorites-page.tsx';
import { offers } from '../../mocks/offers.ts';
import { AppProps } from '../../props/app-props.tsx';

export function App({placeCount}: AppProps): React.JSX.Element {
return (
<BrowserRouter>
<Routes>
<Route path={AppRoutesProps.MainPage} element={<MainPage placeCount={placeCount} offers={offers}/>} />
<Route path={AppRoutesProps.LoginPage} element={<LoginPage />} />
<Route path={AppRoutesProps.FavoritesPage}
element={
<Authorization isAuthorized={false}>
<FavoritesPage favorites={offers}/>
</Authorization>
}
/>
<Route path={AppRoutesProps.OfferPage} element={<OfferPage />} />
<Route path="*" element={<NotFoundPage />} />
</Routes>
</BrowserRouter>
);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Navigate } from 'react-router-dom';
import { AppRoutesProps } from '../props/AppRoutesProps.tsx';
import { AppRoutesProps } from '../props/app-routes-props.tsx';

interface AuthorizationProps {
isAuthorized: boolean;
Expand Down
118 changes: 118 additions & 0 deletions src/components/comment-form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { useState } from 'react';

export function CommentForm() {
const [text, setText] = useState('');
return (
<form className="reviews__form form" action="#" method="post">
<label className="reviews__label form__label" htmlFor="review">
Your review
</label>
<div className="reviews__rating-form form__rating">
<input
className="form__rating-input visually-hidden"
name="rating"
defaultValue={5}
id="5-stars"
type="radio"
/>
<label
htmlFor="5-stars"
className="reviews__rating-label form__rating-label"
title="perfect"
>
<svg className="form__star-image" width={37} height={33}>
<use xlinkHref="#icon-star" />
</svg>
</label>
<input
className="form__rating-input visually-hidden"
name="rating"
defaultValue={4}
id="4-stars"
type="radio"
/>
<label
htmlFor="4-stars"
className="reviews__rating-label form__rating-label"
title="good"
>
<svg className="form__star-image" width={37} height={33}>
<use xlinkHref="#icon-star" />
</svg>
</label>
<input
className="form__rating-input visually-hidden"
name="rating"
defaultValue={3}
id="3-stars"
type="radio"
/>
<label
htmlFor="3-stars"
className="reviews__rating-label form__rating-label"
title="not bad"
>
<svg className="form__star-image" width={37} height={33}>
<use xlinkHref="#icon-star" />
</svg>
</label>
<input
className="form__rating-input visually-hidden"
name="rating"
defaultValue={2}
id="2-stars"
type="radio"
/>
<label
htmlFor="2-stars"
className="reviews__rating-label form__rating-label"
title="badly"
>
<svg className="form__star-image" width={37} height={33}>
<use xlinkHref="#icon-star" />
</svg>
</label>
<input
className="form__rating-input visually-hidden"
name="rating"
defaultValue={1}
id="1-star"
type="radio"
/>
<label
htmlFor="1-star"
className="reviews__rating-label form__rating-label"
title="terribly"
>
<svg className="form__star-image" width={37} height={33}>
<use xlinkHref="#icon-star" />
</svg>
</label>
</div>
<textarea
className="reviews__textarea form__textarea"
id="review"
name="review"
placeholder="Tell how was your stay, what you like and what can be improved"
onChange={(evt) => setText(evt.target.value)}
value={text}
>
</textarea>
<div className="reviews__button-wrapper">
<p className="reviews__help">
To submit review please make sure to set{' '}
<span className="reviews__star">rating</span> and describe your stay
with at least <b className="reviews__text-amount">50 characters</b>.
</p>
<button
className="reviews__submit form__submit button"
type="submit"
disabled={undefined}
onClick={(evt) => evt.preventDefault()}
>
Submit
</button>
</div>
</form>
);
}
12 changes: 12 additions & 0 deletions src/components/favorites-list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { FavoritesListProps } from '../props/favorites-list-props.tsx';
import { PlaceCard } from './place-card.tsx';

export function FavoritesList({ favorites }: FavoritesListProps) {
return (
<div className="favorites__places">
{favorites.map((favorite) => (
<PlaceCard key={favorite.id} offer={favorite} />
))}
</div>
);
}
16 changes: 16 additions & 0 deletions src/components/logo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Link } from 'react-router-dom';
import { AppRoutesProps } from '../props/app-routes-props.tsx';

export function Logo() {
return(
<Link className="header__logo-link header__logo-link--active" to={AppRoutesProps.MainPage}>
<img
className="header__logo"
src="img/logo.svg"
alt="6 cities logo"
width={81}
height={41}
/>
</Link>
);
}
12 changes: 12 additions & 0 deletions src/components/offers-list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {OffersListProps} from '../props/offers-list-props.tsx';
import {PlaceCard} from './place-card.tsx';

export function OffersList({ offers }: OffersListProps) {
return (
<div className="cities__places-list places__list tabs__content">
{offers.map((offer) => (
<PlaceCard key={offer.id} offer={offer} />
))}
</div>
);
}
59 changes: 59 additions & 0 deletions src/components/place-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { useState } from 'react';
import { PlaceCardProps } from '../props/place-card-props.tsx';
import {Link} from 'react-router-dom';

export function PlaceCard({offer}: PlaceCardProps): React.JSX.Element {
const [, setActive] = useState('');
return (
<article
className="cities__card place-card"
onMouseOver={() => setActive(offer.id.toString())}
>
{offer.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={offer.imageUrl}
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;{offer.price}</b>
<span className="place-card__price-text">&#47;&nbsp;night</span>
</div>
<button
className="place-card__bookmark-button place-card__bookmark-button--active button"
type="button"
>
<svg className="place-card__bookmark-icon" width="18" height="19">
{offer.isFavorite && <use xlinkHref="#icon-bookmark"></use>}
</svg>
<span className="visually-hidden">In bookmarks</span>
</button>
</div>
<div className="place-card__rating rating">
<div className="place-card__stars rating__stars">
<span style={{ width: `${(offer.rating / 5) * 100}%` }}></span>
<span className="visually-hidden">Rating</span>
</div>
</div>
<h2 className="place-card__name">
<Link to={`/offer/${offer.id}`} state={offer}>
{offer.title}
</Link>
</h2>
<p className="place-card__type">{offer.type}</p>
</div>
</article>
);
}
7 changes: 4 additions & 3 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import { App } from './components/app/App.tsx';
import { App } from './components/app/app.tsx';
import { offers } from './mocks/offers.ts';

const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);

const placeCount = 100;
const placeCount = 64;

root.render(
<React.StrictMode>
<App placeCount={placeCount}/>
<App placeCount={placeCount} offers={offers} favorites={offers}/>
</React.StrictMode>
);
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export enum PlaceType {
Apartment = 'Apartment',
Hotel = 'Hotel',
House = 'House',
Room = 'Room',
}
13 changes: 13 additions & 0 deletions src/internal/types/offer-type.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {PlaceType} from '../enums/place-type-enum.tsx';

export type Offer = {
id: number;
title: string;
rating: number;
type: PlaceType;
price: number;
imageUrl: string;
isPremium: boolean;
isBookmarked: boolean;
isFavorite: boolean;
};
Loading

0 comments on commit 1be603c

Please sign in to comment.