diff --git a/src/components/favorites-list/favorites-list.test.tsx b/src/components/favorites-list/favorites-list.test.tsx
index 9a73e1e..8fc5ad5 100644
--- a/src/components/favorites-list/favorites-list.test.tsx
+++ b/src/components/favorites-list/favorites-list.test.tsx
@@ -1,11 +1,17 @@
import { render, screen } from '@testing-library/react';
+import { Provider } from 'react-redux';
+import { configureMockStore } from '@jedmao/redux-mock-store';
import { FavoritesList } from './favorites-list';
import { Offer } from '../../types/offer';
+import {BrowserRouter} from 'react-router-dom';
vi.mock('../favorite-card/favorite-card', () => ({
- FavoriteCard: vi.fn(({ offer }: {offer: Offer}) =>
{offer.title}
),
+ FavoriteCard: vi.fn(({ offer }: { offer: Offer }) =>
{offer.title}
),
}));
+const mockStore = configureMockStore();
+const store = mockStore({});
+
describe('Component: FavoritesList', () => {
const mockOffers: Offer[] = [
{
@@ -47,7 +53,13 @@ describe('Component: FavoritesList', () => {
];
it('should render grouped offers by city', () => {
- render(
);
+ render(
+
+
+
+
+
+ );
expect(screen.getByText('Paris')).toBeInTheDocument();
expect(screen.getByText('Amsterdam')).toBeInTheDocument();
@@ -64,7 +76,11 @@ describe('Component: FavoritesList', () => {
});
it('should render no offers if offers array is empty', () => {
- render(
);
+ render(
+
+
+
+ );
expect(screen.queryByText(/Paris|Amsterdam/)).not.toBeInTheDocument();
expect(screen.queryByTestId('favorite-card')).not.toBeInTheDocument();
diff --git a/src/components/favorites-list/favorites-list.tsx b/src/components/favorites-list/favorites-list.tsx
index 3f29621..c869c9b 100644
--- a/src/components/favorites-list/favorites-list.tsx
+++ b/src/components/favorites-list/favorites-list.tsx
@@ -1,6 +1,10 @@
-import {useMemo} from 'react';
+import {useCallback, useMemo} from 'react';
import {Offer} from '../../types/offer.ts';
import {FavoriteCard} from '../favorite-card/favorite-card.tsx';
+import {Link} from 'react-router-dom';
+import {AppRoute} from '../../const.ts';
+import {setCity} from '../../store/slices/city-slice.ts';
+import {useAppDispatch} from '../../hooks';
type FavoritesListProps = {
offers: Offer[];
@@ -19,15 +23,25 @@ export function FavoritesList({offers}: FavoritesListProps) {
return acc;
}, {} as Record
), [offers]);
+ const dispatch = useAppDispatch();
+
+ const handleCityClick = useCallback((city: string) => {
+ dispatch(setCity(city));
+ }, [dispatch]);
+
return (
{Object.entries(groupedOffers).map(([city, cityOffers]) => (
-
diff --git a/src/components/login-form/login-form.test.tsx b/src/components/login-form/login-form.test.tsx
index 3520b32..7028115 100644
--- a/src/components/login-form/login-form.test.tsx
+++ b/src/components/login-form/login-form.test.tsx
@@ -2,10 +2,14 @@ import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { LoginForm } from './login-form';
import {loginAction} from '../../store/api-actions';
-import { showCustomToast } from '../custom-toast/custom-toast';
import {withHistory, withStore} from '../../utils/mock-component.tsx';
+import {showCustomToast} from '../../utils/show-custom-toast.tsx';
vi.mock('../custom-toast/custom-toast', () => ({
+ CustomToast: vi.fn(() => null),
+}));
+
+vi.mock('../../utils/show-custom-toast', () => ({
showCustomToast: vi.fn(),
}));
diff --git a/src/components/login-form/login-form.tsx b/src/components/login-form/login-form.tsx
index 4cd3580..0926b8d 100644
--- a/src/components/login-form/login-form.tsx
+++ b/src/components/login-form/login-form.tsx
@@ -1,7 +1,7 @@
import {FormEvent, useRef, useCallback, memo} from 'react';
import { useAppDispatch } from '../../hooks';
import { loginAction } from '../../store/api-actions.ts';
-import { showCustomToast } from '../custom-toast/custom-toast.tsx';
+import {showCustomToast} from '../../utils/show-custom-toast.tsx';
const validatePassword = (password: string): boolean => {
const hasLetter = /[a-zA-Z]/.test(password);
diff --git a/src/components/offers-list/offers-list.test.tsx b/src/components/offers-list/offers-list.test.tsx
index a6a11c0..881c6dc 100644
--- a/src/components/offers-list/offers-list.test.tsx
+++ b/src/components/offers-list/offers-list.test.tsx
@@ -64,12 +64,12 @@ describe('Component: OffersList', () => {
expect(mockSetActiveOfferId).toHaveBeenCalledWith(null);
});
- it('should render with "near-places__list places__list" class when isNearby is true', () => {
+ it('should render with "near-places__list places__list" class when isNearby', () => {
render(
);
diff --git a/src/components/offers-list/offers-list.tsx b/src/components/offers-list/offers-list.tsx
index 56d9d99..7a36561 100644
--- a/src/components/offers-list/offers-list.tsx
+++ b/src/components/offers-list/offers-list.tsx
@@ -1,14 +1,13 @@
-import { memo } from 'react';
import { Offer } from '../../types/offer';
import { Card } from '../card/card';
type OffersListProps = {
offers: Offer[];
setActiveOfferId: (id: string | null) => void;
- isNearby?: boolean;
+ parentOfferId?: string;
}
-function OffersListComponent({ offers, setActiveOfferId, isNearby = false }: OffersListProps) {
+export function OffersList({ offers, setActiveOfferId, parentOfferId = undefined }: OffersListProps) {
const handleMouseEnter = (id: string) => {
setActiveOfferId(id);
};
@@ -17,7 +16,7 @@ function OffersListComponent({ offers, setActiveOfferId, isNearby = false }: Off
setActiveOfferId(null);
};
- const containerName = isNearby ? 'near-places__list places__list' : 'cities__places-list places__list tabs__content';
+ const containerName = parentOfferId ? 'near-places__list places__list' : 'cities__places-list places__list tabs__content';
return (
@@ -27,10 +26,9 @@ function OffersListComponent({ offers, setActiveOfferId, isNearby = false }: Off
key={offer.id}
onMouseEnter={() => handleMouseEnter(offer.id)}
onMouseLeave={handleMouseLeave}
+ parentOfferId={parentOfferId}
/>
))}
);
}
-
-export const OffersList = memo(OffersListComponent);
diff --git a/src/hooks/useMap/useMap.ts b/src/hooks/useMap/useMap.ts
index 9b8ac23..414a1a7 100644
--- a/src/hooks/useMap/useMap.ts
+++ b/src/hooks/useMap/useMap.ts
@@ -40,7 +40,7 @@ export function useMap(mapRef: React.MutableRefObject
, city: City) {
}
}
- }, [mapRef, city]);
+ }, [mapRef, city, map]);
return map;
}
diff --git a/src/pages/favorites-page/favorites-page.tsx b/src/pages/favorites-page/favorites-page.tsx
index 5511e87..56ecc3b 100644
--- a/src/pages/favorites-page/favorites-page.tsx
+++ b/src/pages/favorites-page/favorites-page.tsx
@@ -3,6 +3,8 @@ import {FavoritesList} from '../../components/favorites-list/favorites-list.tsx'
import {useAppSelector} from '../../hooks';
import {Header} from '../../components/header/header.tsx';
import {getFavoriteOffers} from '../../store/user-data/selectors.ts';
+import {Link} from 'react-router-dom';
+import {AppRoute} from '../../const.ts';
export function FavoritesPage() {
const favoriteOffers = useAppSelector(getFavoriteOffers);
@@ -35,9 +37,9 @@ export function FavoritesPage() {
);
diff --git a/src/pages/login-page/login-page.test.tsx b/src/pages/login-page/login-page.test.tsx
index 278f550..eb3826a 100644
--- a/src/pages/login-page/login-page.test.tsx
+++ b/src/pages/login-page/login-page.test.tsx
@@ -54,7 +54,7 @@ describe('LoginPage Component', () => {
render(withStoreComponent);
- expect(screen.getByText('Amsterdam')).toBeInTheDocument();
- expect(screen.getByRole('link', { name: 'Amsterdam' })).toHaveAttribute('href', '#');
+ const locationLink = screen.getByRole('link-to-main');
+ expect(locationLink).not.toBeNull();
});
});
diff --git a/src/pages/login-page/login-page.tsx b/src/pages/login-page/login-page.tsx
index 5bc00d3..e2c9ecd 100644
--- a/src/pages/login-page/login-page.tsx
+++ b/src/pages/login-page/login-page.tsx
@@ -1,9 +1,21 @@
-import {Helmet} from 'react-helmet-async';
-import {LoginForm} from '../../components/login-form/login-form.tsx';
-import {Header} from '../../components/header/header.tsx';
-import {memo} from 'react';
+import { Helmet } from 'react-helmet-async';
+import { LoginForm } from '../../components/login-form/login-form.tsx';
+import { Header } from '../../components/header/header.tsx';
+import {memo, useCallback, useMemo} from 'react';
+import { Link } from 'react-router-dom';
+import {AppRoute, CITIES} from '../../const';
+import {useAppDispatch} from '../../hooks';
+import {setCity} from '../../store/slices/city-slice.ts';
function LoginPageComponent() {
+ const dispatch = useAppDispatch();
+
+ const randomCity = useMemo(() => CITIES[Math.floor(Math.random() * CITIES.length)], []);
+
+ const handleCityClick = useCallback(() => {
+ dispatch(setCity(randomCity));
+ }, [dispatch, randomCity]);
+
return (
@@ -16,9 +28,14 @@ function LoginPageComponent() {
diff --git a/src/pages/offer-page/offer-page.tsx b/src/pages/offer-page/offer-page.tsx
index e00e751..30a06d0 100644
--- a/src/pages/offer-page/offer-page.tsx
+++ b/src/pages/offer-page/offer-page.tsx
@@ -14,6 +14,7 @@ import {getComments} from '../../store/comments-data/selectors.ts';
import {AppRoute, AuthorizationStatus} from '../../const.ts';
import {redirectToRoute} from '../../store/action.ts';
import {getAuthorizationStatus} from '../../store/user-data/selectors.ts';
+import {showCustomToast} from '../../utils/show-custom-toast.tsx';
export function OfferPage() {
const {id} = useParams<{ id: string }>();
@@ -63,6 +64,12 @@ export function OfferPage() {
dispatch(fetchDetailedOfferAction(offer.id));
};
+ const handleClickWrapper = () => {
+ handleFavoriteClick().catch((error) => {
+ showCustomToast(`${error}`);
+ });
+ };
+
return (
@@ -95,7 +102,7 @@ export function OfferPage() {
diff --git a/src/services/api.ts b/src/services/api.ts
index b42a85c..083215f 100644
--- a/src/services/api.ts
+++ b/src/services/api.ts
@@ -1,7 +1,7 @@
import axios, {AxiosError, AxiosInstance, AxiosResponse, InternalAxiosRequestConfig} from 'axios';
import {getToken} from './token.ts';
import {StatusCodes} from 'http-status-codes';
-import {showCustomToast} from '../components/custom-toast/custom-toast.tsx';
+import {showCustomToast} from '../utils/show-custom-toast.tsx';
type DetailMessageType = {
type: string;
diff --git a/src/store/city-data/selectors.test.ts b/src/store/city-data/selectors.test.ts
new file mode 100644
index 0000000..77ccf71
--- /dev/null
+++ b/src/store/city-data/selectors.test.ts
@@ -0,0 +1,33 @@
+import { expect } from 'vitest';
+import { NameSpace } from '../../const.ts';
+import {getActiveCity} from './selectors.ts';
+import {createRandomState} from '../../utils/create-random-state.ts';
+
+describe('Selector: getActiveCity', () => {
+ it('should return the active city from the state', () => {
+ const state = createRandomState();
+
+ const result = getActiveCity(state);
+ expect(result).toBe('Paris');
+ });
+
+ it('should return an empty string if activeCity is not set', () => {
+ const state = createRandomState();
+ state[NameSpace.City].activeCity = '';
+
+ const result = getActiveCity(state);
+ expect(result).toBe('');
+ });
+
+ it('should return the active city after its change', () => {
+ const state = createRandomState();
+
+ const result1 = getActiveCity(state);
+ expect(result1).toBe('Paris');
+
+ state[NameSpace.City].activeCity = 'Amsterdam';
+
+ const result2 = getActiveCity(state);
+ expect(result2).toBe('Amsterdam');
+ });
+});
diff --git a/src/store/comments-data/selectors.test.ts b/src/store/comments-data/selectors.test.ts
new file mode 100644
index 0000000..dd1525f
--- /dev/null
+++ b/src/store/comments-data/selectors.test.ts
@@ -0,0 +1,48 @@
+import { expect } from 'vitest';
+import { getComments } from './selectors.ts';
+import { createRandomState } from '../../utils/create-random-state.ts';
+import { NameSpace } from '../../const.ts';
+import { Review } from '../../types/review.ts';
+
+describe('Selector: getComments', () => {
+ it('should return the comments from the state', () => {
+ const state = createRandomState();
+
+ const result = getComments(state);
+ expect(result).toBeInstanceOf(Array);
+ expect(result.length).toBeGreaterThan(0);
+ });
+
+ it('should return an empty array if comments are not set', () => {
+ const state = createRandomState();
+
+ state[NameSpace.Comments].comments = [];
+
+ const result = getComments(state);
+ expect(result).toEqual([]);
+ });
+
+ it('should return the updated comments after their change', () => {
+ const state = createRandomState();
+
+ const initialComments = getComments(state);
+ expect(initialComments.length).toBeGreaterThan(0);
+
+ const newComment: Review = {
+ id: '123',
+ comment: 'New comment',
+ rating: 5,
+ date: '2023-10-01T12:00:00.000Z',
+ user: {
+ name: 'John Doe',
+ avatarUrl: 'https://example.com/avatar.png',
+ isPro: true,
+ },
+ };
+ state[NameSpace.Comments].comments = [...initialComments, newComment];
+
+ const updatedComments = getComments(state);
+ expect(updatedComments.length).toBe(initialComments.length + 1);
+ expect(updatedComments).toContainEqual(newComment);
+ });
+});
diff --git a/src/store/offer-data/selectors.test.ts b/src/store/offer-data/selectors.test.ts
new file mode 100644
index 0000000..2ade242
--- /dev/null
+++ b/src/store/offer-data/selectors.test.ts
@@ -0,0 +1,75 @@
+import {createRandomState} from '../../utils/create-random-state.ts';
+import {getNearbyOffers, getOffer} from './selectors.ts';
+import {NameSpace} from '../../const.ts';
+import {createRandomDetailedOffer} from '../../utils/create-random-detailed-offer.ts';
+import {createRandomOffer} from '../../utils/create-random-offer.ts';
+
+describe('Selector: getOffer', () => {
+ it('should return the detailed offer from the state', () => {
+ const state = createRandomState();
+
+ const result = getOffer(state);
+ expect(result).toBeInstanceOf(Object);
+ expect(result).toHaveProperty('id');
+ expect(result).toHaveProperty('title');
+ expect(result).toHaveProperty('description');
+ });
+
+ it('should return null if the detailed offer is not set', () => {
+ const state = createRandomState();
+
+ state[NameSpace.Offer].offer = null;
+
+ const result = getOffer(state);
+ expect(result).toBeNull();
+ });
+
+ it('should return the updated offer after its change', () => {
+ const state = createRandomState();
+
+ const initialOffer = getOffer(state);
+ expect(initialOffer).toBeInstanceOf(Object);
+
+ const newOffer = createRandomDetailedOffer();
+ state[NameSpace.Offer].offer = newOffer;
+
+ const updatedOffer = getOffer(state);
+ expect(updatedOffer).toEqual(newOffer);
+ });
+});
+
+describe('Selector: getNearbyOffers', () => {
+ it('should return the nearby offers from the state', () => {
+ const state = createRandomState();
+
+ const result = getNearbyOffers(state);
+ expect(result).toBeInstanceOf(Array);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty('id');
+ expect(result[0]).toHaveProperty('title');
+ expect(result[0]).toHaveProperty('type');
+ });
+
+ it('should return an empty array if nearby offers are not set', () => {
+ const state = createRandomState();
+
+ state[NameSpace.Offer].nearbyOffers = [];
+
+ const result = getNearbyOffers(state);
+ expect(result).toEqual([]);
+ });
+
+ it('should return the updated nearby offers after their change', () => {
+ const state = createRandomState();
+
+ const initialNearbyOffers = getNearbyOffers(state);
+ expect(initialNearbyOffers.length).toBeGreaterThan(0);
+
+ const newNearbyOffer = createRandomOffer();
+ state[NameSpace.Offer].nearbyOffers = [...initialNearbyOffers, newNearbyOffer];
+
+ const updatedNearbyOffers = getNearbyOffers(state);
+ expect(updatedNearbyOffers.length).toBe(initialNearbyOffers.length + 1);
+ expect(updatedNearbyOffers).toContainEqual(newNearbyOffer);
+ });
+});
diff --git a/src/store/offers-data/selectors.test.ts b/src/store/offers-data/selectors.test.ts
new file mode 100644
index 0000000..e6aafe1
--- /dev/null
+++ b/src/store/offers-data/selectors.test.ts
@@ -0,0 +1,68 @@
+import {createRandomState} from '../../utils/create-random-state.ts';
+import {getDataLoadingStatus, getOffers} from './selectors.ts';
+import {NameSpace} from '../../const.ts';
+import {createRandomOffer} from '../../utils/create-random-offer.ts';
+
+describe('Selector: getOffers', () => {
+ it('should return the offers from the state', () => {
+ const state = createRandomState();
+
+ const result = getOffers(state);
+ expect(result).toBeInstanceOf(Array);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty('id');
+ expect(result[0]).toHaveProperty('title');
+ expect(result[0]).toHaveProperty('isPremium');
+ });
+
+ it('should return an empty array if offers are not set', () => {
+ const state = createRandomState();
+
+ state[NameSpace.Offers].offers = [];
+
+ const result = getOffers(state);
+ expect(result).toEqual([]);
+ });
+
+ it('should return the updated offers after their change', () => {
+ const state = createRandomState();
+
+ const initialOffers = getOffers(state);
+ expect(initialOffers.length).toBeGreaterThan(0);
+
+ const newOffer = createRandomOffer();
+ state[NameSpace.Offers].offers = [...initialOffers, newOffer];
+
+ const updatedOffers = getOffers(state);
+ expect(updatedOffers.length).toBe(initialOffers.length + 1);
+ expect(updatedOffers).toContainEqual(newOffer);
+ });
+});
+
+describe('Selector: getDataLoadingStatus', () => {
+ it('should return the data loading status from the state', () => {
+ const state = createRandomState();
+
+ const result = getDataLoadingStatus(state);
+ expect(typeof result).toBe('boolean');
+ });
+
+ it('should return false if data loading status is not set', () => {
+ const state = createRandomState();
+
+ const result = getDataLoadingStatus(state);
+ expect(result).toBe(false);
+ });
+
+ it('should return the updated data loading status after its change', () => {
+ const state = createRandomState();
+
+ const initialStatus = getDataLoadingStatus(state);
+ expect(typeof initialStatus).toBe('boolean');
+
+ state[NameSpace.Offers].isDataLoading = !initialStatus;
+
+ const updatedStatus = getDataLoadingStatus(state);
+ expect(updatedStatus).toBe(!initialStatus);
+ });
+});
diff --git a/src/store/user-data/selectors.test.ts b/src/store/user-data/selectors.test.ts
new file mode 100644
index 0000000..2b3f2e0
--- /dev/null
+++ b/src/store/user-data/selectors.test.ts
@@ -0,0 +1,105 @@
+import {getAuthorizationStatus, getFavoriteOffers, getUserInfo} from './selectors.ts';
+import {createRandomState} from '../../utils/create-random-state.ts';
+import {AuthorizationStatus, NameSpace} from '../../const.ts';
+import {createRandomUserInfo} from '../../utils/create-random-user-info.ts';
+import {createRandomOffer} from '../../utils/create-random-offer.ts';
+
+describe('Selector: getAuthorizationStatus', () => {
+ it('should return the authorization status from the state', () => {
+ const state = createRandomState();
+
+ const result = getAuthorizationStatus(state);
+ expect(Object.values(AuthorizationStatus)).toContain(result);
+ });
+
+ it('should return "NoAuth" if authorization status is not set', () => {
+ const state = createRandomState();
+
+ state[NameSpace.User].authorizationStatus = AuthorizationStatus.NoAuth;
+
+ const result = getAuthorizationStatus(state);
+ expect(result).toBe(AuthorizationStatus.NoAuth);
+ });
+
+ it('should return the updated authorization status after its change', () => {
+ const state = createRandomState();
+
+ const initialStatus = getAuthorizationStatus(state);
+ expect(Object.values(AuthorizationStatus)).toContain(initialStatus);
+
+ state[NameSpace.User].authorizationStatus = AuthorizationStatus.NoAuth;
+
+ const updatedStatus = getAuthorizationStatus(state);
+ expect(updatedStatus).toBe(AuthorizationStatus.NoAuth);
+ });
+});
+
+describe('Selector: getUserInfo', () => {
+ it('should return the user info from the state', () => {
+ const state = createRandomState();
+
+ const result = getUserInfo(state);
+ expect(result).toBeInstanceOf(Object);
+ expect(result).toHaveProperty('name');
+ expect(result).toHaveProperty('avatarUrl');
+ expect(result).toHaveProperty('isPro');
+ });
+
+ it('should return null if user info is not set', () => {
+ const state = createRandomState();
+
+ state[NameSpace.User].userInfo = null;
+
+ const result = getUserInfo(state);
+ expect(result).toBeNull();
+ });
+
+ it('should return the updated user info after its change', () => {
+ const state = createRandomState();
+
+ const initialUserInfo = getUserInfo(state);
+ expect(initialUserInfo).toBeInstanceOf(Object);
+
+ const newUserInfo = createRandomUserInfo();
+ state[NameSpace.User].userInfo = newUserInfo;
+
+ const updatedUserInfo = getUserInfo(state);
+ expect(updatedUserInfo).toEqual(newUserInfo);
+ });
+});
+
+describe('Selector: getFavoriteOffers', () => {
+ it('should return the favorite offers from the state', () => {
+ const state = createRandomState();
+
+ const result = getFavoriteOffers(state);
+ expect(result).toBeInstanceOf(Array);
+ expect(result.length).toBeGreaterThan(0);
+ expect(result[0]).toHaveProperty('id');
+ expect(result[0]).toHaveProperty('title');
+ expect(result[0]).toHaveProperty('isFavorite');
+ });
+
+ it('should return an empty array if favorite offers are not set', () => {
+ const state = createRandomState();
+
+ state[NameSpace.User].favoriteOffers = [];
+
+ const result = getFavoriteOffers(state);
+ expect(result).toEqual([]);
+ });
+
+ it('should return the updated favorite offers after their change', () => {
+ const state = createRandomState();
+
+ const initialFavoriteOffers = getFavoriteOffers(state);
+ expect(initialFavoriteOffers.length).toBeGreaterThan(0);
+
+ const newFavoriteOffer = createRandomOffer();
+ state[NameSpace.User].favoriteOffers = [...initialFavoriteOffers, newFavoriteOffer];
+
+ const updatedFavoriteOffers = getFavoriteOffers(state);
+ expect(updatedFavoriteOffers.length).toBe(initialFavoriteOffers.length + 1);
+ expect(updatedFavoriteOffers).toContainEqual(newFavoriteOffer);
+ });
+});
diff --git a/src/utils/create-random-state.ts b/src/utils/create-random-state.ts
new file mode 100644
index 0000000..6a1e795
--- /dev/null
+++ b/src/utils/create-random-state.ts
@@ -0,0 +1,30 @@
+import {State} from '../types/state.ts';
+import {AuthorizationStatus, NameSpace} from '../const.ts';
+import {createRandomReview} from './create-random-review.ts';
+import {createRandomDetailedOffer} from './create-random-detailed-offer.ts';
+import {createRandomOffer} from './create-random-offer.ts';
+import {createRandomUserInfo} from './create-random-user-info.ts';
+
+export function createRandomState() : State {
+ return {
+ [NameSpace.City]: {
+ activeCity: 'Paris',
+ },
+ [NameSpace.Comments]: {
+ comments: [createRandomReview()],
+ },
+ [NameSpace.Offer]: {
+ offer: createRandomDetailedOffer(),
+ nearbyOffers: [createRandomOffer(), createRandomOffer()],
+ },
+ [NameSpace.Offers]: {
+ offers: [createRandomOffer(), createRandomOffer(), createRandomOffer()],
+ isDataLoading: false,
+ },
+ [NameSpace.User]: {
+ authorizationStatus: AuthorizationStatus.Auth,
+ userInfo: createRandomUserInfo(),
+ favoriteOffers: [createRandomOffer(), createRandomOffer()],
+ },
+ };
+}
diff --git a/src/utils/show-custom-toast.tsx b/src/utils/show-custom-toast.tsx
new file mode 100644
index 0000000..3180c10
--- /dev/null
+++ b/src/utils/show-custom-toast.tsx
@@ -0,0 +1,6 @@
+import {toast} from 'react-toastify';
+import {CustomToast} from '../components/custom-toast/custom-toast.tsx';
+
+export const showCustomToast = (message: string) => {
+ toast(
);
+};