From b61a2ab07b1f10c75d2506bba71b3cbf2e3eb23f Mon Sep 17 00:00:00 2001 From: kang Date: Fri, 22 May 2026 14:34:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E5=A4=A7=E5=8E=85=20?= =?UTF-8?q?Jackpot=20=E5=8F=82=E4=B8=8E=E6=8F=90=E7=A4=BA=E4=B8=8E?= =?UTF-8?q?=E7=8E=A9=E5=AE=B6=E9=A1=B5=E5=A4=B4=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/layout/player-panel.tsx | 6 +- src/features/hall/hall-bet-preview-dialog.tsx | 12 ++++ src/features/hall/hall-bet-result-dialog.tsx | 9 +++ src/features/hall/hall-betting-grid.tsx | 63 ++++++++++--------- src/i18n/locales/en/player.json | 16 +++++ src/i18n/locales/ne/player.json | 16 +++++ src/i18n/locales/zh/player.json | 16 +++++ 7 files changed, 104 insertions(+), 34 deletions(-) diff --git a/src/components/layout/player-panel.tsx b/src/components/layout/player-panel.tsx index 426b87f..1998b2e 100644 --- a/src/components/layout/player-panel.tsx +++ b/src/components/layout/player-panel.tsx @@ -39,12 +39,12 @@ export function PlayerPanel({
-
+
void; @@ -107,6 +108,7 @@ export function HallBetPreviewDialog({ currencyCode, data, placing, + jackpotEnabled = false, allowSubmit = true, onConfirmPlace, }: HallBetPreviewDialogProps) { @@ -188,6 +190,16 @@ export function HallBetPreviewDialog({
+ {jackpotEnabled ? ( + + + {t("hall.jackpotParticipation.title")} + + {t("hall.jackpotParticipation.previewDescription")} + + + ) : null} +
diff --git a/src/features/hall/hall-bet-result-dialog.tsx b/src/features/hall/hall-bet-result-dialog.tsx index 441fd43..7929eaf 100644 --- a/src/features/hall/hall-bet-result-dialog.tsx +++ b/src/features/hall/hall-bet-result-dialog.tsx @@ -21,6 +21,7 @@ type HallBetResultDialogProps = { onOpenChange: (open: boolean) => void; currencyCode: string; data: TicketPlaceData | null; + jackpotEnabled?: boolean; }; export function HallBetResultDialog({ @@ -28,6 +29,7 @@ export function HallBetResultDialog({ onOpenChange, currencyCode, data, + jackpotEnabled = false, }: HallBetResultDialogProps) { const { t } = useTranslation("player"); @@ -119,6 +121,13 @@ export function HallBetResultDialog({

+ {jackpotEnabled ? ( +
+

{t("hall.jackpotParticipation.title")}

+

{t("hall.jackpotParticipation.resultDescription")}

+
+ ) : null} +

{t("hall.result.items")} diff --git a/src/features/hall/hall-betting-grid.tsx b/src/features/hall/hall-betting-grid.tsx index 0548734..ef5e736 100644 --- a/src/features/hall/hall-betting-grid.tsx +++ b/src/features/hall/hall-betting-grid.tsx @@ -84,7 +84,6 @@ const categoryTabs: { value: HallCategory; label: string }[] = [ { value: "D2", label: "2D" }, { value: "D3", label: "3D" }, { value: "D4", label: "4D" }, - { value: "JACKPOT", label: "Jackpot" }, ]; const D2_PLAY_ORDER = ["pos_2a", "pos_2b", "pos_2c", "pos_2abc"] as const; @@ -496,8 +495,25 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } const currentQuickFill = quickFillState[activeCategory] ?? { favorites: [], history: [] }; const favorites = currentQuickFill.favorites; const historyNumbers = currentQuickFill.history; + const jackpotPanelCopy = !jackpot?.enabled + ? { + title: t("hall.jackpotPanel.disabledTitle"), + subtitle: t("hall.jackpotPanel.disabledSubtitle"), + description: t("hall.jackpotPanel.disabledDescription"), + } + : isBettable + ? { + title: t("hall.jackpotPanel.infoTitle"), + subtitle: t("hall.jackpotPanel.infoSubtitle"), + description: t("hall.jackpotPanel.infoDescription"), + } + : { + title: t("hall.jackpotPanel.closedInfoTitle"), + subtitle: t("hall.jackpotPanel.closedInfoSubtitle"), + description: t("hall.jackpotPanel.closedInfoDescription"), + }; - const tableDisabled = activeCategory === "JACKPOT" || !isBettable || catalogState.kind !== "ok"; + const tableDisabled = !isBettable || catalogState.kind !== "ok"; const sealedBetUi = Boolean(display && isHallSealedCountdownUi(display.status)); const numberPlaceholder = activeCategory === "D2" ? "00" : activeCategory === "D3" ? "000" : "0000"; @@ -888,7 +904,7 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } <>

-
+
{categoryTabs.map((tab) => { const active = activeCategory === tab.value; return ( @@ -941,33 +957,18 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot }
) : null} - {activeCategory === "JACKPOT" ? ( -
-
- +
+
+
+

+ {t("hall.quickFill.title")} +

+

+ {t("hall.quickFill.description")} +

-

- {t("hall.closed.title")} -

-

{t("hall.closed.subtitle")}

-
- {t("hall.closed.description")} -
-
- ) : ( - <> -
-
-
-

- {t("hall.quickFill.title")} -

-

- {t("hall.quickFill.description")} -

-
-
- {activeRow?.number ? ( +
+ {activeRow?.number ? (
= debouncedSummary.actual} onConfirmPlace={() => void handlePlace()} /> @@ -1300,6 +1300,7 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } }} currencyCode={currencyCode} data={resultData} + jackpotEnabled={Boolean(jackpot?.enabled)} /> ); diff --git a/src/i18n/locales/en/player.json b/src/i18n/locales/en/player.json index bcf22d4..274fc6a 100644 --- a/src/i18n/locales/en/player.json +++ b/src/i18n/locales/en/player.json @@ -135,6 +135,22 @@ "subtitle": "This issue is now closed.", "description": "The betting window has closed. Please wait for the next issue to place your bets." }, + "jackpotPanel": { + "disabledTitle": "Unavailable", + "disabledSubtitle": "Jackpot is currently disabled.", + "disabledDescription": "The admin has turned off Jackpot for now. This tab remains visible for information only.", + "infoTitle": "Pool Information", + "infoSubtitle": "Jackpot is currently enabled.", + "infoDescription": "Jackpot is not a standalone play. Eligible tickets placed in the active plays will join the pool automatically based on admin rules.", + "closedInfoTitle": "Pool Information", + "closedInfoSubtitle": "Jackpot is currently enabled.", + "closedInfoDescription": "Jackpot uses automatic participation for eligible tickets. This issue is closed, so please wait for the next issue." + }, + "jackpotParticipation": { + "title": "Automatic Jackpot Participation", + "previewDescription": "If this ticket is submitted successfully and meets the configured rules, it will join the Jackpot pool automatically. No separate Jackpot bet is needed.", + "resultDescription": "The successful ticket lines in this order will join the Jackpot pool automatically under the configured rules. If a first-prize hit later triggers the pool, it will settle together with the normal payout." + }, "boxMode": { "iboxTitle": "iBox", "iboxDesc": "Divide all by amount", diff --git a/src/i18n/locales/ne/player.json b/src/i18n/locales/ne/player.json index ba79f05..24af032 100644 --- a/src/i18n/locales/ne/player.json +++ b/src/i18n/locales/ne/player.json @@ -135,6 +135,22 @@ "subtitle": "यो इश्यू बन्द भएको छ।", "description": "बेटिङ समय बन्द भएको छ। अर्को इश्यू पर्खेर बेट राख्नुहोस्।" }, + "jackpotPanel": { + "disabledTitle": "बन्द गरिएको छ", + "disabledSubtitle": "Jackpot अहिले सक्षम छैन।", + "disabledDescription": "एडमिनले Jackpot बन्द गरेको छ। यो ट्याब अहिले जानकारीका लागि मात्र देखाइन्छ।", + "infoTitle": "पूल जानकारी", + "infoSubtitle": "Jackpot अहिले सक्षम छ।", + "infoDescription": "Jackpot छुट्टै बेट होइन। उपलब्ध खेलमा गरिएको योग्य टिकटहरू एडमिन नियमअनुसार स्वतः Jackpot पूलमा सहभागी हुन्छन्।", + "closedInfoTitle": "पूल जानकारी", + "closedInfoSubtitle": "Jackpot अहिले सक्षम छ।", + "closedInfoDescription": "योग्य टिकटहरू स्वतः Jackpot मा सहभागी हुन्छन्। यो इश्यू बन्द भइसकेको छ, त्यसैले अर्को इश्यू पर्खनुहोस्।" + }, + "jackpotParticipation": { + "title": "Jackpot स्वतः सहभागिता", + "previewDescription": "यदि यो टिकट सफलतापूर्वक पेश भयो र नियम पूरा गर्यो भने, यो स्वतः Jackpot पूलमा सहभागी हुनेछ। छुट्टै Jackpot बेट आवश्यक छैन।", + "resultDescription": "यस अर्डरका सफल टिकटहरू कन्फिगर गरिएको नियमअनुसार स्वतः Jackpot पूलमा सहभागी हुनेछन्। पछि पहिलो पुरस्कार र पूल ट्रिगर सर्त पूरा भएमा, नियमित payout सँगै सेटल हुनेछ।" + }, "boxMode": { "iboxTitle": "iBox", "iboxDesc": "रकम सबैमा बाँड्नुहोस्", diff --git a/src/i18n/locales/zh/player.json b/src/i18n/locales/zh/player.json index bda96c5..006c3d4 100644 --- a/src/i18n/locales/zh/player.json +++ b/src/i18n/locales/zh/player.json @@ -135,6 +135,22 @@ "subtitle": "当前期已停止接收注单。", "description": "下注窗口已关闭,请等待下一期再下注。" }, + "jackpotPanel": { + "disabledTitle": "已关闭", + "disabledSubtitle": "Jackpot 当前未启用。", + "disabledDescription": "后台已关闭 Jackpot 功能,当前仅保留展示页签。", + "infoTitle": "奖池信息", + "infoSubtitle": "Jackpot 当前已启用。", + "infoDescription": "Jackpot 不是单独下注玩法。玩家在开放玩法中提交有效注单后,将按后台规则自动参与奖池。", + "closedInfoTitle": "奖池信息", + "closedInfoSubtitle": "Jackpot 当前已启用。", + "closedInfoDescription": "Jackpot 采用有效注单自动参与机制。本期下注窗口已关闭,请等待下一期开放后参与。" + }, + "jackpotParticipation": { + "title": "Jackpot 自动参与", + "previewDescription": "若本单成功提交且满足后台规则,系统会自动按有效注单参与 Jackpot 奖池,无需单独再下一笔。", + "resultDescription": "本次成功注项将按后台规则自动参与 Jackpot 奖池,后续若命中头奖并满足触发条件,将与常规派彩一并结算。" + }, "boxMode": { "iboxTitle": "iBox", "iboxDesc": "按金额分摊全部组合",