feat: invite code
This commit is contained in:
@@ -200,6 +200,7 @@ export type { FinishPauseByShiftIdResponse } from './models/FinishPauseByShiftId
|
||||
export type { FinishPauseByUserIdResponse } from './models/FinishPauseByUserIdResponse';
|
||||
export type { FinishShiftByIdResponse } from './models/FinishShiftByIdResponse';
|
||||
export type { FinishShiftResponse } from './models/FinishShiftResponse';
|
||||
export type { GenerateInviteCodeRequest } from './models/GenerateInviteCodeRequest';
|
||||
export type { GenerateInviteCodeResponse } from './models/GenerateInviteCodeResponse';
|
||||
export type { GetAllBarcodeTemplateAttributesResponse } from './models/GetAllBarcodeTemplateAttributesResponse';
|
||||
export type { GetAllBarcodeTemplateSizesResponse } from './models/GetAllBarcodeTemplateSizesResponse';
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import type { Body_upload_passport_image } from '../models/Body_upload_passport_image';
|
||||
import type { CreateUserRequest } from '../models/CreateUserRequest';
|
||||
import type { CreateUserResponse } from '../models/CreateUserResponse';
|
||||
import type { GenerateInviteCodeRequest } from '../models/GenerateInviteCodeRequest';
|
||||
import type { GenerateInviteCodeResponse } from '../models/GenerateInviteCodeResponse';
|
||||
import type { GetAllUsersResponse } from '../models/GetAllUsersResponse';
|
||||
import type { GetManagersResponse } from '../models/GetManagersResponse';
|
||||
@@ -134,10 +135,19 @@ export class UserService {
|
||||
* @returns GenerateInviteCodeResponse Successful Response
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static generateInviteCode(): CancelablePromise<GenerateInviteCodeResponse> {
|
||||
public static generateInviteCode({
|
||||
requestBody,
|
||||
}: {
|
||||
requestBody: GenerateInviteCodeRequest,
|
||||
}): CancelablePromise<GenerateInviteCodeResponse> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'POST',
|
||||
url: '/user/generate-invite-code',
|
||||
body: requestBody,
|
||||
mediaType: 'application/json',
|
||||
errors: {
|
||||
422: `Validation Error`,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
import { UserSchema, UserService } from "../../../../client";
|
||||
import { UserSchema } from "../../../../client";
|
||||
import { BaseTable } from "../../../../components/BaseTable/BaseTable.tsx";
|
||||
import { ActionIcon, Badge, Button, Flex, Input, rem, Text, Tooltip } from "@mantine/core";
|
||||
import { ActionIcon, Button, Flex, rem, Text, Tooltip } from "@mantine/core";
|
||||
import { useUsersTableColumns } from "./columns.tsx";
|
||||
import { IconEdit, IconQrcode, IconTrash } from "@tabler/icons-react";
|
||||
import { IconEdit, IconTrash } from "@tabler/icons-react";
|
||||
import { modals } from "@mantine/modals";
|
||||
import { MRT_TableOptions } from "mantine-react-table";
|
||||
import { useUsersTabContext } from "../../tabs/Users/contexts/UsersTabContext.tsx";
|
||||
import { notifications } from "../../../../shared/lib/notifications.ts";
|
||||
import { useClipboard } from "@mantine/hooks";
|
||||
|
||||
|
||||
const UsersTable = () => {
|
||||
const columns = useUsersTableColumns();
|
||||
const clipboard = useClipboard();
|
||||
const {
|
||||
usersCrud: {
|
||||
items,
|
||||
@@ -66,40 +63,7 @@ const UsersTable = () => {
|
||||
size: "md",
|
||||
});
|
||||
};
|
||||
const onGenerateQrClick = (user: UserSchema) => {
|
||||
const pdfWindow = window.open(
|
||||
`${import.meta.env.VITE_API_URL}/work-shifts/generate-qr-code/${user.id}`,
|
||||
);
|
||||
if (!pdfWindow) return;
|
||||
pdfWindow.print();
|
||||
};
|
||||
const onCreateInviteCodeClick = async () => {
|
||||
const { inviteCode, ok, message } = await UserService.generateInviteCode();
|
||||
if (!ok || !inviteCode) {
|
||||
notifications.error({ message });
|
||||
return;
|
||||
}
|
||||
modals.openConfirmModal({
|
||||
withCloseButton: false,
|
||||
children: (
|
||||
<Flex gap={rem(10)} direction={"column"} justify={"center"} align={"center"}>
|
||||
|
||||
<Text>
|
||||
Ваш код приглашения!
|
||||
</Text>
|
||||
<Badge variant={"default"} style={{cursor:"text"}} radius={"sm"} size={"xl"}>{inviteCode}</Badge>
|
||||
<Input.Description>
|
||||
Код действителен в течении 30 минут
|
||||
</Input.Description>
|
||||
</Flex>
|
||||
|
||||
),
|
||||
labels: { confirm: "Скопировать", cancel: "Закрыть" },
|
||||
onConfirm: () => {
|
||||
clipboard.copy(inviteCode);
|
||||
},
|
||||
});
|
||||
};
|
||||
return (
|
||||
<BaseTable
|
||||
data={items}
|
||||
@@ -117,14 +81,7 @@ const UsersTable = () => {
|
||||
onClick={() => onCreateClick()}>
|
||||
Создать пользователя
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => onCreateInviteCodeClick()}
|
||||
variant={"default"}
|
||||
>
|
||||
Создать код приглашения
|
||||
</Button>
|
||||
</Flex>
|
||||
|
||||
</Flex>
|
||||
),
|
||||
enableRowActions: true,
|
||||
@@ -148,15 +105,7 @@ const UsersTable = () => {
|
||||
<IconTrash />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
onClick={() => {
|
||||
onGenerateQrClick(row.original);
|
||||
}}
|
||||
label="QR-код">
|
||||
<ActionIcon variant={"default"}>
|
||||
<IconQrcode />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
|
||||
</Flex>
|
||||
),
|
||||
} as MRT_TableOptions<UserSchema>
|
||||
|
||||
@@ -17,12 +17,13 @@ const UserFormModal = ({
|
||||
id,
|
||||
innerProps,
|
||||
}: ContextModalProps<Props>) => {
|
||||
|
||||
const isEditing = "element" in innerProps;
|
||||
const [modalTab, setModalTab] = useState<ModalTab>(ModalTab.COMMON);
|
||||
|
||||
const closeModal = () => {
|
||||
context.closeContextModal(id);
|
||||
}
|
||||
};
|
||||
|
||||
if (!isEditing) {
|
||||
return (
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { UserRoleEnum } from "../../../../../../shared/enums/UserRole.ts";
|
||||
import { useForm } from "@mantine/form";
|
||||
import { UserSchema } from "../../../../../../client";
|
||||
import { UserSchema, UserService } from "../../../../../../client";
|
||||
import phone from "phone";
|
||||
import BaseFormModal, { CreateEditFormProps } from "../../../../../ClientsPage/modals/BaseFormModal/BaseFormModal.tsx";
|
||||
import { Checkbox, Fieldset, Input, Stack, Textarea, TextInput } from "@mantine/core";
|
||||
import { Badge, Button, Checkbox, Fieldset, Flex, Input, rem, Stack, Text, Textarea, TextInput } from "@mantine/core";
|
||||
import { capitalize } from "lodash";
|
||||
import { IMaskInput } from "react-imask";
|
||||
import PassportImageDropzone from "../../../../components/PassportImageDropzone/PassportImageDropzone.tsx";
|
||||
@@ -11,6 +11,9 @@ import { BaseFormInputProps } from "../../../../../../types/utils.ts";
|
||||
import RoleSelect from "../../../../components/RoleSelect/RoleSelect.tsx";
|
||||
import PositionSelect from "../../../../components/PositionSelect/PositionSelect.tsx";
|
||||
import PayRateSelect from "../../../../../../components/Selects/PayRateSelect/PayRateSelect.tsx";
|
||||
import { useClipboard } from "@mantine/hooks";
|
||||
import { notifications } from "../../../../../../shared/lib/notifications.ts";
|
||||
import { modals } from "@mantine/modals";
|
||||
|
||||
|
||||
type Props = {
|
||||
@@ -23,6 +26,47 @@ const CommonTab = ({
|
||||
formProps,
|
||||
}: Props) => {
|
||||
const isEditing = "element" in formProps;
|
||||
const clipboard = useClipboard();
|
||||
const onCreateInviteCodeClick = async () => {
|
||||
if (!isEditing) return;
|
||||
const {
|
||||
inviteCode,
|
||||
ok,
|
||||
message,
|
||||
} = await UserService.generateInviteCode({ requestBody: { userId: formProps.element.id } });
|
||||
if (!ok || !inviteCode) {
|
||||
notifications.error({ message });
|
||||
return;
|
||||
}
|
||||
modals.openConfirmModal({
|
||||
withCloseButton: false,
|
||||
children: (
|
||||
<Flex gap={rem(10)} direction={"column"} justify={"center"} align={"center"}>
|
||||
|
||||
<Text>
|
||||
Ваш код приглашения!
|
||||
</Text>
|
||||
<Badge variant={"default"} style={{ cursor: "text" }} radius={"sm"} size={"xl"}>{inviteCode}</Badge>
|
||||
<Input.Description>
|
||||
Код действителен в течении 30 минут
|
||||
</Input.Description>
|
||||
</Flex>
|
||||
|
||||
),
|
||||
labels: { confirm: "Скопировать", cancel: "Закрыть" },
|
||||
onConfirm: () => {
|
||||
clipboard.copy(inviteCode);
|
||||
},
|
||||
});
|
||||
};
|
||||
const onGenerateQrClick = () => {
|
||||
if (!isEditing) return;
|
||||
const pdfWindow = window.open(
|
||||
`${import.meta.env.VITE_API_URL}/work-shifts/generate-qr-code/${formProps.element.id}`,
|
||||
);
|
||||
if (!pdfWindow) return;
|
||||
pdfWindow.print();
|
||||
};
|
||||
const initialValues = isEditing
|
||||
? formProps.element
|
||||
: {
|
||||
@@ -189,6 +233,15 @@ const CommonTab = ({
|
||||
/>
|
||||
</Stack>
|
||||
</Fieldset>
|
||||
{isEditing && (
|
||||
<Fieldset pt={rem(20)}>
|
||||
<Flex h={"100%"} justify={"center"} gap={rem(10)} direction={"column"}>
|
||||
<Button onClick={() => onCreateInviteCodeClick()} variant={"default"}>Код
|
||||
приглашения</Button>
|
||||
<Button onClick={() => onGenerateQrClick()} variant={"default"}>QR Код</Button>
|
||||
</Flex>
|
||||
</Fieldset>)
|
||||
}
|
||||
</>
|
||||
</BaseFormModal.Body>
|
||||
</BaseFormModal>
|
||||
|
||||
Reference in New Issue
Block a user