Fixed issue with SSR
This commit is contained in:
parent
148fd20b66
commit
6deb48239e
@ -7,11 +7,11 @@ import { makeStore } from '@/shared/store';
|
||||
export default async function About() {
|
||||
const store = makeStore();
|
||||
|
||||
const { data, isLoading } = await store.dispatch(
|
||||
const { data } = await store.dispatch(
|
||||
mainPageApi.endpoints.fetchAboutUsPageContent.initiate(),
|
||||
);
|
||||
|
||||
if (isLoading || !data) return null;
|
||||
if (!data) return null;
|
||||
|
||||
return <AboutPage content={data} />;
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import oriyoClient from '@/app/api-utlities/utilities/oriyo.client';
|
||||
|
||||
import { validationErrorHandler } from '../../middlewares/error-handler.middleware';
|
||||
|
||||
export const routeHandler = async (req: NextRequest) => {
|
||||
const routeHandler = async (req: NextRequest) => {
|
||||
const bonusTokenData = req.cookies.get('bonus__token');
|
||||
|
||||
if (!bonusTokenData) {
|
||||
|
||||
@ -2,9 +2,9 @@ import { NextRequest, NextResponse } from 'next/server';
|
||||
import { ZodError } from 'zod';
|
||||
|
||||
export const validationErrorHandler =
|
||||
(handler: Function) => async (req: NextRequest, res: NextResponse) => {
|
||||
(handler: Function) => async (req: NextRequest) => {
|
||||
try {
|
||||
return await handler(req, res);
|
||||
return await handler(req);
|
||||
} catch (error) {
|
||||
if (error instanceof ZodError)
|
||||
return NextResponse.json({ message: error.format() }, { status: 400 });
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
import {
|
||||
presentHistoryItems,
|
||||
presentReviews,
|
||||
presentStations,
|
||||
presentTeamMembers,
|
||||
} from '@/app/api-utlities/presenters';
|
||||
import { aboutUsPageRequest } from '@/app/api-utlities/requests/about-us-page.request';
|
||||
import { requestTaylor } from '@/app/api-utlities/utilities/taylor.client';
|
||||
|
||||
import { validationErrorHandler } from '../../middlewares/error-handler.middleware';
|
||||
|
||||
const routeHandler = async () => {
|
||||
const response = await requestTaylor(aboutUsPageRequest);
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
team: presentTeamMembers(response.data._komanda),
|
||||
history: presentHistoryItems(response.data._istoriya),
|
||||
stations: presentStations(response.data._azs),
|
||||
reviews: presentReviews(response.data._otzyvy),
|
||||
}),
|
||||
{
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export const GET = validationErrorHandler(routeHandler);
|
||||
@ -1,28 +0,0 @@
|
||||
import {
|
||||
presentDiscounts,
|
||||
presentJobs,
|
||||
presentPartners,
|
||||
presentStations,
|
||||
} from '@/app/api-utlities/presenters';
|
||||
import { mainPageRequest } from '@/app/api-utlities/requests/main-page.request';
|
||||
import { requestTaylor } from '@/app/api-utlities/utilities/taylor.client';
|
||||
|
||||
import { validationErrorHandler } from '../../middlewares/error-handler.middleware';
|
||||
|
||||
const routeHandler = async (request: Request) => {
|
||||
const response = await requestTaylor(mainPageRequest);
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
partners: presentPartners(response.data._partners),
|
||||
jobs: presentJobs(response.data._vacancies),
|
||||
discounts: presentDiscounts(response.data._akcii),
|
||||
stations: presentStations(response.data._azs),
|
||||
}),
|
||||
{
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export const GET = validationErrorHandler(routeHandler);
|
||||
@ -1,14 +0,0 @@
|
||||
import { presentTexts } from '@/app/api-utlities/presenters';
|
||||
import { textsRequest } from '@/app/api-utlities/requests/common';
|
||||
import { requestTaylor } from '@/app/api-utlities/utilities/taylor.client';
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const response = await requestTaylor(textsRequest);
|
||||
|
||||
return new Response(
|
||||
JSON.stringify(presentTexts(response.data._kontentSajta)),
|
||||
{
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -37,7 +37,7 @@ export default async function RootLayout({
|
||||
className='scroll-smooth'
|
||||
style={{ scrollBehavior: 'smooth' }}
|
||||
>
|
||||
<body className={`${inter.className} antialiased min-w-2xs`}>
|
||||
<body className={`${inter.className} min-w-2xs antialiased`}>
|
||||
<Providers textItems={response.data as TextItem[]}>
|
||||
<Header />
|
||||
{children}
|
||||
|
||||
@ -15,7 +15,7 @@ import { VacanciesSection } from '@/widgets/vacancies-section';
|
||||
export default async function Home() {
|
||||
const store = makeStore();
|
||||
|
||||
const { data, isLoading } = await store.dispatch(
|
||||
const { data, isLoading, error } = await store.dispatch(
|
||||
mainPageApi.endpoints.fetchMainPageContent.initiate(),
|
||||
);
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ import {
|
||||
} from 'lucide-react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { Stations } from '@/app/api-utlities/@types/main';
|
||||
import { Stations } from '@/app/api-utlities/@types';
|
||||
|
||||
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
||||
import { Badge } from '@/shared/shadcn-ui/badge';
|
||||
|
||||
@ -1,19 +1,59 @@
|
||||
import { jsonToGraphQLQuery } from 'json-to-graphql-query';
|
||||
|
||||
import { AboutUsPageData } from '@/app/api-utlities/@types/about-us';
|
||||
import { MainPageData } from '@/app/api-utlities/@types/main';
|
||||
import {
|
||||
presentDiscounts,
|
||||
presentHistoryItems,
|
||||
presentJobs,
|
||||
presentPartners,
|
||||
presentReviews,
|
||||
presentStations,
|
||||
presentTeamMembers,
|
||||
} from '@/app/api-utlities/presenters';
|
||||
import { aboutUsPageRequest } from '@/app/api-utlities/requests/about-us-page.request';
|
||||
import { mainPageRequest } from '@/app/api-utlities/requests/main-page.request';
|
||||
|
||||
import { baseAPI } from '@/shared/api/base-api';
|
||||
import { taylorAPI } from '@/shared/api/taylor-api';
|
||||
|
||||
export const mainPageApi = baseAPI.injectEndpoints({
|
||||
export const mainPageApi = taylorAPI.injectEndpoints({
|
||||
endpoints: (builder) => ({
|
||||
fetchMainPageContent: builder.query<MainPageData, void>({
|
||||
query: () => '/pages/main',
|
||||
query: () => ({
|
||||
url: '',
|
||||
method: 'POST',
|
||||
body: {
|
||||
query: jsonToGraphQLQuery({ query: mainPageRequest }),
|
||||
},
|
||||
}),
|
||||
|
||||
transformResponse: (response: any) => {
|
||||
return {
|
||||
partners: presentPartners(response.data._partners),
|
||||
jobs: presentJobs(response.data._vacancies),
|
||||
discounts: presentDiscounts(response.data._akcii),
|
||||
stations: presentStations(response.data._azs),
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
fetchAboutUsPageContent: builder.query<AboutUsPageData, void>({
|
||||
query: () => '/pages/about-us',
|
||||
fetchAboutUsPageContent: builder.mutation<AboutUsPageData, void>({
|
||||
query: () => ({
|
||||
url: '',
|
||||
method: 'POST',
|
||||
body: {
|
||||
query: jsonToGraphQLQuery({ query: aboutUsPageRequest }),
|
||||
},
|
||||
}),
|
||||
|
||||
transformResponse: (response: any) => {
|
||||
return {
|
||||
team: presentTeamMembers(response.data._komanda),
|
||||
history: presentHistoryItems(response.data._istoriya),
|
||||
stations: presentStations(response.data._azs),
|
||||
reviews: presentReviews(response.data._otzyvy),
|
||||
};
|
||||
},
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export const { useFetchMainPageContentQuery, useFetchAboutUsPageContentQuery } =
|
||||
mainPageApi;
|
||||
|
||||
@ -4,6 +4,7 @@ import { deleteCookie, getCookie } from 'cookies-next';
|
||||
import { Building2, Fuel, User } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import { useRouter, useSearchParams } from 'next/navigation';
|
||||
import { Suspense } from 'react';
|
||||
|
||||
import { LoginForm } from '@/features/auth/login-form';
|
||||
|
||||
@ -16,13 +17,13 @@ import {
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from '@/shared/shadcn-ui/card';
|
||||
import Container from '@/shared/shadcn-ui/conteiner';
|
||||
import {
|
||||
Tabs,
|
||||
TabsContent,
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
} from '@/shared/shadcn-ui/tabs';
|
||||
import Container from '@/shared/shadcn-ui/conteiner';
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
@ -41,16 +42,97 @@ const tabs = [
|
||||
},
|
||||
];
|
||||
|
||||
export default function LoginPage() {
|
||||
function LoginPageTabs() {
|
||||
const { t } = useTextController();
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
const defaultTab = searchParams.get('tab') || 'bonus';
|
||||
|
||||
const handleTabChange = (tabType: string) => {
|
||||
router.push(`?tab=${tabType}`, undefined, { shallow: true });
|
||||
router.push(`?tab=${tabType}`, undefined);
|
||||
};
|
||||
|
||||
return (
|
||||
<Tabs
|
||||
defaultValue={defaultTab}
|
||||
value={defaultTab}
|
||||
onValueChange={handleTabChange}
|
||||
className='w-full'
|
||||
>
|
||||
<TabsList className='mb-8 flex h-fit w-full flex-col sm:flex-row'>
|
||||
{tabs.map((tab) => {
|
||||
return (
|
||||
<TabsTrigger
|
||||
key={tab.label}
|
||||
value={tab.type}
|
||||
className='w-full text-base'
|
||||
>
|
||||
<tab.Icon className='mr-2 h-4 w-4' /> {t(tab.label)}
|
||||
</TabsTrigger>
|
||||
);
|
||||
})}
|
||||
</TabsList>
|
||||
|
||||
{tabs.map((tab) => {
|
||||
const tabCookieName = `${tab.type}__token`;
|
||||
|
||||
const authenticationCookie = getCookie(tabCookieName);
|
||||
|
||||
if (authenticationCookie) {
|
||||
return (
|
||||
<TabsContent key={tab.label} value={tab.type}>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>{t(tab.title)}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className='flex justify-center gap-2 space-y-4'>
|
||||
<Link
|
||||
href={
|
||||
tab.type === 'bonus'
|
||||
? '/customer-dashboard'
|
||||
: '/corporate-dashboard'
|
||||
}
|
||||
>
|
||||
<Button className='flex items-center'>Открыть</Button>
|
||||
</Link>
|
||||
<Button
|
||||
variant='outline'
|
||||
className='flex items-center gap-2'
|
||||
onClick={() => {
|
||||
deleteCookie(tabCookieName);
|
||||
window.location.reload();
|
||||
}}
|
||||
>
|
||||
Выйти
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TabsContent key={tab.label} value={tab.type}>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>{t(tab.title)}</CardTitle>
|
||||
<CardDescription>{t(tab.description)}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className='space-y-4'>
|
||||
<LoginForm type={tab.type} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
);
|
||||
})}
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
|
||||
export default function LoginPage() {
|
||||
const { t } = useTextController();
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<div className='flex min-h-screen flex-col items-center justify-center'>
|
||||
@ -67,86 +149,17 @@ export default function LoginPage() {
|
||||
</div>
|
||||
|
||||
<div data-aos='zoom-in' className='mx-auto max-w-lg'>
|
||||
<Tabs
|
||||
defaultValue={defaultTab}
|
||||
value={defaultTab}
|
||||
onValueChange={handleTabChange}
|
||||
className='w-full'
|
||||
>
|
||||
<TabsList className='mb-8 flex h-fit w-full flex-col sm:flex-row'>
|
||||
{tabs.map((tab) => {
|
||||
return (
|
||||
<TabsTrigger
|
||||
key={tab.label}
|
||||
value={tab.type}
|
||||
className='w-full text-base'
|
||||
>
|
||||
<tab.Icon className='mr-2 h-4 w-4' /> {t(tab.label)}
|
||||
</TabsTrigger>
|
||||
);
|
||||
})}
|
||||
</TabsList>
|
||||
|
||||
{tabs.map((tab) => {
|
||||
const tabCookieName = `${tab.type}__token`;
|
||||
|
||||
const authenticationCookie = getCookie(tabCookieName);
|
||||
|
||||
if (authenticationCookie) {
|
||||
return (
|
||||
<TabsContent key={tab.label} value={tab.type}>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>{t(tab.title)}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className='flex justify-center gap-2 space-y-4'>
|
||||
<Link
|
||||
href={
|
||||
tab.type === 'bonus'
|
||||
? '/customer-dashboard'
|
||||
: '/corporate-dashboard'
|
||||
}
|
||||
>
|
||||
<Button className='flex items-center'>
|
||||
Открыть
|
||||
</Button>
|
||||
</Link>
|
||||
<Button
|
||||
variant='outline'
|
||||
className='flex items-center gap-2'
|
||||
onClick={() => {
|
||||
deleteCookie(tabCookieName);
|
||||
window.location.reload();
|
||||
}}
|
||||
>
|
||||
Выйти
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TabsContent key={tab.label} value={tab.type}>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>{t(tab.title)}</CardTitle>
|
||||
<CardDescription>{t(tab.description)}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className='space-y-4'>
|
||||
<LoginForm type={tab.type} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
);
|
||||
})}
|
||||
</Tabs>
|
||||
<Suspense>
|
||||
<LoginPageTabs />
|
||||
</Suspense>
|
||||
|
||||
<div className='mt-8 text-center text-sm text-gray-500'>
|
||||
<p>
|
||||
{t('auth.loginIssues')}{' '}
|
||||
<Link href='/contact' className='text-red-600 hover:underline'>
|
||||
<Link
|
||||
href='/contact'
|
||||
className='text-red-600 hover:underline'
|
||||
>
|
||||
{t('auth.contactLink')}
|
||||
</Link>
|
||||
</p>
|
||||
|
||||
14
src/shared/api/taylor-api.ts
Normal file
14
src/shared/api/taylor-api.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query';
|
||||
|
||||
const baseQuery = fetchBaseQuery({
|
||||
baseUrl: process.env.TAYLOR_API_ENDPOINT,
|
||||
headers: {
|
||||
Authorization: process.env.TAYLOR_API_TOKEN || '',
|
||||
},
|
||||
});
|
||||
|
||||
export const taylorAPI = createApi({
|
||||
reducerPath: 'taylorAPI',
|
||||
baseQuery,
|
||||
endpoints: () => ({}),
|
||||
});
|
||||
@ -5,7 +5,7 @@ import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { Discounts } from '@/app/api-utlities/@types/main';
|
||||
import { Discounts } from '@/app/api-utlities/@types';
|
||||
|
||||
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
||||
import { Button } from '@/shared/shadcn-ui/button';
|
||||
|
||||
@ -1,12 +1,25 @@
|
||||
import { baseAPI } from '@/shared/api/base-api';
|
||||
import { jsonToGraphQLQuery } from 'json-to-graphql-query';
|
||||
|
||||
import { presentTexts } from '@/app/api-utlities/presenters';
|
||||
import { textsRequest } from '@/app/api-utlities/requests/common';
|
||||
|
||||
import { taylorAPI } from '@/shared/api/taylor-api';
|
||||
import { TextItem } from '@/shared/types/text.types';
|
||||
|
||||
export const textControlApi = baseAPI.injectEndpoints({
|
||||
export const textControlApi = taylorAPI.injectEndpoints({
|
||||
endpoints: (builder) => ({
|
||||
fetchText: builder.query<TextItem[], void>({
|
||||
query: () => '/text',
|
||||
query: () => ({
|
||||
url: '',
|
||||
method: 'POST',
|
||||
body: {
|
||||
query: jsonToGraphQLQuery({ query: textsRequest }),
|
||||
},
|
||||
}),
|
||||
|
||||
transformResponse: (response: any) => {
|
||||
return presentTexts(response.data._kontentSajta);
|
||||
},
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export const { useFetchTextQuery } = textControlApi;
|
||||
|
||||
@ -2,6 +2,9 @@ import { combineReducers } from '@reduxjs/toolkit';
|
||||
|
||||
import { baseAPI } from '@/shared/api/base-api';
|
||||
|
||||
import { taylorAPI } from '../api/taylor-api';
|
||||
|
||||
export const rootReducer = combineReducers({
|
||||
[baseAPI.reducerPath]: baseAPI.reducer,
|
||||
[taylorAPI.reducerPath]: taylorAPI.reducer,
|
||||
});
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
import { Calendar, ChevronDown, ChevronUp } from 'lucide-react';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { HistoryItems } from '@/app/api-utlities/@types/about-us';
|
||||
import { HistoryItems } from '@/app/api-utlities/@types';
|
||||
|
||||
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
||||
import { Button } from '@/shared/shadcn-ui/button';
|
||||
|
||||
@ -2,9 +2,8 @@
|
||||
|
||||
import { MapPin } from 'lucide-react';
|
||||
|
||||
import { Stations } from '@/app/api-utlities/@types/main';
|
||||
import { Stations } from '@/app/api-utlities/@types';
|
||||
|
||||
import { GasStationMap } from '@/features/map';
|
||||
import { Point } from '@/features/map/model';
|
||||
import { YandexMap } from '@/features/map/ui/yandex-map';
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import { Handshake } from 'lucide-react';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
|
||||
import { Partners } from '@/app/api-utlities/@types/main';
|
||||
import { Partners } from '@/app/api-utlities/@types';
|
||||
|
||||
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
||||
import { Button } from '@/shared/shadcn-ui/button';
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
import { Gift } from 'lucide-react';
|
||||
|
||||
import { Discounts } from '@/app/api-utlities/@types/main';
|
||||
import { Discounts } from '@/app/api-utlities/@types';
|
||||
|
||||
import PromotionSlider from '@/shared/components/promotion-slider';
|
||||
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
import { Briefcase } from 'lucide-react';
|
||||
|
||||
import { Jobs } from '@/app/api-utlities/@types/main';
|
||||
import { Jobs } from '@/app/api-utlities/@types';
|
||||
|
||||
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
||||
import { cn } from '@/shared/lib/utils';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user