feat(docs, agents, risk): enhance documentation, API queries, and UI components

Updated the public documentation site with improved layout and accessibility, including new sections for client integration and admin guides. Enhanced API queries by adding 'active_only' and 'group_by' parameters for better data filtering in risk management. Refined UI components for agent management, ensuring consistent styling and improved user experience across the application. Added localization support for new documentation content in English and Nepali.
This commit is contained in:
2026-06-15 17:21:50 +08:00
parent 17335cb47a
commit 641c87ff50
107 changed files with 5114 additions and 943 deletions

View File

@@ -4,7 +4,7 @@ import { AgentsSubnav } from "@/modules/agents/agents-subnav";
export default function AdminAgentsLayout({ children }: { children: ReactNode }) {
return (
<div className="mx-auto flex w-full max-w-[1680px] min-w-0 flex-col gap-4 px-4 py-4 sm:px-6 lg:px-8 lg:py-5">
<div className="mx-auto flex w-full max-w-[1680px] min-h-0 min-w-0 flex-1 flex-col gap-4 px-4 py-4 sm:px-6 lg:px-8 lg:py-5">
<AgentsSubnav />
{children}
</div>

View File

@@ -3,7 +3,7 @@ import type { Metadata } from "next";
import { AgentsDirectoryConsole } from "@/modules/agents/agents-directory-console";
import { buildPageMetadata } from "@/lib/page-metadata";
export const metadata: Metadata = buildPageMetadata("agents", "directoryTitle");
export const metadata: Metadata = buildPageMetadata("agents", "listTitle");
export default function AgentsListPage() {
return <AgentsDirectoryConsole />;

View File

@@ -4,10 +4,10 @@ import {
} from "@/modules/risk/risk-pools-console";
function parsePoolFilter(raw: string | undefined): RiskPoolListFilter {
if (raw === "sold_out" || raw === "high_risk") {
if (raw === "sold_out" || raw === "high_risk" || raw === "all" || raw === "active") {
return raw;
}
return "all";
return "active";
}
export default async function AdminDrawRiskPoolsPage(props: {
@@ -24,7 +24,7 @@ export default async function AdminDrawRiskPoolsPage(props: {
drawId={id}
titleKey="allPoolsPageTitle"
initialFilter={filter}
defaultSort={filter === "high_risk" ? "usage_desc" : "number_asc"}
defaultSort={filter === "high_risk" || filter === "active" ? "usage_desc" : "number_asc"}
allowSortChange
/>
);

View File

@@ -0,0 +1,22 @@
import { AdminPermissionGate } from "@/components/admin/admin-permission-gate";
import { ModuleScaffold } from "@/components/admin/module-scaffold";
import { PRD_TICKETS_ACCESS_ANY } from "@/lib/admin-prd";
import { TicketDetailConsole } from "@/modules/tickets/ticket-detail-console";
import { buildPageMetadata } from "@/lib/page-metadata";
import type { Metadata } from "next";
export const metadata: Metadata = buildPageMetadata("tickets", "detailTitle");
export default async function AdminTicketDetailPage(props: {
params: Promise<{ ticketNo: string }>;
}) {
const { ticketNo } = await props.params;
return (
<ModuleScaffold>
<AdminPermissionGate requiredAny={PRD_TICKETS_ACCESS_ANY}>
<TicketDetailConsole ticketNo={decodeURIComponent(ticketNo)} />
</AdminPermissionGate>
</ModuleScaffold>
);
}

View File

@@ -0,0 +1,5 @@
import { AdminAgentsDocScreen } from "@/modules/docs/admin/admin-doc-screens";
export default function AdminDocsAgentsPage(): React.ReactElement {
return <AdminAgentsDocScreen />;
}

View File

@@ -0,0 +1,5 @@
import { AdminConfigDocScreen } from "@/modules/docs/admin/admin-doc-screens";
export default function AdminDocsConfigPage(): React.ReactElement {
return <AdminConfigDocScreen />;
}

View File

@@ -0,0 +1,5 @@
import { AdminDrawsDocScreen } from "@/modules/docs/admin/admin-doc-screens";
export default function AdminDocsDrawsPage(): React.ReactElement {
return <AdminDrawsDocScreen />;
}

View File

@@ -0,0 +1,5 @@
import { AdminFaqDocScreen } from "@/modules/docs/admin/admin-doc-screens";
export default function AdminDocsFaqPage(): React.ReactElement {
return <AdminFaqDocScreen />;
}

View File

@@ -0,0 +1,5 @@
import { AdminFundOperationsDocScreen } from "@/modules/docs/admin/admin-doc-screens";
export default function AdminDocsFundOperationsPage(): React.ReactElement {
return <AdminFundOperationsDocScreen />;
}

View File

@@ -0,0 +1,13 @@
import type { ReactNode } from "react";
import { DocsSidebar } from "@/components/docs/docs-sidebar";
import { DocsBody } from "@/components/docs/docs-shell";
import { ADMIN_DOCS_NAV_GROUPS } from "@/lib/admin-docs-nav";
export default function AdminDocsLayout({ children }: { children: ReactNode }): React.ReactElement {
return (
<DocsBody sidebar={<DocsSidebar groups={ADMIN_DOCS_NAV_GROUPS} namespace="adminDocs" />}>
{children}
</DocsBody>
);
}

View File

@@ -0,0 +1,5 @@
import { AdminManualReviewDocScreen } from "@/modules/docs/admin/admin-doc-screens";
export default function AdminDocsManualReviewPage(): React.ReactElement {
return <AdminManualReviewDocScreen />;
}

View File

@@ -0,0 +1,5 @@
import { AdminOverviewDocScreen } from "@/modules/docs/admin/admin-doc-screens";
export default function AdminDocsOverviewPage(): React.ReactElement {
return <AdminOverviewDocScreen />;
}

View File

@@ -0,0 +1,5 @@
import { AdminPlayersDocScreen } from "@/modules/docs/admin/admin-doc-screens";
export default function AdminDocsPlayersPage(): React.ReactElement {
return <AdminPlayersDocScreen />;
}

View File

@@ -0,0 +1,5 @@
import { AdminReportsDocScreen } from "@/modules/docs/admin/admin-doc-screens";
export default function AdminDocsReportsPage(): React.ReactElement {
return <AdminReportsDocScreen />;
}

View File

@@ -0,0 +1,5 @@
import { AdminRolesDocScreen } from "@/modules/docs/admin/admin-doc-screens";
export default function AdminDocsRolesPage(): React.ReactElement {
return <AdminRolesDocScreen />;
}

View File

@@ -0,0 +1,5 @@
import { AdminSettlementCenterDocScreen } from "@/modules/docs/admin/admin-doc-screens";
export default function AdminDocsSettlementCenterPage(): React.ReactElement {
return <AdminSettlementCenterDocScreen />;
}

View File

@@ -0,0 +1,5 @@
import { AdminSiteSetupDocScreen } from "@/modules/docs/admin/admin-doc-screens";
export default function AdminDocsSiteSetupPage(): React.ReactElement {
return <AdminSiteSetupDocScreen />;
}

View File

@@ -0,0 +1,5 @@
import { AdminTicketsDocScreen } from "@/modules/docs/admin/admin-doc-screens";
export default function AdminDocsTicketsPage(): React.ReactElement {
return <AdminTicketsDocScreen />;
}

View File

@@ -0,0 +1,5 @@
import { AdminWalletDocScreen } from "@/modules/docs/admin/admin-doc-screens";
export default function AdminDocsWalletPage(): React.ReactElement {
return <AdminWalletDocScreen />;
}

View File

@@ -0,0 +1,5 @@
import { redirect } from "next/navigation";
export default function LegacyAdminGuidePage(): never {
redirect("/docs/admin");
}

View File

@@ -0,0 +1,6 @@
import { redirect } from "next/navigation";
/** 旧链接兼容:完整内容已拆至左侧分章导航 */
export default function ApiReferencePage(): never {
redirect("/docs/integration");
}

View File

@@ -0,0 +1,5 @@
import { DeliveryDocScreen } from "@/modules/docs/integration/integration-doc-screens";
export default function IntegrationDeliveryPage(): React.ReactElement {
return <DeliveryDocScreen />;
}

View File

@@ -0,0 +1,5 @@
import { TroubleshootingDocScreen } from "@/modules/docs/integration/integration-doc-screens";
export default function IntegrationTroubleshootingPage(): React.ReactElement {
return <TroubleshootingDocScreen />;
}

View File

@@ -5,10 +5,10 @@ import { DocsShell } from "@/components/docs/docs-shell";
export const metadata: Metadata = {
title: {
template: "%s · Integration API",
default: "Integration API",
template: "%s · Docs",
default: "Documentation",
},
description: "Lottery integration docs: SSO, wallet gateway, transfers.",
description: "Lottery admin user guide and API integration documentation.",
};
export default function DocsLayout({ children }: { children: ReactNode }): React.ReactElement {

View File

@@ -238,3 +238,21 @@
}
}
/* 公开文档站:正文链接与强调,避免继承后台 muted 色 */
.docs-site .doc-content a:not([class]) {
color: #0f172a;
font-weight: 500;
text-decoration: underline;
text-decoration-color: #cbd5e1;
text-underline-offset: 2px;
}
.docs-site .doc-content a:not([class]):hover {
text-decoration-color: #64748b;
}
.docs-site .doc-content strong {
color: #0f172a;
font-weight: 600;
}