mirror of
https://github.com/zuiidea/antd-admin
synced 2026-10-29 04:14:12 +00:00
feat(basic): remove Lingui bootstrap and English shell (batch A)
Made-with: Cursor
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { Flex, theme } from "antd";
|
||||
import { useLingui } from "@lingui/react/macro";
|
||||
import { BarChart3 } from "lucide-react";
|
||||
import type { ReactElement } from "react";
|
||||
|
||||
@@ -7,7 +6,6 @@ import type { ReactElement } from "react";
|
||||
* Table empty state: icon in soft tile + bold title + secondary description (dashboard-style).
|
||||
*/
|
||||
export function DataTableEmpty(): ReactElement {
|
||||
const { t } = useLingui();
|
||||
const { token } = theme.useToken();
|
||||
|
||||
return (
|
||||
@@ -46,7 +44,7 @@ export function DataTableEmpty(): ReactElement {
|
||||
lineHeight: token.lineHeightLG,
|
||||
}}
|
||||
>
|
||||
{t`No data`}
|
||||
No data
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
@@ -56,7 +54,7 @@ export function DataTableEmpty(): ReactElement {
|
||||
lineHeight: token.lineHeight,
|
||||
}}
|
||||
>
|
||||
{t`Nothing to show in this list yet`}
|
||||
Nothing to show in this list yet
|
||||
</span>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { Flex, Typography, theme } from "antd";
|
||||
import { useLingui } from "@lingui/react/macro";
|
||||
import { GitHub } from "@/components/Icon";
|
||||
|
||||
const ANTD_ADMIN_REPO = "https://github.com/zuiidea/antd-admin";
|
||||
|
||||
export function AppFooter() {
|
||||
const { token } = theme.useToken();
|
||||
const { t } = useLingui();
|
||||
const iconSize = Math.max(12, Math.round(Number(token.fontSizeSM)));
|
||||
|
||||
return (
|
||||
@@ -20,7 +18,7 @@ export function AppFooter() {
|
||||
}}
|
||||
>
|
||||
<Typography.Text type="secondary" style={{ fontSize: token.fontSizeSM, marginBottom: 0 }}>
|
||||
{t`Powered by`}
|
||||
Powered by
|
||||
</Typography.Text>
|
||||
<a
|
||||
href={ANTD_ADMIN_REPO}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { Layout, Button, Space, theme, Breadcrumb, Flex, Divider, Grid } from "antd";
|
||||
import type { ItemType } from "antd/es/breadcrumb/Breadcrumb";
|
||||
import { useLingui } from "@lingui/react/macro";
|
||||
import { useSettingsStore, type Locale } from "@/stores/settings";
|
||||
import { useSettingsStore } from "@/stores/settings";
|
||||
import { Link, useLocation, useMatches } from "@tanstack/react-router";
|
||||
import { Home, Languages, PanelLeft, ShieldAlert, Users } from "lucide-react";
|
||||
import { Home, PanelLeft, ShieldAlert, Users } from "lucide-react";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import type { ReactNode } from "react";
|
||||
import { Theme } from "@/components/Icon";
|
||||
@@ -32,11 +31,8 @@ export type HeaderProps = {
|
||||
export function Header({ showBreadcrumb: showBreadcrumbProp = true }: HeaderProps) {
|
||||
const toggleSidebar = useSettingsStore((s) => s.toggleSidebar);
|
||||
const toggleDarkMode = useSettingsStore((s) => s.toggleDarkMode);
|
||||
const locale = useSettingsStore((s) => s.locale);
|
||||
const setLocale = useSettingsStore((s) => s.setLocale);
|
||||
const location = useLocation();
|
||||
const matches = useMatches();
|
||||
const { t } = useLingui();
|
||||
const { token } = theme.useToken();
|
||||
const screens = Grid.useBreakpoint();
|
||||
const isMobile = !screens.lg;
|
||||
@@ -74,14 +70,7 @@ export function Header({ showBreadcrumb: showBreadcrumbProp = true }: HeaderProp
|
||||
const leafIcon: LucideIcon =
|
||||
firstSegmentPath === "/users" ? Users : firstSegmentPath === "/403" ? ShieldAlert : Home;
|
||||
|
||||
const leafLabel =
|
||||
leafLabelKey === "Dashboard"
|
||||
? t`Dashboard`
|
||||
: leafLabelKey === "Users"
|
||||
? t`Users`
|
||||
: leafLabelKey === "403"
|
||||
? t`403`
|
||||
: leafLabelKey;
|
||||
const leafLabel = leafLabelKey;
|
||||
|
||||
const breadcrumbItems: ItemType[] = [];
|
||||
|
||||
@@ -89,11 +78,11 @@ export function Header({ showBreadcrumb: showBreadcrumbProp = true }: HeaderProp
|
||||
|
||||
if (onDashboard) {
|
||||
breadcrumbItems.push({
|
||||
title: crumb(Home, t`Dashboard`),
|
||||
title: crumb(Home, "Dashboard"),
|
||||
});
|
||||
} else {
|
||||
breadcrumbItems.push({
|
||||
title: crumb(Home, t`Dashboard`, "/dashboard"),
|
||||
title: crumb(Home, "Dashboard", "/dashboard"),
|
||||
});
|
||||
|
||||
breadcrumbItems.push({
|
||||
@@ -113,11 +102,6 @@ export function Header({ showBreadcrumb: showBreadcrumbProp = true }: HeaderProp
|
||||
const showBreadcrumb =
|
||||
showBreadcrumbProp && !hideBreadcrumbFromRoute && breadcrumbItems.length > 0;
|
||||
|
||||
const toggleLocale = () => {
|
||||
const next: Locale = locale === "en" ? "zh" : "en";
|
||||
setLocale(next);
|
||||
};
|
||||
|
||||
return (
|
||||
<AntHeader
|
||||
style={{
|
||||
@@ -135,7 +119,7 @@ export function Header({ showBreadcrumb: showBreadcrumbProp = true }: HeaderProp
|
||||
size="small"
|
||||
onClick={toggleSidebar}
|
||||
icon={<PanelLeft size={token.size} />}
|
||||
aria-label={t`Toggle sidebar`}
|
||||
aria-label="Toggle sidebar"
|
||||
/>
|
||||
) : null}
|
||||
{showBreadcrumb ? (
|
||||
@@ -146,17 +130,11 @@ export function Header({ showBreadcrumb: showBreadcrumbProp = true }: HeaderProp
|
||||
) : null}
|
||||
</Flex>
|
||||
<Space>
|
||||
<Button
|
||||
type="text"
|
||||
onClick={toggleLocale}
|
||||
icon={<Languages size={token.size} />}
|
||||
aria-label={t`Switch language`}
|
||||
/>
|
||||
<Button
|
||||
type="text"
|
||||
onClick={toggleDarkMode}
|
||||
icon={<Theme size={token.size} />}
|
||||
aria-label={t`Toggle Theme`}
|
||||
aria-label="Toggle Theme"
|
||||
/>
|
||||
</Space>
|
||||
</AntHeader>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { Menu, Layout, theme, Flex, Grid, Drawer, Button } from "antd";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useNavigate, useLocation } from "@tanstack/react-router";
|
||||
import { useLingui } from "@lingui/react/macro";
|
||||
import { msg } from "@lingui/core/macro";
|
||||
import {
|
||||
Book,
|
||||
Briefcase,
|
||||
@@ -26,14 +24,14 @@ import { UserMenu } from "../UserMenu";
|
||||
import "./index.css";
|
||||
|
||||
const { Sider } = Layout;
|
||||
/** API menu `name` → Lingui descriptors (extracted into catalogs). */
|
||||
const MENU_LABELS: Record<string, ReturnType<typeof msg>> = {
|
||||
Platform: msg`Platform`,
|
||||
Projects: msg`Projects`,
|
||||
Dashboard: msg`Dashboard`,
|
||||
Users: msg`Users`,
|
||||
"Design Engineering": msg`Design Engineering`,
|
||||
"Sales & Marketing": msg`Sales & Marketing`,
|
||||
/** API menu `name` → English labels for known keys; unknown keys pass through as `menu.name`. */
|
||||
const MENU_LABELS: Record<string, string> = {
|
||||
Platform: "Platform",
|
||||
Projects: "Projects",
|
||||
Dashboard: "Dashboard",
|
||||
Users: "Users",
|
||||
"Design Engineering": "Design Engineering",
|
||||
"Sales & Marketing": "Sales & Marketing",
|
||||
};
|
||||
|
||||
type AntMenuItem = Required<MenuProps>["items"][number];
|
||||
@@ -64,7 +62,6 @@ function renderMenuIcon(icon: string | null, size = 16) {
|
||||
|
||||
function buildMenuItems(
|
||||
menus: MenuItemType[],
|
||||
t: ReturnType<typeof useLingui>["t"],
|
||||
token: ReturnType<typeof theme.useToken>["token"],
|
||||
collapsed = false,
|
||||
iconSize = 16,
|
||||
@@ -76,11 +73,11 @@ function buildMenuItems(
|
||||
const items: AntMenuItem[] = [];
|
||||
|
||||
for (const menu of sorted) {
|
||||
const label = MENU_LABELS[menu.name] ? t(MENU_LABELS[menu.name]) : menu.name;
|
||||
const label = MENU_LABELS[menu.name] ?? menu.name;
|
||||
const key = menu.id;
|
||||
|
||||
if (menu.kind === "group") {
|
||||
const built = buildMenuItems(menu.children, t, token, collapsed, iconSize, parentKeys);
|
||||
const built = buildMenuItems(menu.children, token, collapsed, iconSize, parentKeys);
|
||||
Object.assign(keyToPath, built.keyToPath);
|
||||
Object.assign(pathToKeyChain, built.pathToKeyChain);
|
||||
if (built.items.length > 0) {
|
||||
@@ -131,7 +128,7 @@ function buildMenuItems(
|
||||
|
||||
let children: AntMenuItem[] | undefined;
|
||||
if (menu.children?.length) {
|
||||
const built = buildMenuItems(menu.children, t, token, collapsed, iconSize, nextParents);
|
||||
const built = buildMenuItems(menu.children, token, collapsed, iconSize, nextParents);
|
||||
Object.assign(keyToPath, built.keyToPath);
|
||||
Object.assign(pathToKeyChain, built.pathToKeyChain);
|
||||
children = built.items.length ? built.items : undefined;
|
||||
@@ -157,14 +154,13 @@ export function Sidebar() {
|
||||
const toggleSidebar = useSettingsStore((s) => s.toggleSidebar);
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const { t } = useLingui();
|
||||
const { token } = theme.useToken();
|
||||
const screens = Grid.useBreakpoint();
|
||||
const isMobile = !screens.lg;
|
||||
const mobileOpen = collapsed;
|
||||
const builtMenu = useMemo(
|
||||
() => buildMenuItems(menus, t, token, !isMobile && collapsed, token.size),
|
||||
[menus, t, token, isMobile, collapsed, token.size],
|
||||
() => buildMenuItems(menus, token, !isMobile && collapsed, token.size),
|
||||
[menus, token, isMobile, collapsed, token.size],
|
||||
);
|
||||
const { selectedKey, routeOpenKeys } = useMemo(() => {
|
||||
const chain = builtMenu.pathToKeyChain[location.pathname] ?? [];
|
||||
@@ -191,7 +187,7 @@ export function Sidebar() {
|
||||
const userMenuItems: MenuProps["items"] = [
|
||||
{
|
||||
key: "logout",
|
||||
label: t`Sign Out`,
|
||||
label: "Sign Out",
|
||||
onClick: () => {
|
||||
if (isMobile) {
|
||||
setSidebarCollapsed(false);
|
||||
@@ -265,7 +261,7 @@ export function Sidebar() {
|
||||
className="sidebar-collapsed-brand__toggle"
|
||||
onClick={toggleSidebar}
|
||||
icon={<PanelLeft size={token.size} />}
|
||||
aria-label={t`Toggle sidebar`}
|
||||
aria-label="Toggle sidebar"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -313,7 +309,7 @@ export function Sidebar() {
|
||||
size="small"
|
||||
onClick={toggleSidebar}
|
||||
icon={<PanelLeft size={token.size} />}
|
||||
aria-label={t`Toggle sidebar`}
|
||||
aria-label="Toggle sidebar"
|
||||
style={{ flexShrink: 0 }}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
import { useLingui } from "@lingui/react/macro";
|
||||
import { ArrowLeft, Home, SearchX } from "lucide-react";
|
||||
import { Button, Flex, Result, Space, theme } from "antd";
|
||||
|
||||
/** Shared 404 UI for `/404` route and root `notFoundComponent`. */
|
||||
export function NotFound() {
|
||||
const navigate = useNavigate();
|
||||
const { t } = useLingui();
|
||||
const { token } = theme.useToken();
|
||||
|
||||
const goDashboard = () => {
|
||||
@@ -52,14 +50,14 @@ export function NotFound() {
|
||||
<SearchX size={64} strokeWidth={1.25} color={token.colorTextQuaternary} aria-hidden />
|
||||
}
|
||||
title="404"
|
||||
subTitle={t`Sorry, the page you visited does not exist.`}
|
||||
subTitle="Sorry, the page you visited does not exist."
|
||||
extra={
|
||||
<Space wrap size="middle">
|
||||
<Button type="primary" icon={<Home size={16} aria-hidden />} onClick={goDashboard}>
|
||||
{t`Back to Home`}
|
||||
Back to Home
|
||||
</Button>
|
||||
<Button icon={<ArrowLeft size={16} aria-hidden />} onClick={goBack}>
|
||||
{t`Go back`}
|
||||
Go back
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user