From 6d0c0aeaa651ec6ddd379875e0754c9f5c229d93 Mon Sep 17 00:00:00 2001 From: mgmman <115487609+mgmman@users.noreply.github.com> Date: Tue, 15 Oct 2024 22:42:36 +0500 Subject: [PATCH 1/7] fixes after review --- package-lock.json | 32 +++++++++++++------ package.json | 4 +-- src/DataTypes/{AppRoutes.tsx => AppRoutes.ts} | 0 src/DataTypes/AuthorizationStatus.ts | 5 +++ src/components/App.tsx | 4 +-- src/components/AuthorizationWrapper.tsx | 3 +- 6 files changed, 34 insertions(+), 14 deletions(-) rename src/DataTypes/{AppRoutes.tsx => AppRoutes.ts} (100%) create mode 100644 src/DataTypes/AuthorizationStatus.ts diff --git a/package-lock.json b/package-lock.json index ca452cd..fa1c926 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,9 +14,10 @@ "history": "5.3.0", "http-status-codes": "2.3.0", "leaflet": "1.7.1", + "prettier": "3.3.3", "react": "18.2.0", "react-dom": "18.2.0", - "react-helmet-async": "1.3.0", + "react-helmet-async": "2.0.5", "react-redux": "8.1.3", "react-router-dom": "6.16.0" }, @@ -4754,6 +4755,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -5110,6 +5112,20 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-format": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", @@ -5146,6 +5162,7 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -5227,19 +5244,16 @@ "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" }, "node_modules/react-helmet-async": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", - "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-2.0.5.tgz", + "integrity": "sha512-rYUYHeus+i27MvFE+Jaa4WsyBKGkL6qVgbJvSBoX8mbsWoABJXdEO0bZyi0F6i+4f0NuIb8AvqPMj3iXFHkMwg==", "dependencies": { - "@babel/runtime": "^7.12.5", "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.2.0", + "react-fast-compare": "^3.2.2", "shallowequal": "^1.1.0" }, "peerDependencies": { - "react": "^16.6.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" + "react": "^16.6.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/react-is": { diff --git a/package.json b/package.json index 9b0c921..daccf47 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,10 @@ "history": "5.3.0", "http-status-codes": "2.3.0", "leaflet": "1.7.1", - "prettier": "^3.3.3", + "prettier": "3.3.3", "react": "18.2.0", "react-dom": "18.2.0", - "react-helmet-async": "^2.0.5", + "react-helmet-async": "2.0.5", "react-redux": "8.1.3", "react-router-dom": "6.16.0" }, diff --git a/src/DataTypes/AppRoutes.tsx b/src/DataTypes/AppRoutes.ts similarity index 100% rename from src/DataTypes/AppRoutes.tsx rename to src/DataTypes/AppRoutes.ts diff --git a/src/DataTypes/AuthorizationStatus.ts b/src/DataTypes/AuthorizationStatus.ts new file mode 100644 index 0000000..3e0b810 --- /dev/null +++ b/src/DataTypes/AuthorizationStatus.ts @@ -0,0 +1,5 @@ +export enum AuthorizationStatus { + Authorized, + Unauthorized, + Unknown +} diff --git a/src/components/App.tsx b/src/components/App.tsx index 827aa5d..1e161f2 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -6,7 +6,7 @@ import { FavoritesPage } from '../Pages/FavoritesPage.tsx'; import { OfferPage } from '../Pages/OfferPage.tsx'; import { NotFoundPage } from '../Pages/NotFoundPage/NotFoundPage.tsx'; import { AuthorizationWrapper } from './AuthorizationWrapper.tsx'; -import { AppRoutes } from '../DataTypes/AppRoutes.tsx'; +import { AppRoutes } from '../DataTypes/AppRoutes.ts'; import { HelmetProvider } from 'react-helmet-async'; interface AppProps { @@ -26,7 +26,7 @@ export function App({ placeCount }: AppProps): React.JSX.Element { + } diff --git a/src/components/AuthorizationWrapper.tsx b/src/components/AuthorizationWrapper.tsx index b0b3603..b7370a5 100644 --- a/src/components/AuthorizationWrapper.tsx +++ b/src/components/AuthorizationWrapper.tsx @@ -1,12 +1,13 @@ import { Navigate } from 'react-router-dom'; interface AuthorizationWrapperProps { + isAuthorized: boolean; children: React.JSX.Element; } export function AuthorizationWrapper({ + isAuthorized, children, }: AuthorizationWrapperProps): React.JSX.Element { - const isAuthorized = false; return isAuthorized ? children : ; } From bfb346a3bad2696c6414453a33ceb99879e19673 Mon Sep 17 00:00:00 2001 From: mgmman <115487609+mgmman@users.noreply.github.com> Date: Wed, 16 Oct 2024 17:13:55 +0500 Subject: [PATCH 2/7] made 1-7 and started layout --- src/DataTypes/RoomType.ts | 4 - src/Pages/FavoritesPage.tsx | 55 +---------- src/Pages/MainPage.tsx | 47 ++------- src/components/App.tsx | 11 ++- src/components/Layout.tsx | 60 ++++++++++++ .../{PlaceCard.tsx => OfferCard.tsx} | 25 +++-- src/components/OffersList.tsx | 32 ++++++ src/dataTypes/City.ts | 6 ++ src/dataTypes/Location.ts | 5 + src/dataTypes/Offer.ts | 16 +++ .../enums}/AppRoutes.ts | 0 .../enums}/AuthorizationStatus.ts | 0 src/dataTypes/enums/RoomType.ts | 4 + src/index.tsx | 3 +- src/mocks/offers.ts | 97 +++++++++++++++++++ 15 files changed, 252 insertions(+), 113 deletions(-) delete mode 100644 src/DataTypes/RoomType.ts create mode 100644 src/components/Layout.tsx rename src/components/{PlaceCard.tsx => OfferCard.tsx} (74%) create mode 100644 src/components/OffersList.tsx create mode 100644 src/dataTypes/City.ts create mode 100644 src/dataTypes/Location.ts create mode 100644 src/dataTypes/Offer.ts rename src/{DataTypes => dataTypes/enums}/AppRoutes.ts (100%) rename src/{DataTypes => dataTypes/enums}/AuthorizationStatus.ts (100%) create mode 100644 src/dataTypes/enums/RoomType.ts create mode 100644 src/mocks/offers.ts diff --git a/src/DataTypes/RoomType.ts b/src/DataTypes/RoomType.ts deleted file mode 100644 index 86c0b35..0000000 --- a/src/DataTypes/RoomType.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum RoomType { - Apartment = 'Apartment', - Room = 'Room', -} diff --git a/src/Pages/FavoritesPage.tsx b/src/Pages/FavoritesPage.tsx index e8b0bbd..1cb2023 100644 --- a/src/Pages/FavoritesPage.tsx +++ b/src/Pages/FavoritesPage.tsx @@ -1,47 +1,9 @@ import { Helmet } from 'react-helmet-async'; +import { Layout } from '../components/Layout.tsx'; export function FavoritesPage(): React.JSX.Element { return ( -
-
-
- -
-
- +
6 cities - favorites @@ -219,17 +181,6 @@ export function FavoritesPage(): React.JSX.Element {
- - + ); } diff --git a/src/Pages/MainPage.tsx b/src/Pages/MainPage.tsx index bcae313..988cc7f 100644 --- a/src/Pages/MainPage.tsx +++ b/src/Pages/MainPage.tsx @@ -1,12 +1,12 @@ import React from 'react'; -import { PlaceCard } from '../components/PlaceCard.tsx'; -import { RoomType } from '../DataTypes/RoomType.ts'; +import { Offer } from '../dataTypes/Offer.ts'; +import { OffersList } from '../components/OffersList.tsx'; interface MainPageProps { - placeCount: number; + offers: Offer[]; } -export function MainPage({ placeCount }: MainPageProps): React.JSX.Element { +export function MainPage({ offers }: MainPageProps): React.JSX.Element { return (
@@ -91,7 +91,7 @@ export function MainPage({ placeCount }: MainPageProps): React.JSX.Element {

Places

- {placeCount} places to stay in Amsterdam + {offers.length} places to stay in Amsterdam
Sort by @@ -119,42 +119,7 @@ export function MainPage({ placeCount }: MainPageProps): React.JSX.Element {
-
- - - - - -
+
diff --git a/src/components/App.tsx b/src/components/App.tsx index 1e161f2..b01d811 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -6,27 +6,28 @@ import { FavoritesPage } from '../Pages/FavoritesPage.tsx'; import { OfferPage } from '../Pages/OfferPage.tsx'; import { NotFoundPage } from '../Pages/NotFoundPage/NotFoundPage.tsx'; import { AuthorizationWrapper } from './AuthorizationWrapper.tsx'; -import { AppRoutes } from '../DataTypes/AppRoutes.ts'; +import { AppRoutes } from '../dataTypes/enums/AppRoutes.ts'; import { HelmetProvider } from 'react-helmet-async'; +import { Offer } from '../dataTypes/Offer.ts'; interface AppProps { - placeCount: number; + offers: Offer[]; } -export function App({ placeCount }: AppProps): React.JSX.Element { +export function App({ offers }: AppProps): React.JSX.Element { return ( } + element={} /> } /> + } diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx new file mode 100644 index 0000000..575d85a --- /dev/null +++ b/src/components/Layout.tsx @@ -0,0 +1,60 @@ +interface LayoutProps { + children: React.JSX.Element; +} + +export function Layout({ children }: LayoutProps): React.JSX.Element { + return ( +
+
+ +
+ {children} + +
+ ); +} diff --git a/src/components/PlaceCard.tsx b/src/components/OfferCard.tsx similarity index 74% rename from src/components/PlaceCard.tsx rename to src/components/OfferCard.tsx index 527c1e2..1409eab 100644 --- a/src/components/PlaceCard.tsx +++ b/src/components/OfferCard.tsx @@ -1,25 +1,30 @@ import React from 'react'; -import { RoomType } from '../DataTypes/RoomType.ts'; +import { RoomType } from '../dataTypes/enums/RoomType.ts'; interface PlaceCardProps { + id: string; price: number; type: RoomType; image: string; - description: string; + title: string; + onMouseOver: (id: string) => void; isPremium?: boolean; - isInBookmarks?: boolean; + isFavorite?: boolean; } -export function PlaceCard({ +export function OfferCard({ + id, price, type, image, - description, + title, + onMouseOver, isPremium, - isInBookmarks, + isFavorite, }: PlaceCardProps): React.JSX.Element { + const handleMouseOver = (): void => onMouseOver(id); return ( -
+
{isPremium && (
Premium @@ -43,14 +48,14 @@ export function PlaceCard({ / night
@@ -61,7 +66,7 @@ export function PlaceCard({

- {description} + {title}

{type}

diff --git a/src/components/OffersList.tsx b/src/components/OffersList.tsx new file mode 100644 index 0000000..e3bfddd --- /dev/null +++ b/src/components/OffersList.tsx @@ -0,0 +1,32 @@ +import { Offer } from '../dataTypes/Offer.ts'; +import { OfferCard } from './OfferCard.tsx'; +import React, { useState } from 'react'; + +interface OffersListProps { + offers: Offer[]; +} + +export function OffersList({ offers }: OffersListProps): React.JSX.Element { + const [activeOfferId, setActiveOfferId] = useState(''); + const handleMouseOver = (id: string): void => { + setActiveOfferId(id); + console.log(activeOfferId); + }; + return ( +
+ {offers.map((offer) => ( + + ))} +
+ ); +} diff --git a/src/dataTypes/City.ts b/src/dataTypes/City.ts new file mode 100644 index 0000000..0b7c648 --- /dev/null +++ b/src/dataTypes/City.ts @@ -0,0 +1,6 @@ +import { Location } from './Location.ts'; + +export type City = { + name: string; + location: Location; +}; diff --git a/src/dataTypes/Location.ts b/src/dataTypes/Location.ts new file mode 100644 index 0000000..5cd6bac --- /dev/null +++ b/src/dataTypes/Location.ts @@ -0,0 +1,5 @@ +export type Location = { + latitude: number; + longitude: number; + zoom: number; +} diff --git a/src/dataTypes/Offer.ts b/src/dataTypes/Offer.ts new file mode 100644 index 0000000..f50a7b3 --- /dev/null +++ b/src/dataTypes/Offer.ts @@ -0,0 +1,16 @@ +import { Location } from './Location.ts'; +import { City } from './City.ts'; +import { RoomType } from './enums/RoomType.ts'; + +export type Offer = { + id: string; + title: string; + type: RoomType; + price: number; + city: City; + location: Location; + isFavorite: boolean; + isPremium: boolean; + rating: number; + previewImage: string; +}; diff --git a/src/DataTypes/AppRoutes.ts b/src/dataTypes/enums/AppRoutes.ts similarity index 100% rename from src/DataTypes/AppRoutes.ts rename to src/dataTypes/enums/AppRoutes.ts diff --git a/src/DataTypes/AuthorizationStatus.ts b/src/dataTypes/enums/AuthorizationStatus.ts similarity index 100% rename from src/DataTypes/AuthorizationStatus.ts rename to src/dataTypes/enums/AuthorizationStatus.ts diff --git a/src/dataTypes/enums/RoomType.ts b/src/dataTypes/enums/RoomType.ts new file mode 100644 index 0000000..10b288f --- /dev/null +++ b/src/dataTypes/enums/RoomType.ts @@ -0,0 +1,4 @@ +export enum RoomType { + Apartment = 'apartment', + Room = 'room', +} diff --git a/src/index.tsx b/src/index.tsx index 13f3c27..c0b6860 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,6 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import { App } from './components/App.tsx'; +import { offerMocks } from './mocks/offers.ts'; const root = ReactDOM.createRoot( document.getElementById('root') as HTMLElement, @@ -8,6 +9,6 @@ const root = ReactDOM.createRoot( root.render( - + , ); diff --git a/src/mocks/offers.ts b/src/mocks/offers.ts new file mode 100644 index 0000000..bb2274f --- /dev/null +++ b/src/mocks/offers.ts @@ -0,0 +1,97 @@ +import { Offer } from '../dataTypes/Offer.ts'; +import { RoomType } from '../dataTypes/enums/RoomType.ts'; + +export const offerMocks: Offer[] = [ + { + id: '6af6f711-c28d-4121-82cd-e0b462a27f00', + title: 'Beautiful & luxurious studio at great location', + type: RoomType.Apartment, + price: 120, + city: { + name: 'Amsterdam', + location: { + latitude: 52.35514938496378, + longitude: 4.673877537499948, + zoom: 8, + }, + }, + location: { + latitude: 52.35514938496378, + longitude: 4.673877537499948, + zoom: 8, + }, + isFavorite: false, + isPremium: false, + rating: 4, + previewImage: 'apartment-01.jpg', + }, + { + id: '6af6f711-c28d-4121-82cd-e0b462a27f33', + title: 'aboba', + type: RoomType.Room, + price: 21412, + city: { + name: 'Amsterdam', + location: { + latitude: 52.35514938496378, + longitude: 4.673877537499948, + zoom: 8, + }, + }, + location: { + latitude: 52.35514938496378, + longitude: 4.673877537499948, + zoom: 8, + }, + isFavorite: false, + isPremium: true, + rating: 4, + previewImage: 'apartment-02.jpg', + }, + { + id: '6af6f711-c28d-4121-82cd-e0b462a27f11', + title: 'Beautiful & luxurious studio at great location', + type: RoomType.Room, + price: 14, + city: { + name: 'Amsterdam', + location: { + latitude: 52.35514938496378, + longitude: 4.673877537499948, + zoom: 8, + }, + }, + location: { + latitude: 52.35514938496378, + longitude: 4.673877537499948, + zoom: 8, + }, + isFavorite: true, + isPremium: false, + rating: 4, + previewImage: 'apartment-03.jpg', + }, + { + id: '6af6f711-c28d-4121-82cd-e0b462a27f22', + title: 'Beautiful & luxurious studio at great location', + type: RoomType.Apartment, + price: 88, + city: { + name: 'Amsterdam', + location: { + latitude: 52.35514938496378, + longitude: 4.673877537499948, + zoom: 8, + }, + }, + location: { + latitude: 52.35514938496378, + longitude: 4.673877537499948, + zoom: 8, + }, + isFavorite: true, + isPremium: true, + rating: 4, + previewImage: 'apartment-02.jpg', + }, +]; From 183b412600cfd83b3f5b50b820811b0475995816 Mon Sep 17 00:00:00 2001 From: mgmman <115487609+mgmman@users.noreply.github.com> Date: Wed, 16 Oct 2024 22:51:38 +0500 Subject: [PATCH 3/7] done module 4 --- package-lock.json | 8 +- package.json | 2 +- src/Pages/FavoritesPage.tsx | 188 ++----------- src/Pages/MainPage.tsx | 48 +--- src/Pages/OfferPage.tsx | 311 +--------------------- src/components/App.tsx | 5 +- src/components/Layout.tsx | 43 +-- src/components/ReviewForm.tsx | 135 ++++++++++ src/components/{ => offer}/OfferCard.tsx | 11 +- src/components/offer/OfferGroup.tsx | 27 ++ src/components/{ => offer}/OffersList.tsx | 3 +- src/dataTypes/enums/AppRoutes.ts | 2 +- src/mocks/offers.ts | 2 +- tsconfig.json | 2 +- 14 files changed, 241 insertions(+), 546 deletions(-) create mode 100644 src/components/ReviewForm.tsx rename src/components/{ => offer}/OfferCard.tsx (87%) create mode 100644 src/components/offer/OfferGroup.tsx rename src/components/{ => offer}/OffersList.tsx (91%) diff --git a/package-lock.json b/package-lock.json index fa1c926..13cd997 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "eslint-plugin-react-refresh": "0.4.3", "faker": "5.5.3", "jsdom": "22.1.0", - "typescript": "5.2.2", + "typescript": "^5.6.3", "vite": "4.4.11", "vitest": "0.34.6" } @@ -6136,9 +6136,9 @@ } }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index daccf47..75c7af0 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "eslint-plugin-react-refresh": "0.4.3", "faker": "5.5.3", "jsdom": "22.1.0", - "typescript": "5.2.2", + "typescript": "5.6.3", "vite": "4.4.11", "vitest": "0.34.6" }, diff --git a/src/Pages/FavoritesPage.tsx b/src/Pages/FavoritesPage.tsx index 1cb2023..f9a438d 100644 --- a/src/Pages/FavoritesPage.tsx +++ b/src/Pages/FavoritesPage.tsx @@ -1,9 +1,17 @@ import { Helmet } from 'react-helmet-async'; import { Layout } from '../components/Layout.tsx'; +import { OfferGroup } from '../components/offer/OfferGroup.tsx'; +import { Offer } from '../dataTypes/Offer.ts'; -export function FavoritesPage(): React.JSX.Element { +interface FavoritesPageProps { + offers: Offer[]; +} + +export function FavoritesPage({ + offers, +}: FavoritesPageProps): React.JSX.Element { return ( - +
6 cities - favorites @@ -12,171 +20,17 @@ export function FavoritesPage(): React.JSX.Element {

Saved listing

    -
  • - -
    - - -
    -
    - - Place image - -
    -
    -
    -
    - €80 - - / night - -
    - -
    -
    -
    - - Rating -
    -
    -

    - Wood and stone place -

    -

    Room

    -
    -
    -
    -
  • - -
  • - -
    -
    -
    - - Place image - -
    -
    -
    -
    - €180 - - / night - -
    - -
    -
    -
    - - Rating -
    -
    -

    - White castle -

    -

    Apartment

    -
    -
    -
    -
  • + {Map.groupBy(offers, (o) => o.city.name) + .entries() + .map(([cityName, offersInCity]) => ( + + )) + .toArray()} + ;
diff --git a/src/Pages/MainPage.tsx b/src/Pages/MainPage.tsx index 988cc7f..11eb9d3 100644 --- a/src/Pages/MainPage.tsx +++ b/src/Pages/MainPage.tsx @@ -1,6 +1,8 @@ import React from 'react'; import { Offer } from '../dataTypes/Offer.ts'; -import { OffersList } from '../components/OffersList.tsx'; +import { OffersList } from '../components/offer/OffersList.tsx'; +import { Layout } from '../components/Layout.tsx'; +import { Helmet } from 'react-helmet-async'; interface MainPageProps { offers: Offer[]; @@ -8,47 +10,9 @@ interface MainPageProps { export function MainPage({ offers }: MainPageProps): React.JSX.Element { return ( -
-
- -
- +
+ 6 cities

Cities

@@ -127,6 +91,6 @@ export function MainPage({ offers }: MainPageProps): React.JSX.Element {
- +
); } diff --git a/src/Pages/OfferPage.tsx b/src/Pages/OfferPage.tsx index ea7fa45..044c452 100644 --- a/src/Pages/OfferPage.tsx +++ b/src/Pages/OfferPage.tsx @@ -1,51 +1,14 @@ import { Helmet } from 'react-helmet-async'; +import { Layout } from '../components/Layout.tsx'; +import { OffersList } from '../components/offer/OffersList.tsx'; +import { offerMocks } from '../mocks/offers.ts'; +import { ReviewForm } from '../components/ReviewForm.tsx'; export function OfferPage(): React.JSX.Element { return ( -
- - 6 cities - view offer - -
- -
- +
+ 6 cities - offer
@@ -210,121 +173,7 @@ export function OfferPage(): React.JSX.Element {
-
- -
- - - - - - - - - - - - - - -
- -
-

- To submit review please make sure to set{' '} - rating and describe - your stay with at least{' '} - 50 characters. -

- -
-
+
@@ -336,153 +185,11 @@ export function OfferPage(): React.JSX.Element { Other places in the neighbourhood
-
-
- - Place image - -
-
-
-
- €80 - - / night - -
- -
-
-
- - Rating -
-
-

- Wood and stone place -

-

Room

-
-
- - - - +
- +
); } diff --git a/src/components/App.tsx b/src/components/App.tsx index b01d811..6f8721f 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -1,5 +1,4 @@ import { MainPage } from '../Pages/MainPage.tsx'; -import React from 'react'; import { BrowserRouter, Route, Routes } from 'react-router-dom'; import { LoginPage } from '../Pages/LoginPage.tsx'; import { FavoritesPage } from '../Pages/FavoritesPage.tsx'; @@ -28,11 +27,11 @@ export function App({ offers }: AppProps): React.JSX.Element { path={AppRoutes.Favorites} element={ - + } /> - } /> + } /> } /> diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 575d85a..22f3b83 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -1,15 +1,22 @@ +import { AppRoutes } from '../dataTypes/enums/AppRoutes.ts'; +import { Link } from 'react-router-dom'; + interface LayoutProps { children: React.JSX.Element; + showFooter?: boolean; } -export function Layout({ children }: LayoutProps): React.JSX.Element { +export function Layout({ + children, + showFooter, +}: LayoutProps): React.JSX.Element { return ( ); } diff --git a/src/components/ReviewForm.tsx b/src/components/ReviewForm.tsx new file mode 100644 index 0000000..71803cf --- /dev/null +++ b/src/components/ReviewForm.tsx @@ -0,0 +1,135 @@ +import { useState } from 'react'; + +type UserReview = { + comment?: string; + rating?: number; +}; + +export function ReviewForm(): React.JSX.Element { + const [review, setReview] = useState(); + const onRatingChange: React.ChangeEventHandler = ( + event, + ): void => setReview({ ...review, rating: +event.target.value }); + const onCommentChange: React.ChangeEventHandler = ( + event, + ): void => setReview({ ...review, comment: event.target.value }); + return ( +
+ +
+ + + + + + + + + + + + + + +
+ +
+

+ To submit review please make sure to set{' '} + rating and describe your stay + with at least 50 characters. +

+ +
+
+ ); +} diff --git a/src/components/OfferCard.tsx b/src/components/offer/OfferCard.tsx similarity index 87% rename from src/components/OfferCard.tsx rename to src/components/offer/OfferCard.tsx index 1409eab..6f15007 100644 --- a/src/components/OfferCard.tsx +++ b/src/components/offer/OfferCard.tsx @@ -1,5 +1,6 @@ -import React from 'react'; -import { RoomType } from '../dataTypes/enums/RoomType.ts'; +import { RoomType } from '../../dataTypes/enums/RoomType.ts'; +import { Link } from 'react-router-dom'; +import { AppRoutes } from '../../dataTypes/enums/AppRoutes.ts'; interface PlaceCardProps { id: string; @@ -31,7 +32,7 @@ export function OfferCard({ )}
- + Place image - +
@@ -66,7 +67,7 @@ export function OfferCard({

- {title} + {title}

{type}

diff --git a/src/components/offer/OfferGroup.tsx b/src/components/offer/OfferGroup.tsx new file mode 100644 index 0000000..dc5af94 --- /dev/null +++ b/src/components/offer/OfferGroup.tsx @@ -0,0 +1,27 @@ +import { Offer } from '../../dataTypes/Offer.ts'; +import { OffersList } from './OffersList.tsx'; + +interface OfferGroupProps { + cityName: string; + offers: Offer[]; +} + +export function OfferGroup({ + cityName, + offers, +}: OfferGroupProps): React.JSX.Element { + return ( +
  • + +
    + +
    +
  • + ); +} diff --git a/src/components/OffersList.tsx b/src/components/offer/OffersList.tsx similarity index 91% rename from src/components/OffersList.tsx rename to src/components/offer/OffersList.tsx index e3bfddd..47cf1e6 100644 --- a/src/components/OffersList.tsx +++ b/src/components/offer/OffersList.tsx @@ -1,4 +1,4 @@ -import { Offer } from '../dataTypes/Offer.ts'; +import { Offer } from '../../dataTypes/Offer.ts'; import { OfferCard } from './OfferCard.tsx'; import React, { useState } from 'react'; @@ -10,7 +10,6 @@ export function OffersList({ offers }: OffersListProps): React.JSX.Element { const [activeOfferId, setActiveOfferId] = useState(''); const handleMouseOver = (id: string): void => { setActiveOfferId(id); - console.log(activeOfferId); }; return (
    diff --git a/src/dataTypes/enums/AppRoutes.ts b/src/dataTypes/enums/AppRoutes.ts index e03dd83..946058b 100644 --- a/src/dataTypes/enums/AppRoutes.ts +++ b/src/dataTypes/enums/AppRoutes.ts @@ -1,6 +1,6 @@ export enum AppRoutes { MainPage = '/', Login = '/login', - Offer = '/offer/:id', + Offer = '/offer', Favorites = '/favorites', } diff --git a/src/mocks/offers.ts b/src/mocks/offers.ts index bb2274f..92daeb6 100644 --- a/src/mocks/offers.ts +++ b/src/mocks/offers.ts @@ -77,7 +77,7 @@ export const offerMocks: Offer[] = [ type: RoomType.Apartment, price: 88, city: { - name: 'Amsterdam', + name: 'Cologne', location: { latitude: 52.35514938496378, longitude: 4.673877537499948, diff --git a/tsconfig.json b/tsconfig.json index 61409ab..3fe56f6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ESNext", "lib": ["DOM", "DOM.Iterable", "ESNext"], "module": "ESNext", "skipLibCheck": true, From f2353a539e5cba1d45f24450fe2b24a42e945259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=93=D1=83=D1=80=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9C=D0=B0?= =?UTF-8?q?=D0=BA=D1=81=D0=B8=D0=BC?= Date: Mon, 21 Oct 2024 23:42:02 +0500 Subject: [PATCH 4/7] fixes --- src/components/ReviewForm.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/ReviewForm.tsx b/src/components/ReviewForm.tsx index 71803cf..b556f0d 100644 --- a/src/components/ReviewForm.tsx +++ b/src/components/ReviewForm.tsx @@ -13,6 +13,8 @@ export function ReviewForm(): React.JSX.Element { const onCommentChange: React.ChangeEventHandler = ( event, ): void => setReview({ ...review, comment: event.target.value }); + const isValid = + review?.comment && review?.comment?.length >= 50 && review?.rating; return (