-
-
- Бонусный клиент
-
-
- Корпоративный клиент
-
+
+ {tabs.map((tab) => {
+ return (
+
+ {tab.label}
+
+ );
+ })}
-
-
-
- Вход для бонусных клиентов
-
- Введите номер телефона и номер бонусной карты для входа в
- личный кабинет.
-
-
-
-
-
-
-
-
-
-
-
- Вход для корпоративных клиентов
-
- Введите номер телефона и номер корпоративной карты для
- входа в личный кабинет.
-
-
-
-
-
-
-
+ {tabs.map((tab) => {
+ return (
+
+
+
+ {tab.title}
+ {tab.description}
+
+
+
+
+
+
+ );
+ })}
diff --git a/src/entities/auth/api/login.api.ts b/src/entities/auth/api/login.api.ts
new file mode 100644
index 0000000..99ad4ed
--- /dev/null
+++ b/src/entities/auth/api/login.api.ts
@@ -0,0 +1,24 @@
+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({
+ 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;
diff --git a/src/entities/auth/index.ts b/src/entities/auth/index.ts
new file mode 100644
index 0000000..d99a63a
--- /dev/null
+++ b/src/entities/auth/index.ts
@@ -0,0 +1 @@
+export { useLazyLoginQuery } from './api/login.api';
diff --git a/src/entities/auth/model/contracts/login.contract.ts b/src/entities/auth/model/contracts/login.contract.ts
new file mode 100644
index 0000000..cb3a3da
--- /dev/null
+++ b/src/entities/auth/model/contracts/login.contract.ts
@@ -0,0 +1,9 @@
+import { LoginFormData } from '@/features/auth/login-form/model/login-form.schema';
+
+export interface LoginResponse {
+ success: boolean;
+}
+
+export interface LoginParams extends LoginFormData {
+ type: 'bonus' | 'corporate';
+}
diff --git a/src/entities/auth/model/types/index.ts b/src/entities/auth/model/types/index.ts
new file mode 100644
index 0000000..1144cca
--- /dev/null
+++ b/src/entities/auth/model/types/index.ts
@@ -0,0 +1,7 @@
+export interface LoginData {
+ card_id: number;
+ created_at: string;
+ phone: string;
+ token: string;
+ uid: string;
+}
diff --git a/src/features/auth/login-form/model/login-form.schema.ts b/src/features/auth/login-form/model/login-form.schema.ts
index eca9731..a8da155 100644
--- a/src/features/auth/login-form/model/login-form.schema.ts
+++ b/src/features/auth/login-form/model/login-form.schema.ts
@@ -6,13 +6,15 @@ export const loginFormSchema = z.object({
.trim()
.regex(/^[0-9+\-() ]*$/, {
message:
- 'Phone number can only contain numbers, spaces, and the following symbols: + - ( )',
+ 'Номер телефона может содержать только цифры, пробелы и следующие символы: + - ( )',
})
- .refine((val) => !val || val.length >= 5, {
- message:
- 'Phone number is too short. Please enter a complete phone number',
- }),
- cardNumber: z.string().min(16).trim(),
+ .min(5, 'Номер телефона слишком короткий. Введите полный номер телефона')
+ .max(13, 'Номер телефона не может быть длиннее 13 символов'),
+ cardNumber: z
+ .string()
+ .min(6, 'Неверный номер карты. Введите полный номер карты')
+ .max(20, 'Номер карты не может быть длиннее 20 символов')
+ .trim(),
});
export type LoginFormData = z.infer;
diff --git a/src/features/auth/login-form/ui/login-form.tsx b/src/features/auth/login-form/ui/login-form.tsx
index b89887b..ad2bc10 100644
--- a/src/features/auth/login-form/ui/login-form.tsx
+++ b/src/features/auth/login-form/ui/login-form.tsx
@@ -5,7 +5,9 @@ import { useRouter } from 'next/navigation';
import { useForm } from 'react-hook-form';
import { toast } from 'sonner';
-import { Button } from '@/shared/shadcn-ui/button';
+import { useLazyLoginQuery } from '@/entities/auth';
+
+import { SubmitButton } from '@/shared/components/submit-button';
import {
Form,
FormControl,
@@ -20,11 +22,12 @@ import { LoginFormData, loginFormSchema } from '../model/login-form.schema';
interface LoginFormProps {
// onSubmit: (data: any) => Promise;
+ type: 'bonus' | 'corporate';
}
-export const LoginForm = ({}: LoginFormProps) => {
+export const LoginForm = ({ type }: LoginFormProps) => {
const router = useRouter();
- // const [login, results] = useLoginMutation();
+ const [login, { isLoading: isLoginLoading }] = useLazyLoginQuery();
const form = useForm({
resolver: zodResolver(loginFormSchema),
@@ -35,23 +38,29 @@ export const LoginForm = ({}: LoginFormProps) => {
});
const onSubmit = async (data: LoginFormData) => {
- // const response = await login(data).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!');
+ try {
+ const response = 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!');
- router.push('/customer-dashboard');
+ router.push(
+ type === 'bonus' ? '/customer-dashboard' : '/corporate-dashboard',
+ );
+ } catch (error) {
+ toast.error('An error occured during login');
+ }
};
return (
@@ -61,7 +70,7 @@ export const LoginForm = ({}: LoginFormProps) => {
control={form.control}
name='phoneNumber'
render={({ field }) => (
-
+
Номер телефона
{
control={form.control}
name='cardNumber'
render={({ field }) => (
-
+
Номер карты
{
)}
/>
-
+
);
diff --git a/src/shared/components/submit-button.tsx b/src/shared/components/submit-button.tsx
new file mode 100644
index 0000000..ef9db2d
--- /dev/null
+++ b/src/shared/components/submit-button.tsx
@@ -0,0 +1,36 @@
+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 (
+
+ );
+};
diff --git a/src/shared/store/root-reducer.ts b/src/shared/store/root-reducer.ts
index 27360ad..56b999c 100644
--- a/src/shared/store/root-reducer.ts
+++ b/src/shared/store/root-reducer.ts
@@ -1,6 +1,10 @@
import { combineReducers } from '@reduxjs/toolkit';
+
+import { loginAPI } from '@/entities/auth/api/login.api';
+
import { baseAPI } from '@/shared/api/base-api';
export const rootReducer = combineReducers({
[baseAPI.reducerPath]: baseAPI.reducer,
+ [loginAPI.reducerPath]: loginAPI.reducer,
});