feat: enhance player login validation and update betting preview
- Added username and password validation to the player login screen, improving user feedback for input errors. - Updated the betting preview dialog to conditionally display rebate information based on the applied instant rebate status. - Enhanced documentation in AGENTS.md to clarify credit flow and settlement processes. - Modified .env.example to provide clearer instructions for multi-site deployment configurations.
This commit is contained in:
@@ -116,6 +116,10 @@ export function HallBetPreviewDialog({
|
||||
const { t } = useTranslation("player");
|
||||
const summary = data?.summary;
|
||||
const lines = data?.lines ?? [];
|
||||
const periodRebate = summary?.instant_rebate_applied === false;
|
||||
const rebateLabel = periodRebate
|
||||
? t("hall.preview.periodRebate", { defaultValue: "账期回水" })
|
||||
: t("hall.preview.rebate");
|
||||
|
||||
useEffect(() => {
|
||||
if (open && !placing && !data) {
|
||||
@@ -216,7 +220,7 @@ export function HallBetPreviewDialog({
|
||||
{t("hall.preview.amount")}
|
||||
</th>
|
||||
<th className="border-r border-[#dfe8f6] px-2 py-3 text-center font-black">
|
||||
{t("hall.preview.rebate")}
|
||||
{rebateLabel}
|
||||
</th>
|
||||
<th className="border-r border-[#dfe8f6] px-2 py-3 text-center font-black">
|
||||
{t("hall.preview.estimatedMax")}
|
||||
@@ -245,7 +249,8 @@ export function HallBetPreviewDialog({
|
||||
{formatMinorAsCurrency(ln.total_bet_amount, currencyCode)}
|
||||
</td>
|
||||
<td className="border-r border-[#e8eef7] px-2 py-3 text-center font-semibold tabular-nums text-emerald-600">
|
||||
-{formatMinorAsCurrency(ln.rebate_amount, currencyCode).replace(`${currencyCode} `, "")}
|
||||
{periodRebate ? "" : "-"}
|
||||
{formatMinorAsCurrency(ln.rebate_amount, currencyCode).replace(`${currencyCode} `, "")}
|
||||
</td>
|
||||
<td className="border-r border-[#e8eef7] px-2 py-3 text-center font-black tabular-nums text-[#e5002c]">
|
||||
{formatMinorAsCurrency(ln.estimated_max_payout, currencyCode)}
|
||||
@@ -268,9 +273,9 @@ export function HallBetPreviewDialog({
|
||||
</p>
|
||||
</div>
|
||||
<div className="border-r border-[#dfe8f6] px-2 py-3">
|
||||
<p className="font-bold text-[#304f86]">{t("hall.preview.rebate")}</p>
|
||||
<p className="font-bold text-[#304f86]">{rebateLabel}</p>
|
||||
<p className="mt-1 font-black tabular-nums text-emerald-600">
|
||||
-
|
||||
{periodRebate ? "" : "-"}
|
||||
{formatMinorAsCurrency(summary.total_rebate_amount, currencyCode).replace(
|
||||
`${currencyCode} `,
|
||||
"",
|
||||
@@ -292,6 +297,15 @@ export function HallBetPreviewDialog({
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{periodRebate ? (
|
||||
<p className="text-xs leading-relaxed text-slate-500">
|
||||
{t("hall.preview.periodRebateHint", {
|
||||
defaultValue:
|
||||
"信用盘回水在账期结算入账,下注时按全额占用可用信用,此处为账期回水预估。",
|
||||
})}
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
{data.warnings.length > 0 ? (
|
||||
<WarningsBlock warnings={data.warnings} />
|
||||
) : (
|
||||
|
||||
@@ -15,10 +15,12 @@ import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { usePlayerSessionStore } from "@/stores/player-session-store";
|
||||
import {
|
||||
validatePlayerLoginPassword,
|
||||
validatePlayerLoginUsername,
|
||||
} from "@/lib/player-input-validation";
|
||||
import { LotteryApiBizError } from "@/types/api/errors";
|
||||
|
||||
const DEPLOY_SITE_CODE = process.env.NEXT_PUBLIC_PLAYER_SITE_CODE?.trim() ?? "";
|
||||
|
||||
function stripSearchParamFromBrowserUrl(name: string): void {
|
||||
if (typeof window === "undefined") return;
|
||||
const url = new URL(window.location.href);
|
||||
@@ -58,10 +60,27 @@ export function PlayerLoginScreen(): React.ReactElement {
|
||||
return;
|
||||
}
|
||||
|
||||
const usernameIssue = validatePlayerLoginUsername(username);
|
||||
if (usernameIssue === "invalid_charset") {
|
||||
toast.error(
|
||||
t("login.usernameInvalidCharset", {
|
||||
defaultValue: "账号只能使用字母、数字、点(.)、下划线和连字符",
|
||||
}),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const passwordIssue = validatePlayerLoginPassword(password);
|
||||
if (passwordIssue === "too_short") {
|
||||
toast.error(
|
||||
t("login.passwordMinLength", { defaultValue: "密码至少需要 6 个字符" }),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
const data = await postPlayerAuthLogin({
|
||||
...(DEPLOY_SITE_CODE !== "" ? { site_code: DEPLOY_SITE_CODE } : {}),
|
||||
username: username.trim(),
|
||||
password,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user