feat: remove pending reconcile notifications section from wallet screen
Some checks failed
lotteryfront CI / build (push) Has been cancelled

- Deleted WalletPendingReconcileSection component and usePendingWalletReconcile hook
- Removed pending reconcile notification helpers and translation key functions
- Cleaned up wallet logs refresh event dispatching and pending reconcile cache logic
- Simplified wallet screen section deep linking to only handle logs section
This commit is contained in:
2026-06-29 17:54:12 +08:00
parent 7702bc90e0
commit 7bfc713b14
4 changed files with 1 additions and 338 deletions

View File

@@ -1,153 +0,0 @@
"use client";
import { BellRing, CheckCheck } from "lucide-react";
import { useTranslation } from "react-i18next";
import { Button } from "@/components/ui/button";
import { usePendingWalletReconcile } from "@/hooks/use-pending-wallet-reconcile";
import { formatPlayerInstant } from "@/lib/player-datetime";
import { formatMinorAsCurrency } from "@/lib/money";
import { isCreditFundingPlayer } from "@/lib/player-funding-mode";
import {
pendingReconcileDescriptionKey,
pendingReconcileTitleKey,
} from "@/lib/pending-reconcile-notification";
import { usePlayerSessionStore } from "@/stores/player-session-store";
import { cn } from "@/lib/utils";
type WalletPendingReconcileSectionProps = {
onViewLogs?: () => void;
};
/** 钱包页内嵌:待对账提醒(原独立 /notifications 页) */
export function WalletPendingReconcileSection({
onViewLogs,
}: WalletPendingReconcileSectionProps) {
const { t } = useTranslation("player");
const creditMode = isCreditFundingPlayer(usePlayerSessionStore((state) => state.profile));
const { pending, unreadPending, unreadCount, loading, markAsRead, markAllAsRead } =
usePendingWalletReconcile();
const unreadSet = new Set(unreadPending.map((item) => item.transfer_no));
if (creditMode) {
return null;
}
return (
<section id="wallet-pending" className="scroll-mt-3 space-y-3">
<div className="flex items-center justify-between rounded-xl border border-[#dce7f7] bg-[#f8fbff] px-3 py-2.5">
<div className="flex items-center gap-2">
<BellRing className="size-4 text-[#0b56b7]" aria-hidden />
<p className="text-sm font-semibold text-[#0b3f96]">
{t("notifications.title")}
{unreadCount > 0 ? (
<span className="ml-1.5 text-xs font-bold text-amber-700">
({t("notifications.unreadCount", { count: unreadCount })})
</span>
) : null}
</p>
</div>
<Button
type="button"
size="sm"
variant="ghost"
className="h-8 px-2 text-xs font-bold text-[#0b56b7] hover:bg-[#ebf2ff]"
onClick={markAllAsRead}
disabled={pending.length === 0 || unreadCount === 0}
>
<CheckCheck className="mr-1 size-3.5" aria-hidden />
{t("notifications.markAllRead")}
</Button>
</div>
{loading && pending.length === 0 ? (
<div className="rounded-xl border border-[#dce7f7] bg-white px-4 py-6 text-center text-sm text-slate-500">
{t("actions.loading")}
</div>
) : null}
{!loading && pending.length === 0 ? (
<div className="rounded-xl border border-dashed border-[#dce7f7] bg-white px-4 py-8 text-center">
<p className="text-sm text-slate-500">{t("notifications.empty")}</p>
</div>
) : null}
{pending.length > 0 ? (
<ul className="space-y-2">
{pending.map((item) => {
const cardRead = !unreadSet.has(item.transfer_no);
return (
<li
key={item.transfer_no}
className={cn(
"rounded-xl border px-3 py-3 transition-colors",
cardRead
? "border-[#e4eaf4] bg-white"
: "border-amber-200 bg-amber-50/80",
)}
>
<div className="flex items-start justify-between gap-2">
<div className="min-w-0">
<p className="text-sm font-bold text-amber-900">
{t(pendingReconcileTitleKey(item.type))}
</p>
<p className="mt-0.5 text-xs text-slate-500">
{formatPlayerInstant(item.created_at)}
</p>
</div>
<div className="flex shrink-0 flex-col items-end gap-1">
<span className="rounded-full bg-amber-100 px-2 py-0.5 text-[11px] font-bold text-amber-800">
{t("notifications.pendingBadge")}
</span>
<span
className={cn(
"text-[11px] font-semibold",
cardRead ? "text-slate-400" : "text-amber-700",
)}
>
{cardRead ? t("notifications.read") : t("notifications.unread")}
</span>
</div>
</div>
<p className="mt-2 text-xs leading-relaxed text-amber-950/85">
{t(pendingReconcileDescriptionKey(item.type))}
</p>
<p className="mt-2 text-sm text-slate-700">
<span className="text-xs font-medium text-slate-500">
{t("notifications.amountLabel")}{" "}
</span>
{formatMinorAsCurrency(item.amount, item.currency_code)}
</p>
<div className="mt-3 flex items-center gap-2">
<Button
type="button"
size="sm"
variant="outline"
className="h-8 rounded-full border-[#dce7f7] px-3 text-xs font-semibold text-[#0b56b7]"
onClick={() => markAsRead(item.transfer_no)}
>
{t("notifications.markRead")}
</Button>
<Button
type="button"
size="sm"
className="h-8 rounded-full bg-[#07459f] px-3 text-xs font-semibold text-white hover:bg-[#063b88]"
onClick={() => {
markAsRead(item.transfer_no);
onViewLogs?.();
}}
>
{t("notifications.viewLogs")}
</Button>
</div>
</li>
);
})}
</ul>
) : null}
</section>
);
}

View File

@@ -14,10 +14,8 @@ import {
TransferInDialog,
TransferOutDialog,
} from "@/features/wallet/wallet-transfer-dialogs";
import { WalletPendingReconcileSection } from "@/features/wallet/wallet-pending-reconcile-section";
import { PlayerMoneyDisplay } from "@/components/player-money-display";
import { WalletLogsBlock } from "@/features/wallet/wallet-logs-block";
import { dispatchWalletLogsRefresh } from "@/hooks/use-pending-wallet-reconcile";
import { useActivePlayerCurrency } from "@/hooks/use-active-player-currency";
import { isCreditFundingPlayer } from "@/lib/player-funding-mode";
import { formatMinorAsCurrency } from "@/lib/money";
@@ -80,10 +78,7 @@ export function WalletScreen() {
if (section !== "logs" && section !== "pending") return;
sectionDeepLinkHandledRef.current = true;
const targetId =
section === "logs" || (section === "pending" && isCreditPlayer)
? "wallet-logs"
: "wallet-pending";
const targetId = "wallet-logs";
const timer = window.setTimeout(() => {
scrollToWalletSection(targetId);
router.replace("/wallet", { scroll: false });
@@ -103,7 +98,6 @@ export function WalletScreen() {
? { ...nextLogs, items: [...current.items, ...nextLogs.items] }
: nextLogs,
);
dispatchWalletLogsRefresh(nextLogs.pending_reconcile ?? []);
return nextLogs;
}, [currency, filter]);
@@ -126,7 +120,6 @@ export function WalletScreen() {
if (cancelled) return;
setBalance(b);
setLogs(nextLogs);
dispatchWalletLogsRefresh(nextLogs.pending_reconcile ?? []);
} catch (e) {
if (!cancelled) {
setError(formatWalletClientError(e, t));
@@ -169,7 +162,6 @@ export function WalletScreen() {
});
if (!cancelled) {
setLogs(nextLogs);
dispatchWalletLogsRefresh(nextLogs.pending_reconcile ?? []);
}
} catch (e) {
if (!cancelled) {
@@ -340,10 +332,6 @@ export function WalletScreen() {
</div>
) : null}
<WalletPendingReconcileSection
onViewLogs={() => scrollToWalletSection("wallet-logs")}
/>
<div id="wallet-logs" className="scroll-mt-3">
<WalletLogsBlock
creditMode={isCreditPlayer}