From 2a495b7fafeb25ca1aa1ff1d6c18232d0add1acb Mon Sep 17 00:00:00 2001 From: Nawwar14 Date: Wed, 25 Sep 2024 12:26:15 +0300 Subject: [PATCH 1/4] First task --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 1c15ed3..294460d 100644 --- a/Readme.md +++ b/Readme.md @@ -1,7 +1,7 @@ # Личный проект «Шесть городов» * Студент: [Навар Худер](https://up.htmlacademy.ru/univer-js3/5/user/2571633). -* Наставник: `Неизвестно`. +* Наставник: `Александр Сударев`. --- From 9facc365e3021e6de879c6f5bc1bb0d7eb099651 Mon Sep 17 00:00:00 2001 From: Nawwar14 <147875072+Nawwar14@users.noreply.github.com> Date: Wed, 23 Oct 2024 23:43:53 +0300 Subject: [PATCH 2/4] V1.1 --- package-lock.json | 2 +- src/App.tsx | 33 ++ src/components/Error/Error404.tsx | 14 + src/components/Favorites/Favorite.tsx | 32 ++ src/components/LoggedRoute/index.tsx | 10 + src/components/Login/LoginPage.tsx | 63 +++ src/components/Main/main.tsx | 24 + src/components/MainPage/MainPage.tsx | 120 +++++ src/components/MainPageCard/Card.tsx | 40 ++ src/components/Offer/Offer.tsx | 485 ++++++++++++++++++ src/components/Offer/OfferCard.tsx | 51 ++ src/components/Offer/OfferList.tsx | 38 ++ .../SendCommentForm/SendCommentForm.tsx | 60 +++ src/components/User/index.ts | 3 + src/components/User/interfaces.ts | 11 + src/components/User/model/index.tsx | 45 ++ src/components/User/model/useContext.tsx | 4 + src/index.tsx | 5 +- src/mock/offers.ts | 42 ++ 19 files changed, 1079 insertions(+), 3 deletions(-) create mode 100644 src/App.tsx create mode 100644 src/components/Error/Error404.tsx create mode 100644 src/components/Favorites/Favorite.tsx create mode 100644 src/components/LoggedRoute/index.tsx create mode 100644 src/components/Login/LoginPage.tsx create mode 100644 src/components/Main/main.tsx create mode 100644 src/components/MainPage/MainPage.tsx create mode 100644 src/components/MainPageCard/Card.tsx create mode 100644 src/components/Offer/Offer.tsx create mode 100644 src/components/Offer/OfferCard.tsx create mode 100644 src/components/Offer/OfferList.tsx create mode 100644 src/components/SendCommentForm/SendCommentForm.tsx create mode 100644 src/components/User/index.ts create mode 100644 src/components/User/interfaces.ts create mode 100644 src/components/User/model/index.tsx create mode 100644 src/components/User/model/useContext.tsx create mode 100644 src/mock/offers.ts diff --git a/package-lock.json b/package-lock.json index 9e0465f..ff09938 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1524,7 +1524,7 @@ "version": "18.2.11", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.11.tgz", "integrity": "sha512-zq6Dy0EiCuF9pWFW6I6k6W2LdpUixLE4P6XjXU1QHLfak3GPACQfLwEuHzY5pOYa4hzj1d0GxX/P141aFjZsyg==", - "devOptional": true, + "dev": true, "dependencies": { "@types/react": "*" } diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..a21e1a8 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,33 @@ +import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; +import MainPage from './components/MainPage/MainPage'; +import Favorite from './components/Favorites/Favorite'; +import LoginPage from './components/Login/LoginPage'; +import Offer from './components/Offer/Offer'; + +type Offer = { + id: number; + title: string; + price: number; + rating: number; + type: string; + isPremium: boolean; + previewImage: string; + NumberOfPlaces: number; +}; + +type AppProps = { + offers: Offer[]; +}; + +export default function App({ offers }: AppProps) { + return ( + + + } /> + } /> + } /> + } /> + + + ); +} diff --git a/src/components/Error/Error404.tsx b/src/components/Error/Error404.tsx new file mode 100644 index 0000000..1c5e106 --- /dev/null +++ b/src/components/Error/Error404.tsx @@ -0,0 +1,14 @@ + +import { Link } from 'react-router-dom'; + + +export const Error404 = () => ( +
+

+ 404 not found +

+ + ⬅️ Main Page + +
+); diff --git a/src/components/Favorites/Favorite.tsx b/src/components/Favorites/Favorite.tsx new file mode 100644 index 0000000..b7525f0 --- /dev/null +++ b/src/components/Favorites/Favorite.tsx @@ -0,0 +1,32 @@ +import OfferCard from '../Offer/OfferCard'; +type Offer = { + id: number; + title: string; + price: number; + rating: number; + type: string; + isPremium: boolean; + previewImage: string; + NumberOfPlaces: number; +}; +type FavoriteProps = { + offers: Offer[]; +}; +const Favorite = ({ offers }: FavoriteProps) => ( +
+
+
+
+

Saved listings

+
+ {offers.map((offer) => ( + + ))} +
+
+
+
+
+); + +export default Favorite; diff --git a/src/components/LoggedRoute/index.tsx b/src/components/LoggedRoute/index.tsx new file mode 100644 index 0000000..870c814 --- /dev/null +++ b/src/components/LoggedRoute/index.tsx @@ -0,0 +1,10 @@ +import {FC} from 'react'; +import { Navigate } from 'react-router-dom'; +import { WithChildren } from '../../shared/interfaces'; +import { useUserContext } from '../User'; + +export const LoggedRoute:FC = ({ children }) => { + const { user } = useUserContext(); + + return user.logged ? children : ; +}; diff --git a/src/components/Login/LoginPage.tsx b/src/components/Login/LoginPage.tsx new file mode 100644 index 0000000..0e1673d --- /dev/null +++ b/src/components/Login/LoginPage.tsx @@ -0,0 +1,63 @@ +export default function LoginPage () { + return ( +
+
+
+
+
+ + 6 cities logo + +
+
+
+
+ +
+
+
+

Sign in

+
+
+ + +
+
+ + +
+ +
+
+
+ +
+
+
+
+ ); +} diff --git a/src/components/Main/main.tsx b/src/components/Main/main.tsx new file mode 100644 index 0000000..473e0db --- /dev/null +++ b/src/components/Main/main.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; +import { BrowserRouter, Route, Routes } from 'react-router-dom'; +import {MainPage} from '../MainPage/MainPage'; +import { LoginPage } from '../Login/LoginPage'; +import { Offer } from '../Offer/Offer'; +import { Favorite } from '../Favorites/Favorite'; +import { Error404 } from '../Error/Error404'; +import {cardProperties} from '../../index.tsx'; +import { UserContextProvider } from '../User'; +import { LoggedRoute } from '../LoggedRoute'; + +export const Main: React.FC<{mainPageCardInfo: cardProperties[]}> = ({mainPageCardInfo}) => ( + + + + } /> + } /> + } /> + } /> + } /> + + + +); diff --git a/src/components/MainPage/MainPage.tsx b/src/components/MainPage/MainPage.tsx new file mode 100644 index 0000000..ee9a53a --- /dev/null +++ b/src/components/MainPage/MainPage.tsx @@ -0,0 +1,120 @@ +import {FC} from 'react'; +import OfferList from '../Offer/OfferList'; + +type Offer = { + id: number; + title: string; + price: number; + rating: number; + type: string; + isPremium: boolean; + previewImage: string; + NumberOfPlaces: number; +}; +type MainPageProps = { + offers: Offer[]; +}; + +export const MainPage : FC = ({ offers }) => + ( +
+
+ +
+ +
+

Cities

+ +
+
+
+

Places

+ {offers.length} places to stay in Amsterdam +
+ Sort by + + Popular + + + + +
    +
  • Popular
  • +
  • Price: low to high
  • +
  • Price: high to low
  • +
  • Top rated first
  • +
+
+
+ +
+
+
+
+
+
+
+
+
+ ); +export default MainPage; diff --git a/src/components/MainPageCard/Card.tsx b/src/components/MainPageCard/Card.tsx new file mode 100644 index 0000000..e6c2be1 --- /dev/null +++ b/src/components/MainPageCard/Card.tsx @@ -0,0 +1,40 @@ +import {cardProperties} from '../../index.tsx'; +function Card(MainPageCardProps:cardProperties):JSX.Element{ + return( +
+ {MainPageCardProps.Premium ? +
+ Premium +
: null} +
+ + Place image + +
+
+
+
+ €{MainPageCardProps.Price} + / night +
+ +
+
+
+ + Rating +
+
+

+ {MainPageCardProps.Description} +

+

{MainPageCardProps.ApartsmentType}

+
+
); +} +export default Card; diff --git a/src/components/Offer/Offer.tsx b/src/components/Offer/Offer.tsx new file mode 100644 index 0000000..6c9511b --- /dev/null +++ b/src/components/Offer/Offer.tsx @@ -0,0 +1,485 @@ +import SendCommentForm from '../SendCommentForm/SendCommentForm'; +export default function Offer () { + return ( +
+
+ +
+ +
+
+
+
+
+ Photo studio +
+
+ Photo studio +
+
+ Photo studio +
+
+ Photo studio +
+
+ Photo studio +
+
+ Photo studio +
+
+
+
+
+
+ Premium +
+
+

+ Beautiful & luxurious studio at great location +

+ +
+
+
+ + Rating +
+ 4.8 +
+
    +
  • + Apartment +
  • +
  • + 3 Bedrooms +
  • +
  • + Max 4 adults +
  • +
+
+ €120 +  night +
+
+

What's inside

+
    +
  • Wi-Fi
  • +
  • Washing machine
  • +
  • Towels
  • +
  • Heating
  • +
  • Coffee machine
  • +
  • Baby seat
  • +
  • Kitchen
  • +
  • Dishwasher
  • +
  • Cabel TV
  • +
  • Fridge
  • +
+
+
+

Meet the host

+
+
+ Host avatar +
+ Angelina + Pro +
+
+

+ A quiet cozy and picturesque that hides behind a a river by + the unique lightness of Amsterdam. The building is green and + from 18th century. +

+

+ An independent House, strategically located between Rembrand + Square and National Opera, but where the bustle of the city + comes to rest in this alley flowery and colorful. +

+
+
+
+

+ Reviews · 1 +

+
    +
  • +
    +
    + Reviews avatar +
    + Max +
    +
    +
    +
    + + Rating +
    +
    +

    + A quiet cozy and picturesque that hides behind a a river + by the unique lightness of Amsterdam. The building is + green and from 18th century. +

    + +
    +
  • +
+
+ +
+ + + + + + + + + + + + + + +
+