jetbrains-license-server/license_ui/src/components/LicenseForm.tsx
2024-04-05 20:31:37 +08:00

105 lines
3.6 KiB
TypeScript

import { licenseValidLength } from "@/constants";
import { useLicenseCodeStore } from "@/hooks/use_license_code_store";
import { useProductsStore } from "@/hooks/use_products_store";
import type { LicenseInfoForm } from "@/types";
import { Button, Flex, Group, Paper, Select, TextInput, Title } from "@mantine/core";
import { useForm } from "@mantine/form";
import { notifications } from "@mantine/notifications";
import { IconAt, IconCalendar, IconTag, IconUser } from "@tabler/icons-react";
import dayjs from "dayjs";
import { find, isEmpty, pluck, prop, propEq } from "ramda";
import { useCallback } from "react";
export function LicenseForm() {
const form = useForm<LicenseInfoForm>({
initialValues: {
licenseName: "",
assigneeName: "",
assigneeEmail: "",
validLength: licenseValidLength[0].label,
},
validate: {
licenseName: (value) => (isEmpty(value) ? "授权名称不能为空" : null),
assigneeName: (value) => (isEmpty(value) ? "被授权人不能为空" : null),
},
});
const selectedProducts = useProductsStore((state) => state.selectedProducts);
const updateLicenseCode = useLicenseCodeStore((state) => state.setLicenseCode);
const licenseGenAction = useCallback(
async (formValue: LicenseInfoForm) => {
const license = await generateLicense(formValue, selectedProducts);
updateLicenseCode(license);
},
[selectedProducts, updateLicenseCode]
);
return (
<Paper shadow="md" p="lg">
<form onSubmit={form.onSubmit(licenseGenAction)}>
<Flex direction="column" gap="md">
<Title order={4}></Title>
<TextInput
label="授权名称"
placeholder="请输入授权名称"
withAsterisk
leftSection={<IconTag size={16} />}
{...form.getInputProps("licenseName")}
/>
<TextInput
label="被授权人"
placeholder="请输入授权人名称"
withAsterisk
leftSection={<IconUser size={16} />}
{...form.getInputProps("assigneeName")}
/>
<TextInput
label="被授权人Email"
placeholder="请输入授权人Email"
leftSection={<IconAt size={16} />}
{...form.getInputProps("assigneeEmail")}
/>
<Select
label="授权有效时长"
placeholder="请选择授权有效时长"
data={pluck("label", licenseValidLength)}
leftSection={<IconCalendar size={16} />}
{...form.getInputProps("validLength")}
/>
<Group justify="flex-end">
<Button type="submit"></Button>
</Group>
</Flex>
</form>
</Paper>
);
}
async function generateLicense(form: LicenseInfoForm, selectedProducts: string[]) {
const validYears = find(propEq(form.validLength, "label"), licenseValidLength)?.value ?? 0;
const now = dayjs();
const validDays = now.add(validYears, "year").diff(now, "day");
if (isEmpty(selectedProducts)) {
notifications.show({
title: "至少需要选择一个产品",
color: "red",
});
return "";
}
const requestBody = {
licenseeName: form.licenseName,
assigneeName: form.assigneeName,
assigneeEmail: form.assigneeEmail,
validDays,
requestProducts: selectedProducts,
};
const response = await fetch("/api/license", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(requestBody),
});
const data = await response.json();
return prop<"license", { license: string }>("license", data);
}