feat(basic): remove Lingui bootstrap and English shell (batch A)

Made-with: Cursor
This commit is contained in:
zuiidea
2026-04-14 20:55:52 +08:00
parent b47e932d92
commit b6f98b71b1
18 changed files with 102 additions and 845 deletions
@@ -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}
+3 -5
View File
@@ -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>
}