refactor: 优化管理端配置页加载与导航,更新本地端口说明
This commit is contained in:
@@ -3,5 +3,5 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
# 必填:Laravel 应用根 URL(无尾部斜杠)。axios 会请求 {此地址}/api/v1/...
|
# 必填:Laravel 应用根 URL(无尾部斜杠)。axios 会请求 {此地址}/api/v1/...
|
||||||
# 需保证 Laravel 已允许该来源的 CORS(本地一般为 http://localhost:3000 等)。
|
# 需保证 Laravel 已允许该来源的 CORS(本地管理端为 http://localhost:3801 等)。
|
||||||
NEXT_PUBLIC_LOTTERY_API_BASE_URL=http://127.0.0.1:8000
|
NEXT_PUBLIC_LOTTERY_API_BASE_URL=http://127.0.0.1:8000
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ pnpm dev
|
|||||||
bun dev
|
bun dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
Open [http://localhost:3801](http://localhost:3801) with your browser to see the result.
|
||||||
|
|
||||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev --port 3801",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "eslint"
|
"lint": "eslint"
|
||||||
|
|||||||
@@ -9,10 +9,11 @@ function pad2(n: number): string {
|
|||||||
*/
|
*/
|
||||||
export function formatAdminInstant(
|
export function formatAdminInstant(
|
||||||
iso: string | null | undefined,
|
iso: string | null | undefined,
|
||||||
_options: {
|
options: {
|
||||||
locale: AdminApiLocale;
|
locale: AdminApiLocale;
|
||||||
},
|
},
|
||||||
): string {
|
): string {
|
||||||
|
void options;
|
||||||
if (iso == null || iso === "") {
|
if (iso == null || iso === "") {
|
||||||
return "—";
|
return "—";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useMemo } from "react";
|
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { usePathname } from "next/navigation";
|
import { usePathname } from "next/navigation";
|
||||||
|
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { CONFIG_NAV_GROUPS } from "@/modules/config/config-nav-model";
|
import { CONFIG_NAV_GROUPS } from "@/modules/config/config-nav-model";
|
||||||
import { configHubMeta } from "@/modules/config/meta";
|
|
||||||
|
|
||||||
function navLinkActive(pathname: string, href: string): boolean {
|
function navLinkActive(pathname: string, href: string): boolean {
|
||||||
return pathname === href || pathname.startsWith(`${href}/`);
|
return pathname === href || pathname.startsWith(`${href}/`);
|
||||||
@@ -15,20 +13,6 @@ function navLinkActive(pathname: string, href: string): boolean {
|
|||||||
|
|
||||||
export function ConfigWorkspaceShell({ children }: { children: ReactNode }) {
|
export function ConfigWorkspaceShell({ children }: { children: ReactNode }) {
|
||||||
const pathname = usePathname() ?? "";
|
const pathname = usePathname() ?? "";
|
||||||
const activeNav = useMemo(() => {
|
|
||||||
for (const group of CONFIG_NAV_GROUPS) {
|
|
||||||
for (const item of group.items) {
|
|
||||||
if (navLinkActive(pathname, item.href)) {
|
|
||||||
return { group, item };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}, [pathname]);
|
|
||||||
|
|
||||||
const title = activeNav?.item.title ?? configHubMeta.title;
|
|
||||||
const description = activeNav?.item.description || configHubMeta.description;
|
|
||||||
const groupLabel = activeNav?.group.label ?? "总览";
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto flex w-full max-w-7xl flex-col gap-6">
|
<div className="mx-auto flex w-full max-w-7xl flex-col gap-6">
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export function WalletConfigDocScreen() {
|
|||||||
setDraft(d);
|
setDraft(d);
|
||||||
setSaved(d);
|
setSaved(d);
|
||||||
setDirty(false);
|
setDirty(false);
|
||||||
} catch (e) {
|
} catch {
|
||||||
toast.error("加载失败");
|
toast.error("加载失败");
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -78,7 +78,9 @@ export function WalletConfigDocScreen() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
queueMicrotask(() => {
|
||||||
void load();
|
void load();
|
||||||
|
});
|
||||||
}, [load]);
|
}, [load]);
|
||||||
|
|
||||||
const handleChange = (field: keyof Draft, value: string) => {
|
const handleChange = (field: keyof Draft, value: string) => {
|
||||||
@@ -96,8 +98,8 @@ export function WalletConfigDocScreen() {
|
|||||||
toast.success("保存成功");
|
toast.success("保存成功");
|
||||||
setSaved(draft);
|
setSaved(draft);
|
||||||
setDirty(false);
|
setDirty(false);
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
toast.error(e instanceof LotteryApiBizError ? e.message : "保存失败");
|
toast.error(error instanceof LotteryApiBizError ? error.message : "保存失败");
|
||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user