Compare commits
No commits in common. "b5b20b054da8c207eba9390532e48c2054998e4d" and "fe52df1b7a403c686484778c9b0620c2c235c3aa" have entirely different histories.
b5b20b054d
...
fe52df1b7a
@ -1,59 +0,0 @@
|
|||||||
import { NextRequest, NextResponse } from 'next/server';
|
|
||||||
|
|
||||||
import { LoginData } from '@/entities/auth/model/types';
|
|
||||||
|
|
||||||
export const GET = async (req: NextRequest) => {
|
|
||||||
if (req.method !== 'GET') {
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: 'Method is not supported' },
|
|
||||||
{ status: 405 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const { searchParams } = req.nextUrl;
|
|
||||||
|
|
||||||
const phoneNumber = searchParams.get('phoneNumber');
|
|
||||||
const cardNumber = searchParams.get('cardNumber');
|
|
||||||
const type = searchParams.get('type');
|
|
||||||
|
|
||||||
if (!phoneNumber || !cardNumber || !type) {
|
|
||||||
return NextResponse.json({ error: 'Bad request' }, { status: 400 });
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const loginRes = await fetch(
|
|
||||||
`https://test.oriyo.tj/api/client/login?type=${type}&phone=${phoneNumber}&uid=${cardNumber}`,
|
|
||||||
{
|
|
||||||
method: 'GET',
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!loginRes.ok) {
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: 'Error during login' },
|
|
||||||
{ status: 400 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = (await loginRes.json()) as LoginData;
|
|
||||||
|
|
||||||
const token = data.token;
|
|
||||||
if (!token) {
|
|
||||||
return NextResponse.json({ error: 'No auth token' }, { status: 401 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = NextResponse.json({ success: true });
|
|
||||||
|
|
||||||
response.cookies.set('token', token, {
|
|
||||||
httpOnly: true,
|
|
||||||
path: '/',
|
|
||||||
maxAge: 2 * 60 * 60,
|
|
||||||
secure: process.env.NODE_ENV === 'production',
|
|
||||||
});
|
|
||||||
|
|
||||||
return response;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('login error:', error);
|
|
||||||
return NextResponse.json({ error: 'Server error' }, { status: 500 });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import LoginPage from '@/pages-templates/login';
|
import LoginPage from "@/pages-templates/login";
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
return <LoginPage />;
|
return <LoginPage/>
|
||||||
}
|
}
|
||||||
@ -1,24 +0,0 @@
|
|||||||
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
|
|
||||||
|
|
||||||
import { LoginParams, LoginResponse } from '../model/contracts/login.contract';
|
|
||||||
|
|
||||||
export const loginAPI = createApi({
|
|
||||||
baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
|
|
||||||
endpoints: (build) => ({
|
|
||||||
login: build.query<LoginResponse, LoginParams>({
|
|
||||||
query: (data) => {
|
|
||||||
const params = new URLSearchParams({
|
|
||||||
type: data.type,
|
|
||||||
phoneNumber: data.phoneNumber,
|
|
||||||
cardNumber: data.cardNumber,
|
|
||||||
}).toString();
|
|
||||||
|
|
||||||
return {
|
|
||||||
url: `/auth/login?${params}`,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const { useLazyLoginQuery } = loginAPI;
|
|
||||||
@ -1 +0,0 @@
|
|||||||
export { useLazyLoginQuery } from './api/login.api';
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import { LoginFormData } from '@/features/auth/login-form/model/login-form.schema';
|
|
||||||
|
|
||||||
export interface LoginResponse {
|
|
||||||
success: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface LoginParams extends LoginFormData {
|
|
||||||
type: 'bonus' | 'corporate';
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
export interface LoginData {
|
|
||||||
card_id: number;
|
|
||||||
created_at: string;
|
|
||||||
phone: string;
|
|
||||||
token: string;
|
|
||||||
uid: string;
|
|
||||||
}
|
|
||||||
@ -6,15 +6,13 @@ export const loginFormSchema = z.object({
|
|||||||
.trim()
|
.trim()
|
||||||
.regex(/^[0-9+\-() ]*$/, {
|
.regex(/^[0-9+\-() ]*$/, {
|
||||||
message:
|
message:
|
||||||
'Номер телефона может содержать только цифры, пробелы и следующие символы: + - ( )',
|
'Phone number can only contain numbers, spaces, and the following symbols: + - ( )',
|
||||||
})
|
})
|
||||||
.min(5, 'Номер телефона слишком короткий. Введите полный номер телефона')
|
.refine((val) => !val || val.length >= 5, {
|
||||||
.max(13, 'Номер телефона не может быть длиннее 13 символов'),
|
message:
|
||||||
cardNumber: z
|
'Phone number is too short. Please enter a complete phone number',
|
||||||
.string()
|
}),
|
||||||
.min(6, 'Неверный номер карты. Введите полный номер карты')
|
cardNumber: z.string().min(16).trim(),
|
||||||
.max(20, 'Номер карты не может быть длиннее 20 символов')
|
|
||||||
.trim(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type LoginFormData = z.infer<typeof loginFormSchema>;
|
export type LoginFormData = z.infer<typeof loginFormSchema>;
|
||||||
|
|||||||
@ -5,10 +5,7 @@ import { useRouter } from 'next/navigation';
|
|||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
|
|
||||||
import { useLazyLoginQuery } from '@/entities/auth';
|
import { Button } from '@/shared/shadcn-ui/button';
|
||||||
|
|
||||||
import { SubmitButton } from '@/shared/components/submit-button';
|
|
||||||
import { useLanguage } from '@/shared/language';
|
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
FormControl,
|
FormControl,
|
||||||
@ -20,16 +17,17 @@ import {
|
|||||||
import { Input } from '@/shared/shadcn-ui/input';
|
import { Input } from '@/shared/shadcn-ui/input';
|
||||||
|
|
||||||
import { LoginFormData, loginFormSchema } from '../model/login-form.schema';
|
import { LoginFormData, loginFormSchema } from '../model/login-form.schema';
|
||||||
|
import { useLanguage } from '@/shared/language';
|
||||||
|
|
||||||
interface LoginFormProps {
|
interface LoginFormProps {
|
||||||
type: 'bonus' | 'corporate';
|
// onSubmit: (data: any) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LoginForm = ({ type }: LoginFormProps) => {
|
export const LoginForm = ({}: LoginFormProps) => {
|
||||||
const { t } = useLanguage();
|
const {t} = useLanguage()
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [login, { isLoading: isLoginLoading }] = useLazyLoginQuery();
|
// const [login, results] = useLoginMutation();
|
||||||
|
|
||||||
const form = useForm<LoginFormData>({
|
const form = useForm<LoginFormData>({
|
||||||
resolver: zodResolver(loginFormSchema),
|
resolver: zodResolver(loginFormSchema),
|
||||||
@ -40,30 +38,34 @@ export const LoginForm = ({ type }: LoginFormProps) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const onSubmit = async (data: LoginFormData) => {
|
const onSubmit = async (data: LoginFormData) => {
|
||||||
try {
|
// const response = await login(data).unwrap();
|
||||||
await login({ ...data, type }).unwrap();
|
// const user = response.data;
|
||||||
|
// dispatch(
|
||||||
|
// setCredentials({
|
||||||
|
// user: {
|
||||||
|
// accessToken: user.accessToken,
|
||||||
|
// affiliateId: user.affiliateId,
|
||||||
|
// email: user.email,
|
||||||
|
// id: user.id,
|
||||||
|
// role: user.role,
|
||||||
|
// username: user.username,
|
||||||
|
// },
|
||||||
|
// }),
|
||||||
|
// );
|
||||||
toast.success('Logged in successfully!');
|
toast.success('Logged in successfully!');
|
||||||
router.push(
|
|
||||||
type === 'bonus' ? '/customer-dashboard' : '/corporate-dashboard',
|
router.push('/customer-dashboard');
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
toast.error('An error occured during login');
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form {...form} >
|
<Form {...form} >
|
||||||
<form
|
<form onSubmit={form.handleSubmit(onSubmit)} className='space-y-4 mx-auto'>
|
||||||
onSubmit={form.handleSubmit(onSubmit)}
|
|
||||||
className='mx-auto space-y-4'
|
|
||||||
>
|
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name='phoneNumber'
|
name='phoneNumber'
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className='flex flex-col'>
|
<FormItem>
|
||||||
<FormLabel>{t('auth.phoneNumber')}</FormLabel>
|
<FormLabel>{t("auth.phoneNumber")}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input
|
||||||
type='tel'
|
type='tel'
|
||||||
@ -80,8 +82,8 @@ export const LoginForm = ({ type }: LoginFormProps) => {
|
|||||||
control={form.control}
|
control={form.control}
|
||||||
name='cardNumber'
|
name='cardNumber'
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className='flex flex-col'>
|
<FormItem>
|
||||||
<FormLabel>{t('auth.cardNumber')}</FormLabel>
|
<FormLabel>{t("auth.cardNumber")}</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input
|
<Input
|
||||||
type='text'
|
type='text'
|
||||||
@ -93,14 +95,16 @@ export const LoginForm = ({ type }: LoginFormProps) => {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<SubmitButton
|
<Button
|
||||||
isLoading={isLoginLoading}
|
// isLoading={results.isLoading}
|
||||||
|
// title='Login'
|
||||||
type='submit'
|
type='submit'
|
||||||
className='w-full'
|
className='w-full'
|
||||||
disabled={isLoginLoading}
|
// variant={'default'}
|
||||||
|
// disabled={loading}
|
||||||
>
|
>
|
||||||
Войти
|
Войти
|
||||||
</SubmitButton>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,36 +0,0 @@
|
|||||||
import { Loader2Icon } from 'lucide-react';
|
|
||||||
|
|
||||||
import { Button, type ButtonProps } from '@/shared/shadcn-ui/button';
|
|
||||||
|
|
||||||
interface SubmitButtonProps extends ButtonProps {
|
|
||||||
title?: string;
|
|
||||||
isLoading: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const SubmitButton = ({
|
|
||||||
title = 'Отправить',
|
|
||||||
size = 'default',
|
|
||||||
type = 'submit',
|
|
||||||
className,
|
|
||||||
disabled,
|
|
||||||
isLoading,
|
|
||||||
onClick,
|
|
||||||
...props
|
|
||||||
}: SubmitButtonProps) => {
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
onClick={onClick}
|
|
||||||
type={type}
|
|
||||||
size={size}
|
|
||||||
className={className}
|
|
||||||
disabled={isLoading || disabled}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{isLoading ? (
|
|
||||||
<Loader2Icon className='animate-spin' />
|
|
||||||
) : (
|
|
||||||
(props.children ?? title)
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,10 +1,6 @@
|
|||||||
import { combineReducers } from '@reduxjs/toolkit';
|
import { combineReducers } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
import { loginAPI } from '@/entities/auth/api/login.api';
|
|
||||||
|
|
||||||
import { baseAPI } from '@/shared/api/base-api';
|
import { baseAPI } from '@/shared/api/base-api';
|
||||||
|
|
||||||
export const rootReducer = combineReducers({
|
export const rootReducer = combineReducers({
|
||||||
[baseAPI.reducerPath]: baseAPI.reducer,
|
[baseAPI.reducerPath]: baseAPI.reducer,
|
||||||
[loginAPI.reducerPath]: loginAPI.reducer,
|
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user