Repository: htmlacademy-react/49149-six-cities-3
Pull request #3: Маршрут по тайным тропам
Author: login: vigolajnen
Created: 2025-03-05T20:56:23Z | Merged: 2025-03-09T21:10:17Z

1. Создала отдельный компонент для страницы «404» - PageNotFound;
2. В App описала все маршруты в приложении. По каждому адресу должен отображается соответствующий компонент страницы:
- Main /
- Login /login
- Favorites /favorites
- Offer /offer/:id
3. Добавила компонент обертку для приватного маршрута - PrivateRoute.

---
:mortar_board: [Маршрут по тайным тропам](https://up.htmlacademy.ru/react-individual/3/user/49149/tasks/5)


Diff:
diff --git a/src/components/App.tsx b/src/components/App.tsx
index 6555cec..28937aa 100644
--- a/src/components/App.tsx
+++ b/src/components/App.tsx
@@ -1,14 +1,30 @@
+import { BrowserRouter, Route, Routes } from 'react-router-dom';
 
-import { PlaceCardProps } from '../types';
 import Main from './Main';
+import Login from './Login';
+import Offer from './Offer';
+import Favorites from './Favorites';
+import PrivateRoute from './PrivateRoute';
+import PageNotFound from './PageNotFound';
+import { Paths } from '../enums/paths';
 
-type AppProps = {
-  data: PlaceCardProps[];
-};
-
-export default function App({data}: AppProps): JSX.Element {
+export default function App(): JSX.Element {
   return (
-    <Main cards={data} />
+    <BrowserRouter>
+      <Routes>
+        <Route path={Paths.Main} element={<Main />} />
+        <Route path={Paths.Login} element={<Login />} />
+        <Route
+          path={Paths.Favorites}
+          element={
+            <PrivateRoute>
+              <Favorites />
+            </PrivateRoute>
+          }
+        />
+        <Route path={Paths.Offer} element={<Offer />} />
+        <Route path='*' element={<PageNotFound />} />
+      </Routes>
+    </BrowserRouter>
   );
 }
-
diff --git a/src/components/Favorites.tsx b/src/components/Favorites.tsx
index 9ad9abd..fad42db 100644
--- a/src/components/Favorites.tsx
+++ b/src/components/Favorites.tsx
@@ -1,3 +1,18 @@
+import { Link } from 'react-router-dom';
+
+import { Place } from '../types';
+import { FAVORITE_PLACES } from '../data';
+import PlaceCard from './PlaceCard';
+import { Paths } from '../enums/paths';
+
+const filterFavoritePlacesByCity = (city: string, data: Place[]) => {
+  const filteredPlaces = data.filter((place: Place) => place.city === city);
+  return filteredPlaces;
+};
+
+const amsterdamFavorites = filterFavoritePlacesByCity('Amsterdam', FAVORITE_PLACES);
+const cologneFavorites = filterFavoritePlacesByCity('Cologne', FAVORITE_PLACES);
+
 export default function Favorites() {
   return (
     <div className='page'>
@@ -5,9 +20,9 @@ export default function Favorites() {
         <div className='container'>
           <div className='header__wrapper'>
             <div className='header__left'>
-              <a className='header__logo-link' href='main.html'>
+              <Link className='header__logo-link' to={Paths.Main}>
                 <img className='header__logo' src='img/logo.svg' alt='6 cities logo' width='81' height='41' />
-              </a>
+              </Link>
             </div>
             <nav className='header__nav'>
               <ul className='header__nav-list'>
@@ -43,72 +58,9 @@ export default function Favorites() {
                   </div>
                 </div>
                 <div className='favorites__places'>
-                  <article className='favorites__card place-card'>
-                    <div className='place-card__mark'>
-                      <span>Premium</span>
-                    </div>
-                    <div className='favorites__image-wrapper place-card__image-wrapper'>
-                      <a href='#'>
-                        <img className='place-card__image' src='img/apartment-small-03.jpg' width='150' height='110' alt='Place image' />
-                      </a>
-                    </div>
-                    <div className='favorites__card-info place-card__info'>
-                      <div className='place-card__price-wrapper'>
-                        <div className='place-card__price'>
-                          <b className='place-card__price-value'>&euro;180</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'>
-                            <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: '100%' }}></span>
-                          <span className='visually-hidden'>Rating</span>
-                        </div>
-                      </div>
-                      <h2 className='place-card__name'>
-                        <a href='#'>Nice, cozy, warm big bed apartment</a>
-                      </h2>
-                      <p className='place-card__type'>Apartment</p>
-                    </div>
-                  </article>
-
-                  <article className='favorites__card place-card'>
-                    <div className='favorites__image-wrapper place-card__image-wrapper'>
-                      <a href='#'>
-                        <img className='place-card__image' src='img/room-small.jpg' width='150' height='110' alt='Place image' />
-                      </a>
-                    </div>
-                    <div className='favorites__card-info place-card__info'>
-                      <div className='place-card__price-wrapper'>
-                        <div className='place-card__price'>
-                          <b className='place-card__price-value'>&euro;80</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'>
-                            <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: '80%' }}></span>
-                          <span className='visually-hidden'>Rating</span>
-                        </div>
-                      </div>
-                      <h2 className='place-card__name'>
-                        <a href='#'>Wood and stone place</a>
-                      </h2>
-                      <p className='place-card__type'>Room</p>
-                    </div>
-                  </article>
+                  {amsterdamFavorites.map((place: Place) => (
+                    <PlaceCard key={place.name} card={place} styled='favorites' isBookmarkActive />
+                  ))}
                 </div>
               </li>
 
@@ -121,37 +73,9 @@ export default function Favorites() {
                   </div>
                 </div>
                 <div className='favorites__places'>
-                  <article className='favorites__card place-card'>
-                    <div className='favorites__image-wrapper place-card__image-wrapper'>
-                      <a href='#'>
-                        <img className='place-card__image' src='img/apartment-small-04.jpg' width='150' height='110' alt='Place image' />
-                      </a>
-                    </div>
-                    <div className='favorites__card-info place-card__info'>
-                      <div className='place-card__price-wrapper'>
-                        <div className='place-card__price'>
-                          <b className='place-card__price-value'>&euro;180</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'>
-                            <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: '100%' }}></span>
-                          <span className='visually-hidden'>Rating</span>
-                        </div>
-                      </div>
-                      <h2 className='place-card__name'>
-                        <a href='#'>White castle</a>
-                      </h2>
-                      <p className='place-card__type'>Apartment</p>
-                    </div>
-                  </article>
+                  {cologneFavorites.map((place: Place) => (
+                    <PlaceCard key={place.name} card={place} styled='favorites' isBookmarkActive />
+                  ))}
                 </div>
               </li>
             </ul>
@@ -159,9 +83,9 @@ export default function Favorites() {
         </div>
       </main>
       <footer className='footer container'>
-        <a className='footer__logo-link' href='main.html'>
+        <Link className='footer__logo-link' to={Paths.Main}>
           <img className='footer__logo' src='img/logo.svg' alt='6 cities logo' width='64' height='33' />
-        </a>
+        </Link>
       </footer>
     </div>
   );
diff --git a/src/components/FavoritesEmpty.tsx b/src/components/FavoritesEmpty.tsx
index 37a52b7..31ae058 100644
--- a/src/components/FavoritesEmpty.tsx
+++ b/src/components/FavoritesEmpty.tsx
@@ -1,3 +1,6 @@
+import { Link } from 'react-router-dom';
+import { Paths } from '../enums/paths';
+
 export default function FavoritesEmpty() {
   return (
     <div className='page page--favorites-empty'>
@@ -5,9 +8,9 @@ export default function FavoritesEmpty() {
         <div className='container'>
           <div className='header__wrapper'>
             <div className='header__left'>
-              <a className='header__logo-link' href='main.html'>
+              <Link className='header__logo-link' to={Paths.Main}>
                 <img className='header__logo' src='img/logo.svg' alt='6 cities logo' width='81' height='41' />
-              </a>
+              </Link>
             </div>
             <nav className='header__nav'>
               <ul className='header__nav-list'>
@@ -41,9 +44,9 @@ export default function FavoritesEmpty() {
         </div>
       </main>
       <footer className='footer'>
-        <a className='footer__logo-link' href='main.html'>
+        <Link className='footer__logo-link' to={Paths.Main}>
           <img className='footer__logo' src='img/logo.svg' alt='6 cities logo' width='64' height='33' />
-        </a>
+        </Link>
       </footer>
     </div>
   );
diff --git a/src/components/Login.tsx b/src/components/Login.tsx
index b415324..07f6b92 100644
--- a/src/components/Login.tsx
+++ b/src/components/Login.tsx
@@ -5,7 +5,7 @@ export default function Login() {
         <div className='container'>
           <div className='header__wrapper'>
             <div className='header__left'>
-              <a className='header__logo-link' href='main.html'>
+              <a className='header__logo-link'>
                 <img className='header__logo' src='img/logo.svg' alt='6 cities logo' width='81' height='41' />
               </a>
             </div>
diff --git a/src/components/Main.tsx b/src/components/Main.tsx
index 6addd30..3fff764 100644
--- a/src/components/Main.tsx
+++ b/src/components/Main.tsx
@@ -1,11 +1,8 @@
-import { PlaceCardProps } from '../types';
+import { PLACES } from '../data';
+import { Place } from '../types';
 import PlaceCard from './PlaceCard';
 
-type MainProps = {
-  cards: PlaceCardProps[];
-};
-
-export default function Main({ cards }: MainProps): JSX.Element {
+export default function Main() {
   return (
     <div className='page page--gray page--main'>
       <header className='header'>
@@ -103,8 +100,8 @@ export default function Main({ cards }: MainProps): JSX.Element {
                 </ul>
               </form>
               <div className='cities__places-list places__list tabs__content'>
-                {cards.map((v) => (
-                  <PlaceCard key={v.name} card={v} />
+                {PLACES.map((place: Place) => (
+                  <PlaceCard key={place.name} card={place} />
                 ))}
               </div>
             </section>
diff --git a/src/components/Offer.tsx b/src/components/Offer.tsx
index e90a83f..d2bbe25 100644
--- a/src/components/Offer.tsx
+++ b/src/components/Offer.tsx
@@ -1,13 +1,29 @@
+import { Link, useParams } from 'react-router-dom';
+import PageNotFound from './PageNotFound';
+import { Place } from '../types';
+import PlaceCard from './PlaceCard';
+import { PLACES } from '../data';
+import { Paths } from '../enums/paths';
+
+
 export default function Offer() {
+  const { id } = useParams();
+  const data = PLACES.filter((place: Place) => place.id === +id!)[0];
+  const dataOther = PLACES.filter((place: Place) => place.id !== +id!);
+
+  if (!data) {
+    return <PageNotFound />;
+  }
+
   return (
     <div className='page'>
       <header className='header'>
         <div className='container'>
           <div className='header__wrapper'>
             <div className='header__left'>
-              <a className='header__logo-link' href='main.html'>
+              <Link className='header__logo-link' to={Paths.Main}>
                 <img className='header__logo' src='img/logo.svg' alt='6 cities logo' width='81' height='41' />
-              </a>
+              </Link>
             </div>
             <nav className='header__nav'>
               <ul className='header__nav-list'>
@@ -55,11 +71,13 @@ export default function Offer() {
           </div>
           <div className='offer__container container'>
             <div className='offer__wrapper'>
-              <div className='offer__mark'>
-                <span>Premium</span>
-              </div>
+              {data.isPremium && (
+                <div className='offer__mark'>
+                  <span>Premium</span>
+                </div>
+              )}
               <div className='offer__name-wrapper'>
-                <h1 className='offer__name'>Beautiful &amp; luxurious studio at great location</h1>
+                <h1 className='offer__name'>{data.name}</h1>
                 <button className='offer__bookmark-button button' type='button'>
                   <svg className='offer__bookmark-icon' width='31' height='33'>
                     <use xlinkHref='#icon-bookmark'></use>
@@ -69,7 +87,7 @@ export default function Offer() {
               </div>
               <div className='offer__rating rating'>
                 <div className='offer__stars rating__stars'>
-                  <span style={{ width: '80%' }}></span>
+                  <span style={{ width: data.rating }}></span>
                   <span className='visually-hidden'>Rating</span>
                 </div>
                 <span className='offer__rating-value rating__value'>4.8</span>
@@ -80,7 +98,7 @@ export default function Offer() {
                 <li className='offer__feature offer__feature--adults'>Max 4 adults</li>
               </ul>
               <div className='offer__price'>
-                <b className='offer__price-value'>&euro;120</b>
+                <b className='offer__price-value'>&euro;{data.price}</b>
                 <span className='offer__price-text'>&nbsp;night</span>
               </div>
               <div className='offer__inside'>
@@ -199,104 +217,9 @@ export default function Offer() {
           <section className='near-places places'>
             <h2 className='near-places__title'>Other places in the neighbourhood</h2>
             <div className='near-places__list places__list'>
-              <article className='near-places__card place-card'>
-                <div className='near-places__image-wrapper place-card__image-wrapper'>
-                  <a href='#'>
-                    <img className='place-card__image' src='img/room.jpg' 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;80</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'>
-                        <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: '80%' }}></span>
-                      <span className='visually-hidden'>Rating</span>
-                    </div>
-                  </div>
-                  <h2 className='place-card__name'>
-                    <a href='#'>Wood and stone place</a>
-                  </h2>
-                  <p className='place-card__type'>Room</p>
-                </div>
-              </article>
-
-              <article className='near-places__card place-card'>
-                <div className='near-places__image-wrapper place-card__image-wrapper'>
-                  <a href='#'>
-                    <img className='place-card__image' src='img/apartment-02.jpg' 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;132</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 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'>
-                    <a href='#'>Canal View Prinsengracht</a>
-                  </h2>
-                  <p className='place-card__type'>Apartment</p>
-                </div>
-              </article>
-
-              <article className='near-places__card place-card'>
-                <div className='place-card__mark'>
-                  <span>Premium</span>
-                </div>
-                <div className='near-places__image-wrapper place-card__image-wrapper'>
-                  <a href='#'>
-                    <img className='place-card__image' src='img/apartment-03.jpg' 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;180</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 className='place-card__rating rating'>
-                    <div className='place-card__stars rating__stars'>
-                      <span style={{ width: '100%' }}></span>
-                      <span className='visually-hidden'>Rating</span>
-                    </div>
-                  </div>
-                  <h2 className='place-card__name'>
-                    <a href='#'>Nice, cozy, warm big bed apartment</a>
-                  </h2>
-                  <p className='place-card__type'>Apartment</p>
-                </div>
-              </article>
+              {dataOther.map((v: Place) => (
+                <PlaceCard key={v.id} card={v} styled='near-places' />
+              ))}
             </div>
           </section>
         </div>
diff --git a/src/components/OfferNotLogged.tsx b/src/components/OfferNotLogged.tsx
index 7052a3e..9e78ca1 100644
--- a/src/components/OfferNotLogged.tsx
+++ b/src/components/OfferNotLogged.tsx
@@ -1,3 +1,6 @@
+import { Link } from 'react-router-dom';
+import { Paths } from '../enums/paths';
+
 export default function OfferNotLogged() {
   return (
     <div className='page'>
@@ -5,9 +8,9 @@ export default function OfferNotLogged() {
         <div className='container'>
           <div className='header__wrapper'>
             <div className='header__left'>
-              <a className='header__logo-link' href='main.html'>
+              <Link className='header__logo-link' to={Paths.Main}>
                 <img className='header__logo' src='img/logo.svg' alt='6 cities logo' width='81' height='41' />
-              </a>
+              </Link>
             </div>
             <nav className='header__nav'>
               <ul className='header__nav-list'>
diff --git a/src/components/PageNotFound.tsx b/src/components/PageNotFound.tsx
new file mode 100644
index 0000000..164b78e
--- /dev/null
+++ b/src/components/PageNotFound.tsx
@@ -0,0 +1,37 @@
+import { Link } from 'react-router-dom';
+import { Paths } from '../enums/paths';
+
+export default function PageNotFound() {
+  return (
+    <div className='page page--gray page--main'>
+      <header className='header'>
+        <div className='container'>
+          <div className='header__wrapper'>
+            <div className='header__left'>
+              <Link className='header__logo-link header__logo-link--active' to={Paths.Main}>
+                <img className='header__logo' src='img/logo.svg' alt='6 cities logo' width='81' height='41' />
+              </Link>
+            </div>
+          </div>
+        </div>
+      </header>
+
+      <main className='page__main page__main--index page__main--index-empty'>
+        <div className='cities'>
+          <div className='cities__places-container cities__places-container--empty container'>
+            <section className='cities__no-places'>
+              <div className='cities__status-wrapper tabs__content'>
+                <b className='cities__status'>404</b>
+                <p className='cities__status-description'>Нет такой страницы</p>
+                <Link to={Paths.Main} style={{ textDecoration: 'underline' }}>
+                  На главную
+                </Link>
+              </div>
+            </section>
+            <div className='cities__right-section'></div>
+          </div>
+        </div>
+      </main>
+    </div>
+  );
+}
diff --git a/src/components/PlaceCard.tsx b/src/components/PlaceCard.tsx
index 3c09509..923dbda 100644
--- a/src/components/PlaceCard.tsx
+++ b/src/components/PlaceCard.tsx
@@ -1,34 +1,38 @@
-import { PlaceCardProps } from '../types';
+import { Link } from 'react-router-dom';
+import { Place } from '../types';
+import { Paths } from '../enums/paths';
 
 type CardProps = {
-  card: PlaceCardProps;
+  card: Place;
+  styled?: string;
+  isBookmarkActive?: boolean;
 };
 
-export default function PlaceCard({ card }: CardProps): JSX.Element {
-  const { name, price, rating, type, poster, isPremium } = card;
+export default function PlaceCard({ card, styled = 'cities', isBookmarkActive = false }: CardProps): JSX.Element {
+  const { name, price, rating, type, poster, isPremium, id } = card;
   return (
-    <article className='cities__card place-card'>
+    <article className={`${styled}__card place-card`}>
       {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={poster} width='260' height='200' alt='Place image' />
-        </a>
+      <div className={`${styled}__image-wrapper place-card__image-wrapper`}>
+        <Link to={Paths.Offer.replace(':id', String(id))}>
+          <img className='place-card__image' src={poster} width={styled === 'favorites' ? '150' : '260'} height={styled === 'favorites' ? '110' : '200'} alt='Place image' />
+        </Link>
       </div>
-      <div className='place-card__info'>
+      <div className={`${styled}__card-info 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'>
+          <button className={`place-card__bookmark-button button ${isBookmarkActive ? 'place-card__bookmark-button--active' : ''}`} 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>
+            <span className='visually-hidden'>{isBookmarkActive ? 'In bookmarks' : 'To bookmarks'}</span>
           </button>
         </div>
         <div className='place-card__rating rating'>
@@ -38,7 +42,7 @@ export default function PlaceCard({ card }: CardProps): JSX.Element {
           </div>
         </div>
         <h2 className='place-card__name'>
-          <a href='#'>{name}</a>
+          <Link to={Paths.Offer.replace(':id', String(id))}>{name}</Link>
         </h2>
         <p className='place-card__type'>{type}</p>
       </div>
diff --git a/src/components/PrivateRoute.tsx b/src/components/PrivateRoute.tsx
new file mode 100644
index 0000000..0469026
--- /dev/null
+++ b/src/components/PrivateRoute.tsx
@@ -0,0 +1,11 @@
+import { Navigate } from 'react-router-dom';
+import { Paths } from '../enums/paths';
+
+type PrivateRouteProps = {
+  children: JSX.Element;
+  hasAccess?: boolean;
+};
+
+export default function PrivateRoute({ children, hasAccess = false }: PrivateRouteProps) {
+  return hasAccess ? children : <Navigate to={Paths.Login} />;
+}
diff --git a/src/data.ts b/src/data.ts
index 0f0db19..251afc6 100644
--- a/src/data.ts
+++ b/src/data.ts
@@ -1,7 +1,9 @@
-import { PlaceCardProps } from './types';
+import { Place } from './types';
 
-export const DATA: PlaceCardProps[] = [
+export const PLACES: Place[] = [
   {
+    id: 1,
+    city: 'Amsterdam',
     name: 'Beautiful &amp; luxurious apartment at great location',
     price: 80,
     rating: '80%',
@@ -10,6 +12,8 @@ export const DATA: PlaceCardProps[] = [
     poster: 'img/apartment-01.jpg',
   },
   {
+    id: 2,
+    city: 'Amsterdam',
     name: 'Canal View Prinsengracht',
     price: 132,
     rating: '80%',
@@ -18,6 +22,8 @@ export const DATA: PlaceCardProps[] = [
     poster: 'img/apartment-02.jpg',
   },
   {
+    id: 3,
+    city: 'Amsterdam',
     name: 'Nice, cozy, warm big bed apartment',
     price: 180,
     rating: '100%',
@@ -26,6 +32,8 @@ export const DATA: PlaceCardProps[] = [
     poster: 'img/apartment-03.jpg',
   },
   {
+    id: 4,
+    city: 'Amsterdam',
     name: 'Wood and stone place',
     price: 80,
     rating: '80%',
@@ -34,3 +42,36 @@ export const DATA: PlaceCardProps[] = [
     poster: 'img/room.jpg',
   },
 ];
+
+export const FAVORITE_PLACES: Place[] = [
+  {
+    id: 1,
+    city: 'Amsterdam',
+    name: 'Nice, cozy, warm big bed apartment',
+    price: 180,
+    rating: '100%',
+    type: 'Apartment',
+    isPremium: true,
+    poster: 'img/apartment-small-03.jpg',
+  },
+  {
+    id: 2,
+    city: 'Amsterdam',
+    name: 'Wood and stone place',
+    price: 80,
+    rating: '80%',
+    type: 'Room',
+    isPremium: false,
+    poster: 'img/room-small.jpg',
+  },
+  {
+    id: 3,
+    city: 'Cologne',
+    name: 'White castle',
+    price: 180,
+    rating: '100%',
+    type: 'Apartment',
+    isPremium: true,
+    poster: 'img/apartment-small-04.jpg',
+  },
+];
diff --git a/src/enums/paths.ts b/src/enums/paths.ts
new file mode 100644
index 0000000..fca6ca2
--- /dev/null
+++ b/src/enums/paths.ts
@@ -0,0 +1,6 @@
+export enum Paths {
+  Main = '/',
+  Login = '/login',
+  Favorites = '/favorites',
+  Offer = '/offer/:id',
+}
diff --git a/src/index.tsx b/src/index.tsx
index be608fb..4af2389 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,7 +1,6 @@
 import React from 'react';
 import ReactDOM from 'react-dom/client';
 
-import { DATA } from './data';
 import App from './components/App';
 
 const root = ReactDOM.createRoot(
@@ -10,6 +9,6 @@ const root = ReactDOM.createRoot(
 
 root.render(
   <React.StrictMode>
-    <App data={DATA} />
+    <App />
   </React.StrictMode>
 );
diff --git a/src/types.ts b/src/types.ts
index 629a1d6..dac9eb4 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -1,8 +1,10 @@
-export type PlaceCardProps = {
+export type Place = {
+  id: number;
+  city: string;
   name: string;
   poster: string;
   price: number;
   rating: string;
   type: string;
   isPremium?: boolean;
-}
+};


Reviews:
user: login: rLukoyanov
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T15:50:13Z
user: login: rLukoyanov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T15:56:26Z
user: login: vigolajnen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T16:54:40Z
user: login: vigolajnen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T16:54:51Z
user: login: rLukoyanov
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T10:49:23Z
user: login: rLukoyanov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T10:50:33Z
user: login: vigolajnen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-09T16:47:42Z

Review comments:
diff_hunk: @@ -1,13 +1,24 @@
+import { Link } from 'react-router-dom';
+import { DATA_FAVORITES } from '../data';
+import { FavoritesCardProps } from '../types';
+import PlaceCard from './PlaceCard';
+
 export default function Favorites() {
+  const getCityFavorites = (city: string, data: FavoritesCardProps[]) => {
+    const result = data.filter((v: FavoritesCardProps) => v.city === city);
path: src/components/Favorites.tsx
user: login: rLukoyanov
body: `result` => переименовать  `cityBookingPlaces` (Примерно)
created_at: 2025-03-06T15:37:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,13 +1,24 @@
+import { Link } from 'react-router-dom';
+import { DATA_FAVORITES } from '../data';
+import { FavoritesCardProps } from '../types';
+import PlaceCard from './PlaceCard';
+
 export default function Favorites() {
+  const getCityFavorites = (city: string, data: FavoritesCardProps[]) => {
+    const result = data.filter((v: FavoritesCardProps) => v.city === city);
+    return result;
+  };
+  const dataAmsterdam = getCityFavorites('Amsterdam', DATA_FAVORITES);
+  const dataCologne = getCityFavorites('Cologne', DATA_FAVORITES);
path: src/components/Favorites.tsx
user: login: rLukoyanov
body: Выносим выше компоненты
created_at: 2025-03-06T15:41:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -43,72 +54,9 @@ export default function Favorites() {
                   </div>
                 </div>
                 <div className='favorites__places'>
-                  <article className='favorites__card place-card'>
-                    <div className='place-card__mark'>
-                      <span>Premium</span>
-                    </div>
-                    <div className='favorites__image-wrapper place-card__image-wrapper'>
-                      <a href='#'>
-                        <img className='place-card__image' src='img/apartment-small-03.jpg' width='150' height='110' alt='Place image' />
-                      </a>
-                    </div>
-                    <div className='favorites__card-info place-card__info'>
-                      <div className='place-card__price-wrapper'>
-                        <div className='place-card__price'>
-                          <b className='place-card__price-value'>&euro;180</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'>
-                            <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: '100%' }}></span>
-                          <span className='visually-hidden'>Rating</span>
-                        </div>
-                      </div>
-                      <h2 className='place-card__name'>
-                        <a href='#'>Nice, cozy, warm big bed apartment</a>
-                      </h2>
-                      <p className='place-card__type'>Apartment</p>
-                    </div>
-                  </article>
-
-                  <article className='favorites__card place-card'>
-                    <div className='favorites__image-wrapper place-card__image-wrapper'>
-                      <a href='#'>
-                        <img className='place-card__image' src='img/room-small.jpg' width='150' height='110' alt='Place image' />
-                      </a>
-                    </div>
-                    <div className='favorites__card-info place-card__info'>
-                      <div className='place-card__price-wrapper'>
-                        <div className='place-card__price'>
-                          <b className='place-card__price-value'>&euro;80</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'>
-                            <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: '80%' }}></span>
-                          <span className='visually-hidden'>Rating</span>
-                        </div>
-                      </div>
-                      <h2 className='place-card__name'>
-                        <a href='#'>Wood and stone place</a>
-                      </h2>
-                      <p className='place-card__type'>Room</p>
-                    </div>
-                  </article>
+                  {dataAmsterdam.map((v: FavoritesCardProps) => (
path: src/components/Favorites.tsx
user: login: rLukoyanov
body: `v` => `place`
created_at: 2025-03-06T15:42:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,8 +1,13 @@
 export type PlaceCardProps = {
+  id: number;
   name: string;
   poster: string;
   price: number;
   rating: string;
   type: string;
   isPremium?: boolean;
 }
+
+export type FavoritesCardProps = PlaceCardProps & {
path: src/types.ts
user: login: rLukoyanov
body: 1) переименовать FavoritePlaceCard (примерно)
2) добавить город на месте
created_at: 2025-03-06T15:45:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -121,47 +69,19 @@ export default function Favorites() {
                   </div>
                 </div>
                 <div className='favorites__places'>
-                  <article className='favorites__card place-card'>
-                    <div className='favorites__image-wrapper place-card__image-wrapper'>
-                      <a href='#'>
-                        <img className='place-card__image' src='img/apartment-small-04.jpg' width='150' height='110' alt='Place image' />
-                      </a>
-                    </div>
-                    <div className='favorites__card-info place-card__info'>
-                      <div className='place-card__price-wrapper'>
-                        <div className='place-card__price'>
-                          <b className='place-card__price-value'>&euro;180</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'>
-                            <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: '100%' }}></span>
-                          <span className='visually-hidden'>Rating</span>
-                        </div>
-                      </div>
-                      <h2 className='place-card__name'>
-                        <a href='#'>White castle</a>
-                      </h2>
-                      <p className='place-card__type'>Apartment</p>
-                    </div>
-                  </article>
+                  {dataCologne.map((v: FavoritesCardProps) => (
+                    <PlaceCard key={v.name} card={v} styled='favorites' isBookmarkActive />
+                  ))}
path: src/components/Favorites.tsx
user: login: rLukoyanov
body: аналогично 
created_at: 2025-03-06T15:46:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,13 +1,24 @@
+import { Link } from 'react-router-dom';
+import { DATA_FAVORITES } from '../data';
+import { FavoritesCardProps } from '../types';
+import PlaceCard from './PlaceCard';
+
 export default function Favorites() {
+  const getCityFavorites = (city: string, data: FavoritesCardProps[]) => {
+    const result = data.filter((v: FavoritesCardProps) => v.city === city);
+    return result;
+  };
+  const dataAmsterdam = getCityFavorites('Amsterdam', DATA_FAVORITES);
+  const dataCologne = getCityFavorites('Cologne', DATA_FAVORITES);
path: src/components/Favorites.tsx
user: login: rLukoyanov
body: `dataAmsterdam` => `amsterdamFavoritePlaces (Примерно)
created_at: 2025-03-06T15:47:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -199,108 +214,15 @@ export default function Offer() {
           <section className='near-places places'>
             <h2 className='near-places__title'>Other places in the neighbourhood</h2>
             <div className='near-places__list places__list'>
-              <article className='near-places__card place-card'>
-                <div className='near-places__image-wrapper place-card__image-wrapper'>
-                  <a href='#'>
-                    <img className='place-card__image' src='img/room.jpg' 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;80</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'>
-                        <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: '80%' }}></span>
-                      <span className='visually-hidden'>Rating</span>
-                    </div>
-                  </div>
-                  <h2 className='place-card__name'>
-                    <a href='#'>Wood and stone place</a>
-                  </h2>
-                  <p className='place-card__type'>Room</p>
-                </div>
-              </article>
-
-              <article className='near-places__card place-card'>
-                <div className='near-places__image-wrapper place-card__image-wrapper'>
-                  <a href='#'>
-                    <img className='place-card__image' src='img/apartment-02.jpg' 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;132</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 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'>
-                    <a href='#'>Canal View Prinsengracht</a>
-                  </h2>
-                  <p className='place-card__type'>Apartment</p>
-                </div>
-              </article>
-
-              <article className='near-places__card place-card'>
-                <div className='place-card__mark'>
-                  <span>Premium</span>
-                </div>
-                <div className='near-places__image-wrapper place-card__image-wrapper'>
-                  <a href='#'>
-                    <img className='place-card__image' src='img/apartment-03.jpg' 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;180</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 className='place-card__rating rating'>
-                    <div className='place-card__stars rating__stars'>
-                      <span style={{ width: '100%' }}></span>
-                      <span className='visually-hidden'>Rating</span>
-                    </div>
-                  </div>
-                  <h2 className='place-card__name'>
-                    <a href='#'>Nice, cozy, warm big bed apartment</a>
-                  </h2>
-                  <p className='place-card__type'>Apartment</p>
-                </div>
-              </article>
+              {dataOther.map((v: PlaceCardProps) => (
+                <PlaceCard key={v.id} card={v} styled='near-places' />
+              ))}
path: src/components/Offer.tsx
user: login: rLukoyanov
body: Аналагично
created_at: 2025-03-06T15:48:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,13 +1,26 @@
-export default function Offer() {
-  return (
+import { Link, useParams } from 'react-router-dom';
+import PageNotFound from './PageNotFound';
+import { PlaceCardProps } from '../types';
+import PlaceCard from './PlaceCard';
+
+type OfferProps = {
+  cards: PlaceCardProps[];
+};
+
+export default function Offer({ cards }: OfferProps) {
+  const { id } = useParams();
+  const data = cards.filter((v: PlaceCardProps) => v.id === +id!)[0];
+  const dataOther = cards.filter((v: PlaceCardProps) => v.id !== +id!);
+
+  return data ? (
     <div className='page'>
       <header className='header'>
         <div className='container'>
path: src/components/Offer.tsx
user: login: rLukoyanov
body: ```js
if (!data) {
 return <PageNotFound>
}
```
created_at: 2025-03-06T15:49:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,14 +1,34 @@
+import { BrowserRouter, Route, Routes } from 'react-router-dom';
 
 import { PlaceCardProps } from '../types';
 import Main from './Main';
+import Login from './Login';
+import Offer from './Offer';
+import Favorites from './Favorites';
+import PrivateRoute from './PrivateRoute';
+import PageNotFound from './PageNotFound';
 
 type AppProps = {
   data: PlaceCardProps[];
 };
 
-export default function App({data}: AppProps): JSX.Element {
+export default function App({ data }: AppProps): JSX.Element {
   return (
-    <Main cards={data} />
+    <BrowserRouter>
+      <Routes>
+        <Route path='/' element={<Main cards={data} />} />
+        <Route path='/login' element={<Login />} />
+        <Route
+          path='/favorites'
+          element={
+            <PrivateRoute>
+              <Favorites />
+            </PrivateRoute>
+          }
+        />
+        <Route path='/offer/:id' element={<Offer cards={data} />} />
+        <Route path='*' element={<PageNotFound />} />
+      </Routes>
path: src/components/App.tsx
user: login: rLukoyanov
body: Вынести в enum, и заменить все роуты на проекте через него
`/`
`/login` 
`/favorites`
`/offer/:id`

created_at: 2025-03-06T15:54:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,14 +1,34 @@
+import { BrowserRouter, Route, Routes } from 'react-router-dom';
 
 import { PlaceCardProps } from '../types';
 import Main from './Main';
+import Login from './Login';
+import Offer from './Offer';
+import Favorites from './Favorites';
+import PrivateRoute from './PrivateRoute';
+import PageNotFound from './PageNotFound';
 
 type AppProps = {
   data: PlaceCardProps[];
 };
 
-export default function App({data}: AppProps): JSX.Element {
+export default function App({ data }: AppProps): JSX.Element {
path: src/components/App.tsx
user: login: rLukoyanov
body: Данные импортируем напрямую, не через лесенку пропсов
created_at: 2025-03-06T15:56:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,14 +1,34 @@
+import { BrowserRouter, Route, Routes } from 'react-router-dom';
 
 import { PlaceCardProps } from '../types';
 import Main from './Main';
+import Login from './Login';
+import Offer from './Offer';
+import Favorites from './Favorites';
+import PrivateRoute from './PrivateRoute';
+import PageNotFound from './PageNotFound';
 
 type AppProps = {
   data: PlaceCardProps[];
 };
 
-export default function App({data}: AppProps): JSX.Element {
+export default function App({ data }: AppProps): JSX.Element {
   return (
-    <Main cards={data} />
+    <BrowserRouter>
+      <Routes>
+        <Route path='/' element={<Main cards={data} />} />
+        <Route path='/login' element={<Login />} />
path: src/components/App.tsx
user: login: rLukoyanov
body: `<Route path='/login' element={<Login />} />` => 
`<Route path={Path.Login} element={<Login />} />`
created_at: 2025-03-06T16:11:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,13 +1,24 @@
+import { Link } from 'react-router-dom';
+import { DATA_FAVORITES } from '../data';
+import { FavoritesCardProps } from '../types';
+import PlaceCard from './PlaceCard';
+
 export default function Favorites() {
+  const getCityFavorites = (city: string, data: FavoritesCardProps[]) => {
+    const result = data.filter((v: FavoritesCardProps) => v.city === city);
+    return result;
+  };
+  const dataAmsterdam = getCityFavorites('Amsterdam', DATA_FAVORITES);
+  const dataCologne = getCityFavorites('Cologne', DATA_FAVORITES);
path: src/components/Favorites.tsx
user: login: vigolajnen
body: Сменила название на amsterdamFavorites
created_at: 2025-03-07T16:54:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,13 +1,24 @@
+import { Link } from 'react-router-dom';
+import { DATA_FAVORITES } from '../data';
+import { FavoritesCardProps } from '../types';
+import PlaceCard from './PlaceCard';
+
 export default function Favorites() {
+  const getCityFavorites = (city: string, data: FavoritesCardProps[]) => {
+    const result = data.filter((v: FavoritesCardProps) => v.city === city);
path: src/components/Favorites.tsx
user: login: vigolajnen
body: Переименовала:
const filterFavoritePlacesByCity = (city: string, data: Place[]) => {
  const filteredPlaces = data.filter((place: Place) => place.city === city);
  return filteredPlaces;
};
created_at: 2025-03-07T16:54:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,13 +1,27 @@
+import { Link } from 'react-router-dom';
+
+import { Place } from '../types';
+import { FAVORITE_PLACES } from '../data';
+import PlaceCard from './PlaceCard';
+
+const filterFavoritePlacesByCity = (city: string, data: Place[]) => {
+  const filteredPlaces = data.filter((place: Place) => place.city === city);
+  return filteredPlaces;
+};
+
+const amsterdamFavorites = filterFavoritePlacesByCity('Amsterdam', FAVORITE_PLACES);
+const cologneFavorites = filterFavoritePlacesByCity('Cologne', FAVORITE_PLACES);
+
 export default function Favorites() {
   return (
     <div className='page'>
       <header className='header'>
         <div className='container'>
           <div className='header__wrapper'>
             <div className='header__left'>
-              <a className='header__logo-link' href='main.html'>
+              <Link className='header__logo-link' to='/'>
path: src/components/Favorites.tsx
user: login: rLukoyanov
body: enum
created_at: 2025-03-08T10:46:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,13 +1,15 @@
+import { Link } from 'react-router-dom';
+
 export default function FavoritesEmpty() {
   return (
     <div className='page page--favorites-empty'>
       <header className='header'>
         <div className='container'>
           <div className='header__wrapper'>
             <div className='header__left'>
-              <a className='header__logo-link' href='main.html'>
+              <Link className='header__logo-link' to='/'>
path: src/components/FavoritesEmpty.tsx
user: login: rLukoyanov
body: enum
created_at: 2025-03-08T10:46:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -41,9 +43,9 @@ export default function FavoritesEmpty() {
         </div>
       </main>
       <footer className='footer'>
-        <a className='footer__logo-link' href='main.html'>
+        <Link className='footer__logo-link' to='/'>
path: src/components/FavoritesEmpty.tsx
user: login: rLukoyanov
body: enum
created_at: 2025-03-08T10:46:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,13 +1,28 @@
+import { Link, useParams } from 'react-router-dom';
+import PageNotFound from './PageNotFound';
+import { Place } from '../types';
+import PlaceCard from './PlaceCard';
+import { PLACES } from '../data';
+
+
 export default function Offer() {
+  const { id } = useParams();
+  const data = PLACES.filter((place: Place) => place.id === +id!)[0];
+  const dataOther = PLACES.filter((place: Place) => place.id !== +id!);
+
+  if (!data) {
+    return <PageNotFound />;
+  }
+
   return (
     <div className='page'>
       <header className='header'>
         <div className='container'>
           <div className='header__wrapper'>
             <div className='header__left'>
-              <a className='header__logo-link' href='main.html'>
+              <Link className='header__logo-link' to='/'>
path: src/components/Offer.tsx
user: login: rLukoyanov
body: enum
created_at: 2025-03-08T10:46:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,13 +1,15 @@
+import { Link } from 'react-router-dom';
+
 export default function OfferNotLogged() {
   return (
     <div className='page'>
       <header className='header'>
         <div className='container'>
           <div className='header__wrapper'>
             <div className='header__left'>
-              <a className='header__logo-link' href='main.html'>
+              <Link className='header__logo-link' to='/'>
path: src/components/OfferNotLogged.tsx
user: login: rLukoyanov
body: enum
created_at: 2025-03-08T10:46:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,36 @@
+import { Link } from 'react-router-dom';
+
+export default function PageNotFound() {
+  return (
+    <div className='page page--gray page--main'>
+      <header className='header'>
+        <div className='container'>
+          <div className='header__wrapper'>
+            <div className='header__left'>
+              <Link className='header__logo-link header__logo-link--active' to='/'>
+                <img className='header__logo' src='img/logo.svg' alt='6 cities logo' width='81' height='41' />
+              </Link>
+            </div>
+          </div>
+        </div>
+      </header>
+
+      <main className='page__main page__main--index page__main--index-empty'>
+        <div className='cities'>
+          <div className='cities__places-container cities__places-container--empty container'>
+            <section className='cities__no-places'>
+              <div className='cities__status-wrapper tabs__content'>
+                <b className='cities__status'>404</b>
+                <p className='cities__status-description'>Нет такой страницы</p>
+                <Link to='/' style={{ textDecoration: 'underline' }}>
path: src/components/PageNotFound.tsx
user: login: rLukoyanov
body: enum
created_at: 2025-03-08T10:47:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,36 @@
+import { Link } from 'react-router-dom';
+
+export default function PageNotFound() {
+  return (
+    <div className='page page--gray page--main'>
+      <header className='header'>
+        <div className='container'>
+          <div className='header__wrapper'>
+            <div className='header__left'>
+              <Link className='header__logo-link header__logo-link--active' to='/'>
path: src/components/PageNotFound.tsx
user: login: rLukoyanov
body: enum
created_at: 2025-03-08T10:47:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,34 +1,37 @@
-import { PlaceCardProps } from '../types';
+import { Link } from 'react-router-dom';
+import { Place } from '../types';
 
 type CardProps = {
-  card: PlaceCardProps;
+  card: Place;
+  styled?: string;
+  isBookmarkActive?: boolean;
 };
 
-export default function PlaceCard({ card }: CardProps): JSX.Element {
-  const { name, price, rating, type, poster, isPremium } = card;
+export default function PlaceCard({ card, styled = 'cities', isBookmarkActive = false }: CardProps): JSX.Element {
+  const { name, price, rating, type, poster, isPremium, id } = card;
   return (
-    <article className='cities__card place-card'>
+    <article className={`${styled}__card place-card`}>
       {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={poster} width='260' height='200' alt='Place image' />
-        </a>
+      <div className={`${styled}__image-wrapper place-card__image-wrapper`}>
+        <Link to={`offer/${id}`}>
path: src/components/PlaceCard.tsx
user: login: rLukoyanov
body: тоже сделать через enum

`USER = "user/:id" `

`Paths.USER.replace(":id", id)`
created_at: 2025-03-08T10:48:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,34 +1,37 @@
-import { PlaceCardProps } from '../types';
+import { Link } from 'react-router-dom';
+import { Place } from '../types';
 
 type CardProps = {
-  card: PlaceCardProps;
+  card: Place;
+  styled?: string;
+  isBookmarkActive?: boolean;
 };
 
-export default function PlaceCard({ card }: CardProps): JSX.Element {
-  const { name, price, rating, type, poster, isPremium } = card;
+export default function PlaceCard({ card, styled = 'cities', isBookmarkActive = false }: CardProps): JSX.Element {
+  const { name, price, rating, type, poster, isPremium, id } = card;
   return (
-    <article className='cities__card place-card'>
+    <article className={`${styled}__card place-card`}>
       {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={poster} width='260' height='200' alt='Place image' />
-        </a>
+      <div className={`${styled}__image-wrapper place-card__image-wrapper`}>
+        <Link to={`offer/${id}`}>
path: src/components/PlaceCard.tsx
user: login: rLukoyanov
body: Все делаем через enum, потому-что нет гарантий что у нас потом все роуты поменяются, допустим добавится везде /v1/. Или главная страница преедет с `/` на `/app`
created_at: 2025-03-08T10:50:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,14 +1,34 @@
+import { BrowserRouter, Route, Routes } from 'react-router-dom';
 
 import { PlaceCardProps } from '../types';
 import Main from './Main';
+import Login from './Login';
+import Offer from './Offer';
+import Favorites from './Favorites';
+import PrivateRoute from './PrivateRoute';
+import PageNotFound from './PageNotFound';
 
 type AppProps = {
   data: PlaceCardProps[];
 };
 
-export default function App({data}: AppProps): JSX.Element {
+export default function App({ data }: AppProps): JSX.Element {
   return (
-    <Main cards={data} />
+    <BrowserRouter>
+      <Routes>
+        <Route path='/' element={<Main cards={data} />} />
+        <Route path='/login' element={<Login />} />
path: src/components/App.tsx
user: login: vigolajnen
body: Path '/login' заменила на {Path.Login}
created_at: 2025-03-09T16:47:41Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-03-05T20:57:10Z
body: Ваш пулреквест опубликован. Посмотреть можно [здесь](https://htmlacademy-react.github.io/49149-six-cities-3/3/)
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-03-06T14:00:55Z
body: Ваш пулреквест опубликован. Посмотреть можно [здесь](https://htmlacademy-react.github.io/49149-six-cities-3/3/)
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-03-07T16:51:19Z
body: Ваш пулреквест опубликован. Посмотреть можно [здесь](https://htmlacademy-react.github.io/49149-six-cities-3/3/)
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-03-09T16:42:07Z
body: Ваш пулреквест опубликован. Посмотреть можно [здесь](https://htmlacademy-react.github.io/49149-six-cities-3/3/)
author_association: NONE