diff --git a/README.md b/README.md index 943e4d6..8f72864 100644 --- a/README.md +++ b/README.md @@ -1,225 +1,89 @@ # Antd Admin -Balanced admin monorepo: MSW mocks, minimal RBAC, full CRUD, and Playwright E2E — built with React 19, Ant Design 6, and Vite+. Ship either an **English-only** app (`apps/basic`) or a **Lingui i18n** variant (`apps/with-lingui`); see [Templates](#templates) below. +A practical admin monorepo with two production-style templates, mock-first development, and test coverage. -[antd](https://github.com/ant-design/ant-design) -[react](https://react.dev) -[vite](https://viteplus.dev) -[TypeScript](https://www.typescriptlang.org/) -[GitHub issues](https://github.com/zuiidea/antd-admin/issues) -[GitHub stars](https://github.com/zuiidea/antd-admin/stargazers) -[License](http://opensource.org/licenses/MIT) -[PRs Welcome](https://github.com/zuiidea/antd-admin/pulls) +- **`apps/basic`**: English-only setup +- **`apps/with-lingui`**: Bilingual setup (`en` + `zh`) with Lingui +- **`apps/docs`**: Nextra documentation site +- **`packages/create`**: `init-antd-admin` scaffolding CLI + +## Links + +- [Ant Design](https://github.com/ant-design/ant-design) +- [React](https://react.dev) +- [Vite+](https://viteplus.dev) +- [TypeScript](https://www.typescriptlang.org/) +- [Issues](https://github.com/zuiidea/antd-admin/issues) +- [Stars](https://github.com/zuiidea/antd-admin/stargazers) +- [PRs Welcome](https://github.com/zuiidea/antd-admin/pulls) +- [License (MIT)](http://opensource.org/licenses/MIT) ## Tech Stack +| Category | Technology | +| --- | --- | +| Build tool | [Vite+](https://viteplus.dev) | +| UI | [Ant Design 6.x](https://ant.design) | +| Routing | [TanStack Router](https://tanstack.com/router) | +| Async state | [TanStack Query v5](https://tanstack.com/query) | +| Local state | [Zustand](https://zustand.docs.pmnd.rs) | +| Validation | [Zod v4](https://zod.dev) | +| i18n | [LinguiJS](https://lingui.dev) in `apps/with-lingui` | +| Mocking | [MSW 2.x](https://mswjs.io) | +| E2E tests | [Playwright](https://playwright.dev) | +| Language | TypeScript 5.9 (strict) | -| Category | Technology | -| ------------ | ------------------------------------------------------------------------------------------------------- | -| Build Tool | [Vite+](https://viteplus.dev) (VoidZero unified toolchain) | -| UI Framework | [Ant Design 6.x](https://ant.design) | -| Routing | [TanStack Router](https://tanstack.com/router) (file-based, type-safe) | -| Async State | [TanStack Query v5](https://tanstack.com/query) | -| Local State | [Zustand](https://zustand.docs.pmnd.rs) (persisted auth & settings) | -| Validation | [Zod v4](https://zod.dev) (schemas, API contracts, form validation) | -| i18n | [LinguiJS](https://lingui.dev) in `**apps/with-lingui` only** (`apps/basic` is English-only, no Lingui) | -| Icons | [lucide-react](https://lucide.dev/guide/packages/lucide-react) | -| API Mocking | [MSW 2.x](https://mswjs.io) (Service Worker based) | -| E2E Testing | [Playwright](https://playwright.dev) | -| Language | TypeScript 5.9 (strict mode) | +## Highlights - -## Features - -- **JWT Authentication** — Login with access/refresh token flow, persisted via Zustand -- **Dynamic Menu & RBAC** — Backend-driven sidebar menu with permission guards and 403 page -- **URL-First State** — Table search params (page, pageSize, keyword, sort) synced to URL -- **i18n (with-lingui app)** — LinguiJS with English (`en`) and Chinese (`zh`); Ant Design locales follow the active locale in `apps/with-lingui` -- **Dark Mode** — One-click toggle with Ant Design theme algorithm -- **Full Type Safety** — Zod schemas validate API boundaries at runtime where used -- **Zero-Config Mocking** — MSW intercepts API calls in development, no backend needed +- JWT login with access/refresh flow +- Backend-driven menu and permission guards +- URL-synced table state (pagination, sorting, search) +- Dark mode theme switching +- Mock-first local development (no backend required) +- Typed API boundaries and reusable CRUD patterns ## Templates -`npx init-antd-admin@latest` · `pnpm dlx init-antd-admin@latest` +| Template | Use when | +| --- | --- | +| `with-lingui` | You need multilingual UI (`en` + `zh`) and Lingui workflow | +| `basic` | You need a simpler English-only setup | +## `init-antd-admin` Usage -| Directory | Use when | -| ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | -| `[apps/with-lingui](./apps/with-lingui/)` | You want **LinguiJS** (en + zh), `.po` extract/compile, and a language switcher — this is the fuller reference stack. | -| `[apps/basic](./apps/basic/)` | You want the **same product surface** with **English-only** UI (no Lingui, fixed `en_US` for Ant Design). | +Use the scaffolding CLI to create a standalone app from official templates. - -Pick one app directory, install, and run Vite+ from there: +### Interactive ```bash -cd apps/basic && vp install && vp dev -# or -cd apps/with-lingui && vp install && vp dev +npx init-antd-admin@latest +pnpm dlx init-antd-admin@latest +yarn dlx init-antd-admin@latest +bunx init-antd-admin@latest ``` -### 文档站(Nextra) - -中文使用文档位于 `**apps/docs**`(Next.js + Nextra)。在仓库根或该目录安装依赖后: +### Non-interactive examples ```bash -cd apps/docs && pnpm install && pnpm dev +pnpm dlx init-antd-admin@latest my-app --example basic -m pnpm +pnpm dlx init-antd-admin@latest my-app --example with-lingui --skip-install ``` -浏览器打开 [http://localhost:3000](http://localhost:3000)。模板 Vite+ 应用仍为 [http://localhost:5173](http://localhost:5173)。开发与构建命令说明见 `[apps/docs/README.md](./apps/docs/README.md)`。 +### Common options -Core Playwright flows (from the app you are working in): +| Option | Description | +| --- | --- | +| `[project-directory]` | Target folder | +| `-e, --example ` | Template source | +| `--example-path ` | Subpath inside remote repository | +| `-m, --package-manager ` | `npm` / `pnpm` / `yarn` / `bun` | +| `--skip-install` | Skip dependency install | +| `--skip-transforms` | Skip rewrite transforms | +| `--no-git` | Skip git initialization | -```bash -cd apps/basic && pnpm run test:e2e:core -``` - -### Git hooks - -提交前检查由仓库根目录 **`.githooks/pre-commit`** 按暂存路径分发到各子项目(在对应目录执行 `vp staged`,避免在仓库根找不到 `vite.config.ts`)。一次性启用: - -```bash -pnpm run setup:git-hooks -``` - -说明见 [.githooks/README.md](./.githooks/README.md)。模板目录内的 `.vite-hooks` 仍保留给模板单独拷贝使用;在本仓库开发请使用上述根级钩子。 - -## Getting Started - -### Prerequisites - -- [Node.js](https://nodejs.org) >= 20 -- [Vite+](https://viteplus.dev/guide/) CLI (`vp`) - -### Install & Run - -From the repository root, choose an app under `apps/` (see [Templates](#templates)), then: - -```bash -cd apps/with-lingui # or: cd apps/basic -vp install -vp dev -``` - -Open [http://localhost:5173](http://localhost:5173) — you'll be redirected to the login page. - -**Default credentials:** `admin` / `admin` - -### Build - -```bash -vp build -vp preview -``` - -### E2E Tests - -Run from the app package (example: `apps/basic`): - -```bash -cd apps/basic -pnpm run test:e2e -pnpm run test:e2e:core -pnpm run test:e2e:ui # interactive UI mode -``` - -`test:e2e:core` runs the scaffold's highest-value flows only: login and users CRUD. - -## Project Structure - -``` -src/ -├── api/ # Zod schemas, endpoint constants, type exports -│ ├── schemas.ts # Domain models (User, AuthTokens, MenuItem, etc.) -│ ├── auth.ts # Auth endpoint constants -│ └── user.ts # User CRUD endpoint constants -├── components/ -│ ├── Aurora/ # Login background effect -│ ├── Auth/ # Auth (permission gate): index.tsx -│ ├── DataTable/ # Shared table shell, skeleton, empty state -│ ├── FilterToolbar/ # Shared filter/action toolbar -│ ├── FormModal/ # Reusable modal + form shell -│ ├── Icon/ # Shared icons and theme toggle icon -│ └── Layout/ # Admin shell (sidebar, header, main) -│ ├── MainLayout/ # Main layout shell: index.tsx -│ ├── AppFooter/ # Login footer: Powered by + GitHub → zuiidea/antd-admin -│ ├── Sidebar/ # Dynamic menu sidebar: index.tsx -│ ├── UserMenu/ # User dropdown in sidebar: index.tsx + index.css -│ └── Header/ # Top bar: index.tsx -├── hooks/ -│ ├── tokenBuilders.ts # Shared Ant Design token/config builders -│ ├── useAppTheme.ts # Theme selection hook (ConfigProvider) -│ ├── usePermission.ts # Permission check hook -│ └── useResourceCRUD.ts # Shared CRUD query/mutation wiring -├── utils/ -│ ├── constants.ts # API base URL, static assets -│ └── http.ts # HTTP client with JWT injection & error handling -├── locales/ # LinguiJS catalogs (.po + compiled .js) -│ ├── en/messages.po -│ └── zh/messages.po -├── mocks/ -│ ├── browser.ts # MSW worker setup -│ ├── createHandler.ts # Shared MSW success/error/delay helpers -│ ├── data.ts # Mock seed data (users, menus) -│ ├── utils.ts # Mock-only helpers (filters, pagination, demo avatar URLs) -│ └── handlers/ # Request handlers (auth, user CRUD) -├── routes/ # TanStack Router file-based routes -│ ├── __root.tsx # Root layout (QueryClient, ConfigProvider, I18n) -│ ├── _auth.tsx # Auth guard layout (redirects to /login) -│ ├── _auth/dashboard/index.tsx -│ ├── _auth/users/index.tsx # Full CRUD with URL-synced search params -│ ├── _auth/403/index.tsx -│ ├── login/index.tsx -│ ├── 404/index.tsx -│ └── index.tsx # Redirects / → /login -├── stores/ -│ ├── auth.ts # Auth store (tokens, user, menus, permissions) -│ ├── createPersistentStore.ts # Shared persisted-store factory -│ └── settings.ts # Settings store (darkMode, locale, sidebar) -└── main.tsx # Entry point (MSW init → React render) - -tests/ -└── e2e/ # Playwright E2E tests - ├── helpers.ts - ├── login.spec.ts - └── users.spec.ts -``` - -## Internationalization (i18n) - -The project uses [LinguiJS](https://lingui.dev) with compile-time macros. Locales: `**en**` (source) and `**zh**`. - -### Workflow - -```bash -vp run i18n:extract -vp run i18n:compile -``` - -Ant Design strings follow the active locale via `ConfigProvider` in `__root.tsx`. - -## Extending the template - -- **Real backend:** Point `VITE_API_BASE_URL` in env and disable or remove MSW in `main.tsx` when you no longer need mocks. -- **Drop i18n:** Remove Lingui packages, vite/swc plugins, and replace `t` macros with plain strings (larger refactor). - -## Developer Notes - -- Prefer Vite+ commands for installs, checks, and scripts. This repo is configured around `vp`. -- Run `vp check --no-fmt` for type/lint validation. -- Core regression coverage lives in the login and users E2E flows. - -## Pages - - -| Route | Description | -| ------------ | ----------------------------------------------------------- | -| `/login` | Login form with validation | -| `/dashboard` | Statistics overview cards | -| `/users` | User CRUD table with search, pagination, create/edit/delete | -| `/403` | Forbidden error page | -| `/404` | Not found error page | +For package-specific details, see [`packages/create/README.md`](./packages/create/README.md). +Production docs: [https://antd-admin-doc.zuiidea.top](https://antd-admin-doc.zuiidea.top) ## License diff --git a/packages/create/README.md b/packages/create/README.md index b3e11fa..c11620d 100644 --- a/packages/create/README.md +++ b/packages/create/README.md @@ -28,17 +28,17 @@ pnpm dlx init-antd-admin@latest my-app --example basic --skip-install ### CLI options -| Option | Description | -| -------------------------- | ----------------------------------------------------- | -| `[project-directory]` | Target folder (relative path or `.`; empty dirs only) | -| `-e, --example ` | Example id from the built-in list, or a template URL | -| `--example-path ` | Extra path inside the repo when using a URL | -| `-m, --package-manager` | `npm` \| `yarn` \| `pnpm` \| `bun` | -| `--skip-install` | Do not run install after scaffold | -| `--skip-transforms` | Skip rewrites (e.g. `package.json` name) | -| `--no-git` | Do not run `git init` | -| `-v, --version` | Print CLI version | -| `-h, --help` | Print help | +| Option | Description | +| ----------------------- | ----------------------------------------------------- | +| `[project-directory]` | Target folder (relative path or `.`; empty dirs only) | +| `-e, --example ` | +| `--example-path ` | Extra path inside the repo when using a URL | +| `-m, --package-manager` | `npm` | `yarn` | `pnpm` | `bun` | +| `--skip-install` | Do not run install after scaffold | +| `--skip-transforms` | Skip rewrites (e.g. `package.json` name) | +| `--no-git` | Do not run `git init` | +| `-v, --version` | Print CLI version | +| `-h, --help` | Print help | Run `init-antd-admin --help` for the full help text. @@ -74,14 +74,14 @@ Design and implementation notes live under `docs/specs/` in the monorepo (e.g. ` CI workflow: `.github/workflows/publish-init-antd-admin.yml` in the monorepo (open on GitHub from the default branch). -1. Add repository secret **`NPM_TOKEN`** (npm automation or granular token with publish permission for `init-antd-admin`). -2. Bump **`version`** in this directory’s `package.json`, commit, then either: - - **Actions → “Publish init-antd-admin” → Run workflow**, or - - Push tag **`init-antd-admin-v`** (e.g. `init-antd-admin-v1.0.3` must match `package.json` version `1.0.3`). -3. Push a matching **`v`** tag on the monorepo (e.g. `v1.0.3`) if users rely on the default template ref `v${version}` from the CLI. +1. Add repository secret `**NPM_TOKEN**` (npm automation or granular token with publish permission for `init-antd-admin`). +2. Bump `**version**` in this directory’s `package.json`, commit, then either: + - **Actions → “Publish init-antd-admin” → Run workflow**, or + - Push tag `**init-antd-admin-v`** (e.g. `init-antd-admin-v1.0.3` must match `package.json` version `1.0.3`). +3. Push a matching `**v**` tag on the monorepo (e.g. `v1.0.3`) if users rely on the default template ref `v${version}` from the CLI. If **provenance** publish fails from your machine, publish from CI (this workflow passes `--provenance`) or see [npm provenance docs](https://docs.npmjs.com/generating-provenance-statements). ## License -MIT (same as the parent repository). +MIT (same as the parent repository). \ No newline at end of file