Browse Source

证书相关UI完成

main
lk 3 months ago
parent
commit
41a1f17d6a
  1. 134
      src/pages/websites/cert/apply.tsx

134
src/pages/websites/cert/apply.tsx

@ -7,8 +7,8 @@ import {
dnsVerifyOKAtom, dnsVerifyOKAtom,
saveOrUpdateCertAtom, saveOrUpdateCertAtom,
} from "@/store/websites/cert.ts"; } from "@/store/websites/cert.ts";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Button, Flex, Form, Input, Progress, Select, Space, Table, Tooltip } from "antd";
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import {Button, Flex, Form, Input, message, Progress, Radio, Select, Space, Steps, Table, Tooltip} from "antd";
import google from "@/pages/websites/cert/assets/google.png"; import google from "@/pages/websites/cert/assets/google.png";
import zerossl from "@/pages/websites/cert/assets/zerossl.png"; import zerossl from "@/pages/websites/cert/assets/zerossl.png";
import lets_encrypt from "@/pages/websites/cert/assets/lets_encrypt.png"; import lets_encrypt from "@/pages/websites/cert/assets/lets_encrypt.png";
@ -17,7 +17,7 @@ import ListPageLayout from "@/layout/ListPageLayout.tsx";
import { ColumnsType } from "antd/es/table"; import { ColumnsType } from "antd/es/table";
import { atomWithStorage } from "jotai/utils"; import { atomWithStorage } from "jotai/utils";
import Copy from "@/components/copy"; import Copy from "@/components/copy";
import { InfoCircleOutlined, LoadingOutlined } from "@ant-design/icons";
import { CopyOutlined, InfoCircleOutlined, LoadingOutlined } from "@ant-design/icons";
const i18nPrefix = "cert.apply"; const i18nPrefix = "cert.apply";
@ -40,7 +40,7 @@ const BrandSelect = (props: any) => {
vertical={true} vertical={true}
onClick={() => onChange("Google")} onClick={() => onChange("Google")}
className={cx("band-normal", { className={cx("band-normal", {
"band-active": value === "Google",
"band-active": value === "Google" || !props.value,
})} })}
> >
<img src={google} style={{ height: "2rem" }} /> <img src={google} style={{ height: "2rem" }} />
@ -85,6 +85,14 @@ const StatusTable = (props: { value: string }) => {
const timerRef = useRef<number>(); const timerRef = useRef<number>();
const handleCopy = (str:string) => {
navigator.clipboard.writeText(str).then(() => {
message.info('复制成功!');
}).catch(err => {
message.info(err);
});
};
const columns = useMemo<ColumnsType>(() => { const columns = useMemo<ColumnsType>(() => {
return [ return [
{ {
@ -127,9 +135,9 @@ const StatusTable = (props: { value: string }) => {
width: 150, width: 150,
render(text) { render(text) {
if (text) { if (text) {
return <span className={"color-green1"}>{text}</span>;
return <span className={"color-yellow"}>{text}</span>;
} }
return <span className={"color-yellow"}></span>;
return <span className={"color-red"}></span>;
}, },
}, },
{ {
@ -137,6 +145,13 @@ const StatusTable = (props: { value: string }) => {
title: t(`${i18nPrefix}.status.columns.domain`, "域名"), title: t(`${i18nPrefix}.status.columns.domain`, "域名"),
dataIndex: "dns_name", dataIndex: "dns_name",
width: 200, width: 200,
render(text) {
return (
<Button size="small" type="text" className={"color-green1"} icon={<CopyOutlined />} iconPosition={"end"} onClick={() => handleCopy(text)}>
{text}
</Button>
);
},
}, },
{ {
//主机记录 //主机记录
@ -162,7 +177,11 @@ const StatusTable = (props: { value: string }) => {
dataIndex: "record_value", dataIndex: "record_value",
width: 200, width: 200,
render: (text) => { render: (text) => {
return <Copy {...{ text: text, tooltips: t(`actions.clickCopy`) }} />;
return (
<Button size="small" type="text" className={"color-green1"} icon={<CopyOutlined />} iconPosition={"end"} onClick={() => handleCopy(text)}>
{t(`actions.clickCopy`)}
</Button>
);
}, },
}, },
] as ColumnsType; ] as ColumnsType;
@ -178,7 +197,7 @@ const StatusTable = (props: { value: string }) => {
dns_name: "example.com", dns_name: "example.com",
host: "example", host: "example",
type: "A", type: "A",
record_value: "192.168.1.1"
record_value: "192.168.1.1",
}, },
{ {
status: 3, status: 3,
@ -186,9 +205,9 @@ const StatusTable = (props: { value: string }) => {
dns_name: "another.com", dns_name: "another.com",
host: "another", host: "another",
type: "CNAME", type: "CNAME",
record_value: "cname.another.com"
}
]
record_value: "cname.another.com",
},
],
}; };
setData(mockData); setData(mockData);
@ -238,6 +257,44 @@ const StatusTable = (props: { value: string }) => {
); );
}; };
const DomainsInput = (props: { setDomains; currentDomainMod; setCurrentDomainMod; currentStep }) => {
return (
<Space direction="vertical" style={{ width: "100%" }}>
<Radio.Group
style={{ marginBottom: 8 }}
value={props.currentDomainMod}
onChange={(e) => props.setCurrentDomainMod(e.target.value)}
>
<Radio.Button value="single" disabled={props.currentStep !== 0}>
</Radio.Button>
<Radio.Button value="multiple" disabled={props.currentStep !== 0}>
</Radio.Button>
</Radio.Group>
{props.currentDomainMod === "single" && (
<Input
disabled={props.currentStep !== 0}
placeholder="请输入域名,支持泛解析域名。如果为多个域名注册到一个证书,域名之间用<逗号(英文输入)>分割。如:a.com,*.b.com"
/>
)}
{props.currentDomainMod === "multiple" && (
<Input.TextArea
disabled={props.currentStep !== 0}
rows={6}
placeholder={`多个域名多个证书申请,用回车分隔。以下示例为6个域名申请3个证书,每行对应一个证书,支持泛解析域名;如:
*.a.baidu.com, *.baidu.com
hello.alibaba.com,b.com,*.c.com
sss.ddd.com`}
onBlur={(e) => {
props.setDomains(e.target.value);
}}
/>
)}
</Space>
);
};
const domainsAtom = atomWithStorage<string>("domains", ""); const domainsAtom = atomWithStorage<string>("domains", "");
const Apply = () => { const Apply = () => {
@ -245,6 +302,8 @@ const Apply = () => {
const [form] = Form.useForm(); const [form] = Form.useForm();
const { mutate: saveOrUpdate, isPending: isSubmitting } = useAtomValue(saveOrUpdateCertAtom); const { mutate: saveOrUpdate, isPending: isSubmitting } = useAtomValue(saveOrUpdateCertAtom);
const [domains, setDomains] = useAtom(domainsAtom); const [domains, setDomains] = useAtom(domainsAtom);
const [currentStep, setCurrentStep] = useState(0);
const [currentDomainMod, setCurrentDomainMod] = useState<"single" | "multiple">("single");
const dnsVerifyOK = useAtomValue(dnsVerifyOKAtom); const dnsVerifyOK = useAtomValue(dnsVerifyOKAtom);
useEffect(() => { useEffect(() => {
@ -261,6 +320,23 @@ const Apply = () => {
className={styles.applyContainer} className={styles.applyContainer}
title={t(`${i18nPrefix}.apply.title`, "证书申请")} title={t(`${i18nPrefix}.apply.title`, "证书申请")}
> >
<div style={{ padding: "50px 50px 0 50px" }}>
<Steps
size="small"
current={currentStep}
items={[
{
title: "填写域名",
},
{
title: "等待检测",
},
{
title: "提交申请",
},
]}
/>
</div>
<Form <Form
form={form} form={form}
{...{ {...{
@ -296,23 +372,22 @@ const Apply = () => {
label={t(`${i18nPrefix}.columns.domains`, "域名")} label={t(`${i18nPrefix}.columns.domains`, "域名")}
rules={[{ required: true, message: t(`${i18nPrefix}.columns.domains.required`, "请输入域名") }]} rules={[{ required: true, message: t(`${i18nPrefix}.columns.domains.required`, "请输入域名") }]}
> >
<Input.TextArea
rows={5}
placeholder={`请输入域名,每行一个,支持泛解析域名;如:
*.google.com
*.a.baidu.com
hello.alibaba.com`}
onBlur={(e) => {
setDomains(e.target.value);
}}
<DomainsInput
currentDomainMod={currentDomainMod}
setCurrentDomainMod={setCurrentDomainMod}
setDomains={setDomains}
currentStep={currentStep}
/> />
</Form.Item> </Form.Item>
{currentStep !== 0 && (
<>
<Form.Item <Form.Item
label={t(`${i18nPrefix}.columns.type`, "域名验证")} label={t(`${i18nPrefix}.columns.type`, "域名验证")}
rules={[{ required: true, message: t(`${i18nPrefix}.columns.type`, "域名验证没有通过") }]} rules={[{ required: true, message: t(`${i18nPrefix}.columns.type`, "域名验证没有通过") }]}
> >
<StatusTable value={domains} /> <StatusTable value={domains} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
name={"brand"} name={"brand"}
label={t(`${i18nPrefix}.columns.brand`, "证书品牌")} label={t(`${i18nPrefix}.columns.brand`, "证书品牌")}
@ -323,7 +398,7 @@ const Apply = () => {
}, },
]} ]}
> >
<BrandSelect />
<BrandSelect value="Google" />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
name={"algorithm"} name={"algorithm"}
@ -340,14 +415,27 @@ const Apply = () => {
<Form.Item name={"remark"} label={t(`${i18nPrefix}.columns.remark`, "备注 ")}> <Form.Item name={"remark"} label={t(`${i18nPrefix}.columns.remark`, "备注 ")}>
<Input style={{ width: 400 }} /> <Input style={{ width: 400 }} />
</Form.Item> </Form.Item>
</>
)}
<Form.Item label={" "} colon={false}> <Form.Item label={" "} colon={false}>
<Space> <Space>
<Button disabled={!dnsVerifyOK || isSubmitting} htmlType={"submit"}>
{currentStep !== 0 && (
<Button type="primary" onClick={() => setCurrentStep(currentStep - 1)} htmlType={"submit"}>
{t(`${i18nPrefix}.apply.prev`, "上一步")} {t(`${i18nPrefix}.apply.prev`, "上一步")}
</Button> </Button>
<Button type={"primary"} disabled={!dnsVerifyOK || isSubmitting} htmlType={"submit"}>
)}
{currentStep === 0 && (
<Button type="primary" onClick={() => setCurrentStep(currentStep + 1)} htmlType={"submit"}>
{t(`${i18nPrefix}.apply.next`, "下一步")}
</Button>
)}
{currentStep !== 0 && (
<Button type="primary" htmlType={"submit"} disabled={currentStep === 1}>
{t(`${i18nPrefix}.apply.submit`, "提交申请")} {t(`${i18nPrefix}.apply.submit`, "提交申请")}
</Button> </Button>
)}
</Space> </Space>
</Form.Item> </Form.Item>
</Form> </Form>

Loading…
Cancel
Save