feat: update license manually
This commit is contained in:
@@ -5,6 +5,7 @@ import useLicense from "../../../common/hook/useLicense";
|
||||
import LicensePriceListModal from "./LicensePriceListModal";
|
||||
import clsx from "clsx";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import UpdateLicenseModal from "./UpdateLicenseModal";
|
||||
|
||||
interface ItemProps extends HTMLAttributes<HTMLSpanElement> { label: string, data?: string | number | string[], foldable?: boolean }
|
||||
const Item = ({ label, data, foldable = false, ...rest }: ItemProps) => {
|
||||
@@ -24,18 +25,20 @@ const Item = ({ label, data, foldable = false, ...rest }: ItemProps) => {
|
||||
};
|
||||
export default function License() {
|
||||
const { t } = useTranslation("setting");
|
||||
const { license: licenseInfo, reachLimit } = useLicense();
|
||||
const { license: licenseInfo, reachLimit, upsertLicense, upserting, upserted } = useLicense();
|
||||
const [modalVisible, setModalVisible] = useState(false);
|
||||
const [updateVisible, setUpdateVisible] = useState(false);
|
||||
const [base58Fold, setBase58Fold] = useState(true);
|
||||
const handleRenewLicense = () => {
|
||||
toggleModalVisible();
|
||||
};
|
||||
const toggleModalVisible = () => {
|
||||
setModalVisible((prev) => !prev);
|
||||
};
|
||||
const toggleUpdateModalVisible = () => {
|
||||
setUpdateVisible((prev) => !prev);
|
||||
};
|
||||
const handleLicenseValueToggle = () => {
|
||||
setBase58Fold(pre => !pre);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="max-w-3xl flex flex-col justify-start items-start gap-4">
|
||||
@@ -48,7 +51,10 @@ export default function License() {
|
||||
<Item label={t("license.value")} data={licenseInfo?.base58} foldable={base58Fold} title={base58Fold ? "Click to see full text" : "Click to fold text"}
|
||||
onClick={handleLicenseValueToggle} />
|
||||
</div>
|
||||
<Button onClick={handleRenewLicense}>{t("license.renew")}</Button>
|
||||
<div className="flex gap-2">
|
||||
<Button onClick={toggleModalVisible}>{t("license.renew")}</Button>
|
||||
<Button onClick={toggleUpdateModalVisible} className="ghost">{t("license.update")}</Button>
|
||||
</div>
|
||||
<div className="flex flex-col gap-4 bg-primary-500 text-white rounded drop-shadow-xl p-5">
|
||||
<h2 className="text-2xl font-bold">{t("license.tip.title")} 🎁</h2>
|
||||
<p className="text-base flex flex-col"><span>
|
||||
@@ -58,7 +64,7 @@ export default function License() {
|
||||
{t("license.tip.booking")} <a className="underline text-lg text-green-200" href="https://calendly.com/hansu/han-meeting" target="_blank" rel="noopener noreferrer">https://calendly.com/hansu/han-meeting</a>
|
||||
</span>
|
||||
<span>
|
||||
{t("license.tip.wechat")}<em className="text-lg text-green-200">yanggc_2013</em>
|
||||
{t("license.tip.wechat")}<em className="text-lg text-green-200">Privoce</em>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
@@ -68,6 +74,14 @@ export default function License() {
|
||||
closeModal={toggleModalVisible}
|
||||
/>
|
||||
)}
|
||||
{updateVisible && (
|
||||
<UpdateLicenseModal
|
||||
updated={upserted}
|
||||
updating={upserting}
|
||||
updateLicense={upsertLicense}
|
||||
closeModal={toggleUpdateModalVisible}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@ interface Props {
|
||||
}
|
||||
|
||||
const LicensePriceListModal: FC<Props> = ({ closeModal }) => {
|
||||
const { t } = useTranslation(["setting", "common"]);
|
||||
const { t } = useTranslation("setting");
|
||||
const { t: ct } = useTranslation();
|
||||
const [getUrl, { isLoading, isSuccess }] = useGetLicensePaymentUrlMutation();
|
||||
const [selectPrice, setSelectPrice] = useState(
|
||||
`${LicensePriceList[0].pid}|${LicensePriceList[0].limit}`
|
||||
@@ -53,9 +54,9 @@ const LicensePriceListModal: FC<Props> = ({ closeModal }) => {
|
||||
buttons={
|
||||
<>
|
||||
<Button onClick={closeModal} className="ghost">
|
||||
{t("action.cancel", { ns: "common" })}
|
||||
{ct("action.cancel")}
|
||||
</Button>
|
||||
<Button disabled={isLoading || isSuccess} onClick={handleRenew} className="danger">
|
||||
<Button disabled={isLoading || isSuccess} onClick={handleRenew} >
|
||||
{isLoading ? "Initialize Payment Url" : isSuccess ? "Redirecting" : t("license.renew")}
|
||||
</Button>
|
||||
</>
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { ChangeEvent, FC, useState, useEffect } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import Modal from "../../../common/component/Modal";
|
||||
import StyledModal from "../../../common/component/styled/Modal";
|
||||
import Button from "../../../common/component/styled/Button";
|
||||
import Textarea from "../../../common/component/styled/Textarea";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
interface Props {
|
||||
closeModal: () => void;
|
||||
updateLicense: (param: string) => void;
|
||||
updated: boolean;
|
||||
updating: boolean
|
||||
// domain: string;
|
||||
}
|
||||
|
||||
const UpdateLicenseModal: FC<Props> = ({ closeModal, updateLicense, updating, updated }) => {
|
||||
const [value, setValue] = useState("");
|
||||
const { t } = useTranslation("setting");
|
||||
const { t: ct } = useTranslation();
|
||||
|
||||
const handleRenew = () => {
|
||||
updateLicense(value);
|
||||
|
||||
};
|
||||
const handleLicenseUpdate = (evt: ChangeEvent<HTMLTextAreaElement>) => {
|
||||
setValue(evt.target.value);
|
||||
};
|
||||
useEffect(() => {
|
||||
if (updated) {
|
||||
toast.success("Update Successfully!");
|
||||
closeModal();
|
||||
}
|
||||
}, [updated]);
|
||||
|
||||
return (
|
||||
<Modal id="modal-modal">
|
||||
<StyledModal
|
||||
buttons={
|
||||
<>
|
||||
<Button onClick={closeModal} className="ghost">
|
||||
{ct("action.cancel")}
|
||||
</Button>
|
||||
<Button disabled={updating || updated || !value} onClick={handleRenew} >
|
||||
{updating ? "Updating" : updated ? "Update Successfully" : t("license.update")}
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Textarea rows={18} placeholder={t("license.update_placeholder")} value={value} onChange={handleLicenseUpdate} />
|
||||
</StyledModal>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default UpdateLicenseModal;
|
||||
@@ -29,7 +29,7 @@ export default function Widget() {
|
||||
{t('code')}:
|
||||
</label>
|
||||
<SyntaxHighlighter id="code" language="html" style={vscDarkPlus} className="rounded">
|
||||
{`<!-- ${t('code_comment')} -->\n<script \n data-host-id="4" \n data-close-width="48" \n data-close-height="48" \n data-open-width="380" \n data-open-height="680" \n src="${location.origin}/widget.js" \n async \n/>`}
|
||||
{`<!-- ${t('code_comment')} -->\n<script \n data-host-id="1" \n data-close-width="48" \n data-close-height="48" \n data-open-width="380" \n data-open-height="680" \n src="${location.origin}/widget.js" \n async \n/>`}
|
||||
</SyntaxHighlighter>
|
||||
<div className="text-gray-500 text-sm mt-5 mb-2">
|
||||
{t('config')}:
|
||||
@@ -47,23 +47,23 @@ export default function Widget() {
|
||||
{[{
|
||||
paramKey: "host-id",
|
||||
paramDefault: 1,
|
||||
remarks: "Assign the user chatting with visitor"
|
||||
remarks: t("param_host")
|
||||
}, {
|
||||
paramKey: "close-width",
|
||||
paramDefault: `48(px)`,
|
||||
remarks: "The width while widget closed"
|
||||
remarks: t("param_open_width")
|
||||
}, {
|
||||
paramKey: "close-height",
|
||||
paramDefault: `48(px)`,
|
||||
remarks: "The height while widget closed"
|
||||
remarks: t("param_close_height")
|
||||
}, {
|
||||
paramKey: "open-width",
|
||||
paramDefault: `380(px)`,
|
||||
remarks: "The width while widget opened"
|
||||
remarks: t("param_open_width")
|
||||
}, {
|
||||
paramKey: "open-height",
|
||||
paramDefault: `680(px)`,
|
||||
remarks: "The height while widget opened"
|
||||
remarks: t("param_open_height")
|
||||
}
|
||||
].map(row => <Row key={row.paramKey} {...row} />)}
|
||||
</tbody>
|
||||
|
||||
@@ -78,7 +78,7 @@ const navs = [
|
||||
},
|
||||
{
|
||||
name: "feedback",
|
||||
component: "Email: han@privoce.com\nWechat: yanggc_2013"
|
||||
component: "Email: han@privoce.com Wechat: Privoce"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user