feat: enhance player panel and draw status handling

- Refactored PlayerPanel layout for improved title positioning and responsiveness.
- Added new function to check if betting is blocked based on hall status.
- Updated HallDrawPanel to utilize the new betting status check and display appropriate messages.
- Enhanced i18n support with new notices for review and non-bettable states across multiple languages.
This commit is contained in:
2026-05-25 15:35:50 +08:00
parent 3649bb9300
commit ca3a1db770
9 changed files with 38 additions and 43 deletions

View File

@@ -14,6 +14,11 @@ export function isHallSealedCountdownUi(status: string): boolean {
return status === "closing" || status === "closed";
}
/** 不可下注时展示阻断提示条 */
export function isHallBlockedForBetting(status: string): boolean {
return status !== "open";
}
/** 对齐界面文档 §4.2 状态文案与 PRD 期号状态 */
export function drawStatusHud(status: string): DrawStatusHud {
switch (status) {

View File

@@ -6,7 +6,7 @@ import { useTranslation } from "react-i18next";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { drawStatusHud, isHallSealedCountdownUi } from "@/features/draw/draw-status-meta";
import { drawStatusHud, isHallBlockedForBetting, isHallSealedCountdownUi } from "@/features/draw/draw-status-meta";
import type { HallDrawLiveSnapshot } from "@/features/hall/use-hall-draw-live";
import { formatSecondsClock } from "@/lib/format-gmt";
import { formatLotteryInstant } from "@/lib/player-datetime";
@@ -64,7 +64,9 @@ function CloseTime({
let seconds = 0;
let label = t("draw.closesIn");
if (hud.countdownKind === "close") {
if (hud.countdownKind === "none") {
label = t(hud.labelKey, { defaultValue: hud.labelKey });
} else if (hud.countdownKind === "close") {
seconds = Math.max(0, Math.ceil(((payload.close_time ? Date.parse(payload.close_time) : 0) - nowMs) / 1000));
} else if (hud.countdownKind === "draw") {
seconds = Math.max(0, Math.ceil(((payload.draw_time ? Date.parse(payload.draw_time) : 0) - nowMs) / 1000));
@@ -77,7 +79,7 @@ function CloseTime({
return (
<>
<span className="text-lg font-black tabular-nums text-[#ff143d]">
{formatSecondsClock(seconds)}
{hud.countdownKind === "none" ? "--:--" : formatSecondsClock(seconds)}
</span>
<span className="mt-1 text-[11px] text-slate-500">{label}</span>
</>
@@ -127,6 +129,7 @@ export function HallDrawPanel({ drawLive }: { drawLive: HallDrawLiveSnapshot })
const hud = drawStatusHud(display.status);
const sealedUi = isHallSealedCountdownUi(display.status);
const blockedUi = isHallBlockedForBetting(display.status);
return (
<section
className={cn(
@@ -163,10 +166,14 @@ export function HallDrawPanel({ drawLive }: { drawLive: HallDrawLiveSnapshot })
/>
</div>
</div>
{sealedUi ? (
{blockedUi ? (
<div className="flex items-center gap-2 border-t border-red-100 bg-red-50 px-3 py-2 text-xs font-medium text-red-600">
<TimerReset className="size-4" aria-hidden />
{t("draw.sealedNotice")}
<TimerReset className="size-4 shrink-0" aria-hidden />
{display.status === "review"
? t("draw.reviewNotice")
: sealedUi
? t("draw.sealedNotice")
: t("draw.notBettableNotice")}
</div>
) : (
<div className="flex items-center justify-between border-t border-[#eef3f9] bg-[#fbfdff] px-3 py-1.5 text-[11px] text-slate-500">