Skip to content

Commit

Permalink
Merge pull request #17 from Nawwar14/module9-task2
Browse files Browse the repository at this point in the history
  • Loading branch information
keksobot authored Dec 24, 2024
2 parents c8b4300 + ea27d82 commit a323ca0
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 37 deletions.
45 changes: 23 additions & 22 deletions src/components/Offer/Offer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { Link, useNavigate, useParams } from 'react-router-dom';
import SendCommentForm from '../SendCommentForm/SendCommentForm';
import { ReviewList } from '../Reviews/ReviewList';
import { useAppDispatch, useAppSelector } from '../../hooks/index';
//import { offers } from '../../mock/offers';

import Map from '../Map/Map';
import { AppRoute, UserReview, CardCssNameList } from '../../types/types';
import { AuthorizationStatus } from '../../const.ts';
Expand All @@ -13,22 +11,25 @@ import { getAuthStatus,getUserEmail} from '../../store/userselector.ts';
import { fetchComments, fetchOffer, fetchOfferNeibourhood, logout, setIsOfferFavorite } from '../../api-actions.ts';
import classNames from 'classnames';
import { useEffect, useState } from 'react';
export const Offer: React.FC = () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
const { id: idOffer } = useParams();
import { store } from '../../store/index.ts';


export default function Offer () {
const { id: OfferId } = useParams();
const dispatch = useAppDispatch();
const userEmail = useAppSelector(getUserEmail);
const authStatus = useAppSelector(getAuthStatus);
const currentCity = useAppSelector((state) => state.currentCity);
useEffect(()=>{
dispatch(fetchOffer(idOffer ?? ''));
dispatch(fetchOfferNeibourhood(idOffer ?? ''));
dispatch(fetchComments(idOffer ?? ''));
},[idOffer,dispatch]);
const nearbyOffers = useAppSelector((store) => store.offerIdDetails.nearbyOffers);
const offerdetails = useAppSelector((store) => store.offerIdDetails.offer);
store.dispatch(fetchOffer(OfferId ?? ''));
store.dispatch(fetchOfferNeibourhood(OfferId ?? ''));
store.dispatch(fetchComments(OfferId ?? ''));
},[OfferId,dispatch]);
const nearbyOffers = useAppSelector((state) => state.offerIdDetails.nearbyOffers);
const offerdetails = useAppSelector((state) => state.offerIdDetails.offer);
const offers = useAppSelector((state) => state.offerPage);
const comments:UserReview[] = useAppSelector((store) => store.offerIdDetails.comments);
const userEmail = useAppSelector(getUserEmail);
const authStatus = useAppSelector(getAuthStatus);
const comments:UserReview[] = useAppSelector((state) => state.offerIdDetails.comments);

const [ isFavorite, setisFavorite ] = useState(false);
const navigate = useNavigate();
useEffect(() => {
Expand Down Expand Up @@ -198,12 +199,13 @@ export const Offer: React.FC = () => {
</div>
</div>
<section className="offer__map map">
<Map
offers={offers === null ? undefined : [...offers.offer]}
selectedPoint={offers.offer?.[1]}
currentCity={currentCity.currentCity}
activeOffer={offers.offer === null ? null : offers.offer[1].id}
/>
{offers !== null && offers.offer !== null && offers.offer.length > 0 ?
<Map
offers={offers === null ? undefined : [...offers.offer]}
selectedPoint={offers.offer?.[1]}
currentCity={currentCity.currentCity}
activeOffer={offers.offer === null ? null : offers?.offer[1].id}
/> : <Map offers={undefined} currentCity={currentCity.currentCity} activeOffer={null} selectedPoint={undefined} />}
</section>
</section>
<div className="container">
Expand All @@ -216,5 +218,4 @@ export const Offer: React.FC = () => {
</main>
</div>
);
};
export default Offer;
}
2 changes: 1 addition & 1 deletion src/components/routes/private-route/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface IPrivateRoute extends PropsWithChildren{
authState: AuthorizationStatus;
}
function PrivateRoute({children, authState}: IPrivateRoute) {
return authState === AuthorizationStatus.Auth ? children : <Navigate to={routesEnum.LOGIN} />;
return authState === AuthorizationStatus.Auth || authState === AuthorizationStatus.Unknown ? children : <Navigate to={routesEnum.LOGIN} />;
}

export default PrivateRoute;
8 changes: 8 additions & 0 deletions src/components/tests/app-router.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Cities } from '../../shared/api';
import MainPage from '../MainPage/MainPage';
import Favorite from '../Favorites/Favorite';
import NotFoundPage from '../NotFoundPage/NotFoundPage';
import Offer from '../Offer/Offer';

describe('Application Routing', () => {
let mockHistory: MemoryHistory;
Expand Down Expand Up @@ -98,4 +99,11 @@ describe('Application Routing', () => {

expect(screen.getByText(/404 Not Found/i)).toBeInTheDocument();
});
it('should render OfferPage when user navigate to "/offer/a01640c0-fed5-4d3f-99b3-deb2391269fc"', () => {
const withHistoryComponent = withHistory(<Offer />, mockHistory);
const { withStoreComponent } = withStore(withHistoryComponent, makeFakeStore());
mockHistory.push('/offer/a01640c0-fed5-4d3f-99b3-deb2391269fc');
render(withStoreComponent);
expect(screen.getByText(/Wood and stone place/i)).toBeInTheDocument();
});
});
39 changes: 34 additions & 5 deletions src/shared/mocks/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { AuthorizationStatus } from '../../const';
import { CITYLIST } from '../../mock/cities';
import { emptyOffer } from '../../mock/offers';
import { RootState } from '../lib/types';
import { State } from '../../types/types';

export function makeFakeStore(
initialState: Partial<RootState> = {}
): RootState {
export function makeFakeStore(initialState: Partial<State> = {}): State {
return {
Cities: {
currentCity: CITYLIST[0],
Expand All @@ -18,7 +16,38 @@ export function makeFakeStore(
offerPageStatus: false,
},
offerIdDetails: {
offer: emptyOffer,
offer: {
id: 'a20a52b2-efc2-4b0f-9396-4bdfbe5e9543',
title: 'Wood and stone place',
type: 'apartment',
price: 576,
images: ['https://14.design.htmlacademy.pro/static/hotel/14.jpg'],
city: {
name: 'Amsterdam',
location: {
latitude: 48.85661,
longitude: 2.351499,
zoom: 13,
},
},
location: {
latitude: 48.868610000000004,
longitude: 2.342499,
zoom: 16,
},
isFavorite: false,
isPremium: false,
rating: 2.1,
description: 'dsf',
bedrooms: 1,
goods: [''],
maxAdults: 1,
host: {
name: 'Oliver Conner',
avatarUrl: 'https://url-to-image/image.png',
isPro: false,
},
},
OfferIdDetailsPageStatus: false,
nearbyOffers: [],
comments: [],
Expand Down
12 changes: 6 additions & 6 deletions src/shared/providers/with-store.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import MockAdapter from 'axios-mock-adapter';
import { RootState } from '../lib/types';
import { $api } from '../api';
import { api } from '../../api-actions';
import thunk from 'redux-thunk';
import { configureMockStore } from '@jedmao/redux-mock-store';
import { Action } from '@reduxjs/toolkit';
import { AppThunkDispatch } from '../lib';
import { Provider } from 'react-redux';
import { withStoreProviderType } from './types';
import { State } from '../../types/types';

export function withStore(component: JSX.Element, initialState: Partial<RootState> = {}): withStoreProviderType {
const mockAxiosAdapter = new MockAdapter($api);
const middleware = [thunk.withExtraArgument($api)];
const mockStoreCreator = configureMockStore<RootState, Action<string>, AppThunkDispatch>(middleware);
export function withStore(component: JSX.Element, initialState: Partial<State> = {}): withStoreProviderType {
const mockAxiosAdapter = new MockAdapter(api);
const middleware = [thunk.withExtraArgument(api)];
const mockStoreCreator = configureMockStore<State, Action<string>, AppThunkDispatch>(middleware);
const store = mockStoreCreator(initialState);

return {
Expand Down
3 changes: 2 additions & 1 deletion src/store/userselector.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createSelector } from '@reduxjs/toolkit';
import { AuthorizationSlice, State } from '../types/types';
const selectAuthStatus = (state: Pick<State, 'user'>) =>
export type RootState = ReturnType<typeof import('../store').store.getState>;
const selectAuthStatus = (state: Pick<RootState, 'user'>) =>
state.user.authorizationStatus;

export const getAuthStatus = createSelector(
Expand Down
2 changes: 0 additions & 2 deletions src/types/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { store } from '../store';
import { AuthorizationStatus } from '../const';

export type City = {
title: string;
lat: number;
Expand Down Expand Up @@ -146,7 +145,6 @@ export type LoginAuth = {
email: string;
password: string;
};

export type ReducerType = {
offer: OfferIdDetailsPage;
user: UserAuth;
Expand Down

0 comments on commit a323ca0

Please sign in to comment.