Files
lotteryAdmin/src/modules/draws/draw-subnav.tsx
kang 65eaeecf8c feat(agents, i18n): enhance agent management and settlement features with new translations and UI updates
Added new translations for agent management and settlement features in English, Nepali, and Chinese, improving multi-language support. Updated the agents console to reflect changes in funding modes and player details, enhancing user experience. Refactored the admin permission gate to include new logic for handling bound line agents, ensuring better permission management. Additionally, streamlined the UI for agent-related pages and improved navigation to the settlement center, consolidating related functionalities for better accessibility.
2026-06-04 18:01:05 +08:00

124 lines
3.7 KiB
TypeScript

"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { buttonVariants } from "@/components/ui/button";
import { adminHasAnyPermission } from "@/lib/admin-permissions";
import { PRD_DRAW_FINANCE_ACCESS_ANY, PRD_RISK_ACCESS_ANY } from "@/lib/admin-prd";
import { canManageDrawResults, canViewDrawFinance, canViewDrawResults } from "@/lib/draw-access";
import { useAdminProfile } from "@/stores/admin-session";
import { cn } from "@/lib/utils";
const segments = [
{ suffix: "", key: "status", label: "subnav.status", requiresManage: false },
{ suffix: "/results", key: "results", label: "subnav.results", requiresManage: false },
{ suffix: "/finance", key: "finance", label: "subnav.finance", requiresManage: false },
{ suffix: "/review", key: "review", label: "subnav.review", requiresManage: true },
{
suffix: "/risk/occupancy",
key: "riskLockLogs",
label: "subnav.riskLockLogs",
requiresManage: false,
requiresRisk: true,
},
{
suffix: "/risk/pools",
key: "riskPools",
label: "subnav.riskPools",
requiresManage: false,
requiresRisk: true,
},
] as const;
function isRiskPoolsTabActive(pathname: string, base: string): boolean {
const riskPrefix = `${base}/risk/`;
if (!pathname.startsWith(riskPrefix)) {
return false;
}
const rest = pathname.slice(riskPrefix.length);
return (
rest === "pools"
|| rest.startsWith("pools/")
|| rest === "hot"
|| rest === "sold-out"
);
}
function isReviewTabActive(pathname: string, base: string): boolean {
const reviewPrefix = `${base}/review`;
const publishPrefix = `${base}/publish`;
return (
pathname === reviewPrefix
|| pathname.startsWith(`${reviewPrefix}/`)
|| pathname.startsWith(`${publishPrefix}/`)
);
}
export function DrawSubnav({ drawId }: { drawId: string }): React.ReactElement {
const { t } = useTranslation("draws");
const pathname = usePathname();
const base = `/admin/draws/${drawId}`;
const profile = useAdminProfile();
const perms = profile?.permissions ?? [];
const canViewDraw = canViewDrawResults(perms);
const canManageDraw = canManageDrawResults(perms);
const canViewFinance = canViewDrawFinance(perms);
const canViewRisk = adminHasAnyPermission(perms, [...PRD_RISK_ACCESS_ANY]);
const visibleSegments = useMemo(
() =>
segments.filter((segment) => {
if (!canViewDraw) {
return false;
}
if (segment.requiresManage && !canManageDraw) {
return false;
}
if (segment.key === "finance" && !canViewFinance) {
return false;
}
if ("requiresRisk" in segment && segment.requiresRisk && !canViewRisk) {
return false;
}
return true;
}),
[canManageDraw, canViewDraw, canViewRisk],
);
return (
<nav className="mb-6 flex flex-wrap gap-2 border-b border-border pb-3">
{visibleSegments.map(({ suffix, key, label }) => {
const href = `${base}${suffix}`;
const active =
suffix === ""
? pathname === base || pathname === `${base}/`
: suffix === "/review"
? isReviewTabActive(pathname, base)
: key === "riskPools"
? isRiskPoolsTabActive(pathname, base)
: pathname === href || pathname.startsWith(`${href}/`);
return (
<Link
key={key}
href={href}
className={cn(
buttonVariants({ variant: active ? "default" : "outline", size: "sm" }),
)}
>
{t(label)}
</Link>
);
})}
</nav>
);
}