update package

This commit is contained in:
Zhang Minghan 2023-09-07 23:12:43 +08:00
parent f9aac47b67
commit 0d53961c18
7 changed files with 143 additions and 23 deletions

View File

@ -28,7 +28,8 @@ import { Toaster } from "./components/ui/toaster.tsx";
import {login, tokenField} from "./conf.ts";
import { useTranslation } from "react-i18next";
import Quota from "./routes/Quota.tsx";
import {openDialog} from "./store/quota.ts";
import { openDialog as openQuotaDialog } from "./store/quota.ts";
import { openDialog as openPackageDialog } from "./store/package.ts";
import Package from "./routes/Package.tsx";
function Settings() {
@ -49,7 +50,8 @@ function Settings() {
{username}
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => dispatch(openDialog())}>{t("quota")}</DropdownMenuItem>
<DropdownMenuItem onClick={() => dispatch(openQuotaDialog())}>{t("quota")}</DropdownMenuItem>
<DropdownMenuItem onClick={() => dispatch(openPackageDialog())}>{t("pkg.title")}</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<Button

View File

@ -0,0 +1,31 @@
.package-wrapper {
display: flex;
flex-direction: column;
margin: 24px 4px !important;
gap: 18px;
.package {
display: flex;
flex-direction: column;
gap: 8px;
.package-title {
display: flex;
flex-direction: row;
align-items: center;
gap: 4px;
font-size: 16px;
color: hsl(var(--text));
user-select: none;
svg {
transform: translateY(1px);
}
}
.package-content {
font-size: 14px;
color: hsl(var(--text-secondary));
}
}
}

View File

@ -0,0 +1,36 @@
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "./lib/utils"
const badgeVariants = cva(
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
{
variants: {
variant: {
default:
"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
secondary:
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
destructive:
"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
outline: "text-foreground",
},
},
defaultVariants: {
variant: "default",
},
}
)
export interface BadgeProps
extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof badgeVariants> {}
function Badge({ className, variant, ...props }: BadgeProps) {
return (
<div className={cn(badgeVariants({ variant }), className)} {...props} />
)
}
export { Badge, badgeVariants }

View File

@ -26,7 +26,11 @@ export async function buyQuota(
export async function getPackage(): Promise<PackageResponse> {
try {
const resp = await axios.get(`/package`);
return resp.data as PackageResponse;
return {
status: resp.data.status,
cert: resp.data.data.cert,
teenager: resp.data.data.teenager,
}
} catch (e) {
console.debug(e);
return { status: false, cert: false, teenager: false };

View File

@ -77,12 +77,16 @@ const resources = {
},
pkg: {
"title": "Packages",
"go": "Go to",
"verify": "Verify",
"go": "Go to Verify",
"cert": "Certification Package",
"cert-desc": "After real-name certification, you can get 50 points (worth 5 CNY)",
"teen": "Teenager Package",
"teen-desc": "After real-name certification, teenagers (18 years old and below) can get an additional 150 points (worth 15 CNY)",
"close": "Close",
state: {
"true": "Received",
"false": "Not Received",
}
}
},
},
@ -152,13 +156,17 @@ const resources = {
},
pkg: {
"title": "礼包",
"go": "前往",
"verify": "实名认证",
"go": "前往实名认证",
"cert": "实名认证礼包",
"cert-desc": "实名认证后可获得 50 点数 (价值 5 元)",
"teen": "未成年人福利",
"teen-desc": "实名认证后未成年人18 周岁及以下)可额外获得 150 点数 (价值 15 元)",
}
"close": "关闭",
state: {
"true": "已领取",
"false": "无法领取",
}
},
},
},
};

View File

@ -10,28 +10,64 @@ import {Button} from "../components/ui/button.tsx";
import "../assets/package.less";
import {useTranslation} from "react-i18next";
import {useDispatch, useSelector} from "react-redux";
import {dialogSelector, refreshPackage} from "../store/package.ts";
import {
certSelector,
closeDialog,
dialogSelector,
refreshPackageTask,
setDialog,
teenagerSelector
} from "../store/package.ts";
import {useEffect} from "react";
import {Gift} from "lucide-react";
import {Separator} from "../components/ui/separator.tsx";
import {Badge} from "../components/ui/badge.tsx";
function Package() {
const { t } = useTranslation();
const dispatch = useDispatch();
const open = useSelector(dialogSelector);
const cert = useSelector(certSelector);
const teenager = useSelector(teenagerSelector);
useEffect(() => {
refreshPackage(dispatch);
refreshPackageTask(dispatch);
}, []);
return (
<Dialog>
<Dialog open={open} onOpenChange={
(open) => dispatch(setDialog(open))
}>
<DialogContent>
<DialogHeader>
<DialogTitle>Edit profile</DialogTitle>
<DialogDescription>
Make changes to your profile here. Click save when you're done.
<DialogTitle>{ t('pkg.title') }</DialogTitle>
<DialogDescription asChild>
<div className={`package-wrapper`}>
<div className={`package`}>
<div className={`package-title`}>
<Gift className={`h-4 w-4`} />
{ t('pkg.cert') }
<Badge variant={cert ? 'default' : 'outline'}>{ t(`pkg.state.${Boolean(cert)}`) }</Badge>
</div>
<div className={`package-content`}>{ t('pkg.cert-desc') }</div>
</div>
<Separator orientation={`horizontal`} />
<div className={`package`}>
<div className={`package-title`}>
<Gift className={`h-4 w-4`} />
{ t('pkg.teen') }
<Badge variant={teenager ? 'default' : 'outline'}>{ t(`pkg.state.${Boolean(teenager)}`) }</Badge>
</div>
<div className={`package-content`}>{ t('pkg.teen-desc') }</div>
</div>
</div>
</DialogDescription>
</DialogHeader>
<DialogFooter>
<Button>Save changes</Button>
<Button variant={`outline`} onClick={() => dispatch(closeDialog())}>{ t('pkg.close') }</Button>
<Button variant={`default`} onClick={
() => window.open("https://deeptrain.lightxi.com/home/package")
}>{ t('pkg.go') }</Button>
</DialogFooter>
</DialogContent>
</Dialog>

View File

@ -35,13 +35,16 @@ export const dialogSelector = (state: any): boolean => state.package.dialog;
export const certSelector = (state: any): boolean => state.package.cert;
export const teenagerSelector = (state: any): boolean => state.package.teenager;
export const refreshPackage = (dispatch: any) => {
setInterval(async () => {
const current = new Date().getTime(); //@ts-ignore
if (window.hasOwnProperty("package") && (current - window.package < 2500)) return; //@ts-ignore
window.package = current;
const refreshPackage = async (dispatch: any) => {
const current = new Date().getTime(); //@ts-ignore
if (window.hasOwnProperty("package") && (current - window.package < 2500)) return; //@ts-ignore
window.package = current;
const response = await getPackage();
if (response.status) dispatch(refreshState(response));
}, 10000);
const response = await getPackage();
if (response.status) dispatch(refreshState(response));
}
export const refreshPackageTask = (dispatch: any) => {
setInterval(() => refreshPackage(dispatch), 5000);
refreshPackage(dispatch).then();
}