From 1f9b7ea1db2200842c625882d0dbdc92198d6f54 Mon Sep 17 00:00:00 2001 From: EUForest Date: Fri, 6 Feb 2026 23:59:31 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20add=20redemption=20code=20f?= =?UTF-8?q?eature=20to=20user=20dashboard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add redemption code input component in dashboard - Integrate redemption API endpoint - Add i18n support for Chinese and English - Display redemption section alongside subscriptions --- .../assets/locales/en-US/dashboard.json | 10 ++- .../assets/locales/zh-CN/dashboard.json | 10 ++- .../src/sections/user/dashboard/content.tsx | 2 + .../sections/user/dashboard/redeem-code.tsx | 85 +++++++++++++++++++ packages/ui/src/services/user/user.ts | 18 ++++ 5 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 apps/user/src/sections/user/dashboard/redeem-code.tsx diff --git a/apps/user/public/assets/locales/en-US/dashboard.json b/apps/user/public/assets/locales/en-US/dashboard.json index 8ca073d..bbc8be3 100644 --- a/apps/user/public/assets/locales/en-US/dashboard.json +++ b/apps/user/public/assets/locales/en-US/dashboard.json @@ -31,5 +31,13 @@ "subscriptionUrl": "Subscription URL", "totalTraffic": "Total Traffic", "unknown": "Unknown", - "used": "Used" + "used": "Used", + "redeemCode": "Redeem Code", + "redeemCodeTitle": "Redeem Code", + "redeemCodeDescription": "Enter redemption code to get subscription plan", + "enterRedemptionCode": "Please enter redemption code", + "redeemButton": "Redeem Now", + "redeeming": "Redeeming...", + "redeemSuccess": "Redemption successful! Subscription has been activated.", + "redeemFailed": "Redemption failed" } diff --git a/apps/user/public/assets/locales/zh-CN/dashboard.json b/apps/user/public/assets/locales/zh-CN/dashboard.json index 5e573b2..2eb4e5a 100644 --- a/apps/user/public/assets/locales/zh-CN/dashboard.json +++ b/apps/user/public/assets/locales/zh-CN/dashboard.json @@ -31,5 +31,13 @@ "subscriptionUrl": "订阅链接", "totalTraffic": "总流量", "unknown": "未知", - "used": "已使用" + "used": "已使用", + "redeemCode": "兑换 CDK", + "redeemCodeTitle": "CDK 兑换", + "redeemCodeDescription": "输入兑换码以获取订阅套餐", + "enterRedemptionCode": "请输入兑换码", + "redeemButton": "立即兑换", + "redeeming": "兑换中...", + "redeemSuccess": "兑换成功!", + "redeemFailed": "兑换失败" } diff --git a/apps/user/src/sections/user/dashboard/content.tsx b/apps/user/src/sections/user/dashboard/content.tsx index db0b531..09ef784 100644 --- a/apps/user/src/sections/user/dashboard/content.tsx +++ b/apps/user/src/sections/user/dashboard/content.tsx @@ -47,6 +47,7 @@ import Subscribe from "../../subscribe"; import Renewal from "../../subscribe/renewal"; import ResetTraffic from "../../subscribe/reset-traffic"; import Unsubscribe from "../../subscribe/unsubscribe"; +import RedeemCode from "./redeem-code"; const platforms: (keyof API.DownloadLink)[] = [ "windows", @@ -164,6 +165,7 @@ export default function Content() { +
{availablePlatforms.length > 0 && ( void; +} + +export default function RedeemCode({ onSuccess }: RedeemCodeProps) { + const { t } = useTranslation("dashboard"); + const [code, setCode] = useState(""); + + const redeemMutation = useMutation({ + mutationFn: (code: string) => redeemCode({ code }), + onSuccess: (response) => { + toast.success(response.data.message || t("redeemSuccess", "兑换成功")); + setCode(""); + onSuccess?.(); + }, + onError: (error: any) => { + const errorMessage = + error?.response?.data?.message || t("redeemFailed", "兑换失败"); + toast.error(errorMessage); + }, + }); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (!code.trim()) { + toast.error(t("pleaseEnterCode", "请输入兑换码")); + return; + } + redeemMutation.mutate(code.trim()); + }; + + return ( + + + {t("redeemCode", "CDK 兑换")} + + {t("redeemCodeDescription", "输入兑换码即可兑换对应的订阅套餐")} + + + +
+
+ +
+ setCode(e.target.value)} + placeholder={t( + "enterRedemptionCode", + "请输入兑换码" + )} + value={code} + /> + +
+
+
+
+
+ ); +} diff --git a/packages/ui/src/services/user/user.ts b/packages/ui/src/services/user/user.ts index d7a25ca..f931d99 100644 --- a/packages/ui/src/services/user/user.ts +++ b/packages/ui/src/services/user/user.ts @@ -268,6 +268,24 @@ export async function updateUserRules( ); } +/** Redeem Code POST /v1/public/redemption/ */ +export async function redeemCode( + body: { code: string }, + options?: { [key: string]: any } +) { + return request( + `${import.meta.env.VITE_API_PREFIX || ""}/v1/public/redemption/`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + data: body, + ...(options || {}), + } + ); +} + /** Query User Subscribe GET /v1/public/user/subscribe */ export async function queryUserSubscribe(options?: { [key: string]: any }) { return request(