import { useDispatch, useSelector } from "react-redux"; import { closeDialog, dialogSelector, refreshQuota, setDialog, } from "@/store/quota.ts"; import { openDialog as openSubDialog, dialogSelector as subDialogSelector, } from "@/store/subscription.ts"; import { useTranslation } from "react-i18next"; import { useState } from "react"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog.tsx"; import "@/assets/pages/quota.less"; import { Cloud, ExternalLink, Plus } from "lucide-react"; import { Input } from "@/components/ui/input.tsx"; import { testNumberInputEvent } from "@/utils/dom.ts"; import { Button } from "@/components/ui/button.tsx"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTrigger, } from "@/components/ui/alert-dialog.tsx"; import { AlertDialogTitle } from "@radix-ui/react-alert-dialog"; import { buyQuota } from "@/api/addition.ts"; import { useToast } from "@/components/ui/use-toast.ts"; import { useEffectAsync } from "@/utils/hook.ts"; import { selectAuthenticated } from "@/store/auth.ts"; import { ToastAction } from "@/components/ui/toast.tsx"; import { buyLink, deeptrainEndpoint, docsEndpoint, useDeeptrain, } from "@/conf/env.ts"; import { useRedeem } from "@/api/redeem.ts"; import { cn } from "@/components/ui/lib/utils.ts"; import { subscriptionDataSelector } from "@/store/globals.ts"; type AmountComponentProps = { amount: number; active?: boolean; other?: boolean; onClick?: () => void; }; function AmountComponent({ amount, active, other, onClick, }: AmountComponentProps) { const { t } = useTranslation(); return (
{!other ? ( <>
{(amount * 10).toFixed(0)}
{amount.toFixed(2)}
) : (
{t("buy.other")}
)}
); } function QuotaDialog() { const { t } = useTranslation(); const { toast } = useToast(); const [current, setCurrent] = useState(1); const [amount, setAmount] = useState(10); const open = useSelector(dialogSelector); const auth = useSelector(selectAuthenticated); const sub = useSelector(subDialogSelector); const subscriptionData = useSelector(subscriptionDataSelector); const [redeem, setRedeem] = useState(""); const dispatch = useDispatch(); useEffectAsync(async () => { if (!auth) return; const task = setInterval(() => refreshQuota(dispatch), 5000); await refreshQuota(dispatch); return () => clearInterval(task); }, [auth]); return ( dispatch(setDialog(state))} > {t("buy.choose")}
{subscriptionData.length > 0 && (

sub ? dispatch(closeDialog()) : dispatch(openSubDialog()) } > {t("sub.subscription-link")}

)}
{ setCurrent(1); setAmount(10); }} /> { setCurrent(2); setAmount(50); }} /> { setCurrent(3); setAmount(250); }} /> { setCurrent(4); setAmount(500); }} /> { setCurrent(5); setAmount(1000); }} /> setCurrent(6)} />
{current === 6 && (
{ if (testNumberInputEvent(e)) { switch (e.key) { case "ArrowUp": setAmount(amount + 1); break; case "ArrowDown": setAmount(amount - 1); break; } } }} onChange={(e) => { if (e.target.value !== "") { setAmount(parseInt(e.target.value)); if (amount > 99999) { setAmount(99999); } } else { setAmount(0); } }} maxLength={5} />
{(amount / 10).toFixed(2)} CNY
)}
{t("buy.dialog-title")} {t("buy.dialog-desc", { amount })} {t("buy.dialog-cancel")} { if (!useDeeptrain) { window.open( `${buyLink}?quota=${amount}`, "_blank", ); return; } const res = await buyQuota(amount); if (res.status) { toast({ title: t("buy.success"), description: t("buy.success-prompt", { amount, }), }); dispatch(closeDialog()); } else { toast({ title: t("buy.failed"), description: `${t("buy.failed-prompt", { amount, })}\n${res.error}`, action: useDeeptrain ? ( (location.href = `${deeptrainEndpoint}/home/wallet`) } > {t("buy.go")} ) : undefined, }); useDeeptrain && setTimeout(() => { window.open( `${deeptrainEndpoint}/home/wallet`, ); }, 2000); } }} > {t("buy.dialog-buy")}
{useDeeptrain ? (
{t("buy.deeptrain-tip")}
) : (
setRedeem(e.target.value)} />
)}
{buyLink && buyLink.length > 0 && ( )}
); } export default QuotaDialog;