feat: 精简玩家端页面结构并支持局域网开发热更新
Some checks failed
lotteryfront CI / build (push) Has been cancelled

- 合并钱包、订单、开奖、通知等独立 screen 到页面层,减少重复壳组件
- 优化订单列表/详情、钱包划转与待对账展示、开奖核对与结果详情交互
- 改进入口 gate、移动端视口与下拉刷新在窄屏下的表现
- dev 绑定 0.0.0.0 并默认放行 192.168/10 网段,修复局域网 HMR WebSocket
This commit is contained in:
2026-06-26 14:10:47 +08:00
parent dd1155978a
commit e5622c58cb
51 changed files with 1184 additions and 1335 deletions

View File

@@ -1,7 +1,7 @@
"use client";
import { ArrowDownLeft, ArrowUpRight } from "lucide-react";
import { useState } from "react";
import { useCallback, useState } from "react";
import { useTranslation } from "react-i18next";
import { Button } from "@/components/ui/button";
@@ -23,6 +23,8 @@ type BaseProps = {
onSuccess: () => Promise<void>;
/** 避免同页多实例 input id 冲突 */
idPrefix?: string;
open?: boolean;
onOpenChange?: (open: boolean) => void;
};
export function TransferInDialog({
@@ -34,6 +36,8 @@ export function TransferInDialog({
triggerClassName,
triggerVariant = "wallet",
triggerLabel,
open: controlledOpen,
onOpenChange: controlledOnOpenChange,
}: BaseProps & {
lotteryMinor: number;
mainMinor?: number | null;
@@ -41,7 +45,19 @@ export function TransferInDialog({
triggerVariant?: "wallet" | "hall";
triggerLabel?: string;
}) {
const [open, setOpen] = useState(false);
const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
const isControlled = controlledOpen !== undefined;
const open = isControlled ? controlledOpen : uncontrolledOpen;
const setOpen = useCallback(
(next: boolean) => {
if (isControlled) {
controlledOnOpenChange?.(next);
} else {
setUncontrolledOpen(next);
}
},
[controlledOnOpenChange, isControlled],
);
const { t } = useTranslation("player");
const resolvedTriggerLabel = triggerLabel ?? t("wallet.transferIn");
@@ -94,13 +110,27 @@ export function TransferOutDialog({
triggerClassName,
triggerVariant = "wallet",
triggerLabel,
open: controlledOpen,
onOpenChange: controlledOnOpenChange,
}: BaseProps & {
availableMinor: number;
triggerClassName?: string;
triggerVariant?: "wallet" | "hall";
triggerLabel?: string;
}) {
const [open, setOpen] = useState(false);
const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
const isControlled = controlledOpen !== undefined;
const open = isControlled ? controlledOpen : uncontrolledOpen;
const setOpen = useCallback(
(next: boolean) => {
if (isControlled) {
controlledOnOpenChange?.(next);
} else {
setUncontrolledOpen(next);
}
},
[controlledOnOpenChange, isControlled],
);
const { t } = useTranslation("player");
const resolvedTriggerLabel = triggerLabel ?? t("wallet.transferOut");