RE
React + Ant Design Frontend
Complete guide for the SE104_VLEAGUE React frontend — pages, services, components, auth flow, i18n, and patterns
Install
mkdir -p .claude/skills/react-ant-design-frontend && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/13899" && unzip -o skill.zip -d .claude/skills/react-ant-design-frontend && rm skill.zipInstalls to .claude/skills/react-ant-design-frontend
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Complete guide for the SE104_VLEAGUE React frontend — pages, services, components, auth flow, i18n, and patterns112 charsno explicit “when” trigger
About this skill
React + Ant Design Frontend Skill
Tech Stack
| Category | Package | Version |
|---|---|---|
| UI Framework | React | 19.x |
| Component Library | Ant Design | 6.x |
| Routing | react-router-dom | 7.x |
| HTTP Client | Axios | 1.x |
| i18n | i18next + react-i18next | 25.x/16.x |
| Charts | Recharts | 3.x |
| Date | dayjs | 1.x |
| PDF Export | jsPDF + jspdf-autotable | 4.x/5.x |
| Error Tracking | @sentry/react | 10.x |
| Build | Vite | 7.x |
| Test | Vitest + @testing-library/react | 4.x/16.x |
| TypeScript | 5.9 |
Project Structure
apps/web/src/
├── App.tsx # Root routing (public + protected routes)
├── main.tsx # Entry: Sentry, i18n, BrowserRouter, AuthProvider, ThemeProvider
├── auth/ # AuthContext, RequireAuth, RequireRole, auth.types
├── components/ # Shared: ErrorBoundary, EventModal, ExportButton, ImageUpload, LoadingSkeleton, ScoreEditModal
├── lib/
│ ├── api.ts # Axios instance with token refresh interceptor
│ └── i18n.ts # i18next config (vi/en, localStorage detection)
├── locales/
│ ├── vi.ts # Vietnamese translations (~1,244 lines)
│ └── en.ts # English translations (~1,207 lines)
├── pages/ # All page components (PascalCase)
│ ├── __tests__/ # Page component tests
│ ├── match-detail/ # MatchDetailPage sub-components
│ └── reports/ # ReportsPage tab sub-components
├── services/ # API service modules (camelCase)
│ └── __tests__/ # Service tests
├── shell/
│ ├── AppShell.tsx # Protected layout (Sider + Header + Content)
│ ├── PublicLayout.tsx # Public layout (gradient header + footer)
│ ├── ThemeContext.tsx # Dark/light mode context
│ └── menu.ts # Role-based menu items (12 items)
└── utils/
└── constants.ts # STATUS_MAP, EVENT_TYPE_MAP, POSITION_MAP, CAN_EDIT_ROLES
All Pages & Routes
Public (No Auth)
| Route | Component | Load | Description |
|---|---|---|---|
/login | LoginPage | Eager | Email/password + Google/Facebook OAuth |
/register | RegisterPage | Eager | Registration with password rules |
/verify-email | VerifyEmailPage | Lazy | OTP email verification with resend |
/forgot-password | ForgotPasswordPage | Lazy | Request password reset OTP |
/reset-password | ResetPasswordPage | Lazy | Reset password with OTP |
/auth/oauth-callback | OAuthCallbackPage | Eager | OAuth redirect token processing |
/403 | ForbiddenPage | Eager | Access denied |
* | NotFoundPage | Lazy | 404 fallback |
Public Layout (PublicLayout)
| Route | Component | Description |
|---|---|---|
/public/standings | PublicStandingsPage | League table (no auth) |
/public/schedule | PublicSchedulePage | Schedule by round (no auth) |
/public/results | PublicResultsPage | Finished results (no auth) |
Protected (RequireAuth + AppShell)
| Route | Component | Roles | Description |
|---|---|---|---|
/ | DashboardPage | All | Stats cards, mini standings, upcoming/recent matches, season progress |
/teams | TeamsPage | All | CRUD team list with search, logo, stadium link |
/teams/:id | TeamDetailPage | All | Team info, roster, match history, standings |
/players | PlayersPage | All | CRUD player list, pagination, filters, CSV import |
/players/:id | PlayerDetailPage | All | Bio, stats (goals/cards), event timeline, goals-by-round chart |
/stadiums | StadiumsPage | ADMIN (guard) | CRUD stadium list — wrapped in RequireRole |
/stadiums/:id | StadiumDetailPage | ADMIN (guard) | Stadium info, home teams, match history — wrapped in RequireRole |
/schedule | SchedulePage | All | Generate/publish schedule, edit match details, grouped by round |
/seasons | SeasonsPage | ADMIN (guard) | CRUD seasons, team registration panel — wrapped in RequireRole |
/matches | MatchesPage | All | Match list by round, detail modal, score edit, events, status transitions |
/matches/:id | MatchDetailPage | All | Scoreboard, events timeline, roster tabs, stat cards |
/standings | StandingsPage | All | Full standings with AFC CL/relegation highlights, top scorers, CSV export |
/head-to-head | HeadToHeadPage | All | Compare two teams — wins/draws/goals + match history |
/regulations | RegulationsPage | ADMIN (guard) | CRUD regulations per season, seed defaults — wrapped in RequireRole |
/reports | ReportsPage | All | Tabs: Top Scorers, Card Stats, Team Stats, Charts — PDF/CSV export |
/users | UsersPage | ADMIN (guard) | User management (create/role/delete) — wrapped in RequireRole |
/profile | ProfilePage | All | View/edit profile, logout all |
/change-password | ChangePasswordPage | All | Change password form |
/sessions | SessionsPage | All | Active sessions, revoke individual/all |
All Services & API Methods
authApi.ts (17 functions)
| Function | Method | Endpoint |
|---|---|---|
apiLogin | POST | /auth/login |
apiRefresh | POST | /auth/refresh |
apiLogout | POST | /auth/logout |
apiRegister | POST | /auth/register |
apiVerifyEmail | POST | /auth/verify-email |
apiResendOtp | POST | /auth/resend-otp |
apiForgotPassword | POST | /auth/forgot-password |
apiResetPassword | POST | /auth/reset-password |
apiGetMe | GET | /auth/me |
apiChangePassword | POST | /auth/change-password |
apiLogoutAll | POST | /auth/logout-all |
apiUpdateProfile | PATCH | /auth/profile |
apiGetSessions | GET | /auth/sessions |
apiRevokeSession | DELETE | /auth/sessions/:id |
apiSetPassword | POST | /auth/set-password |
getGoogleAuthUrl | — | Returns /auth/google URL |
getFacebookAuthUrl | — | Returns /auth/facebook URL |
teamApi.ts
| Function | Method | Endpoint |
|---|---|---|
apiGetTeams | GET | /teams?page&limit&search&status |
apiGetTeam | GET | /teams/:id |
apiCreateTeam | POST | /teams |
apiUpdateTeam | PATCH | /teams/:id |
apiDeleteTeam | DELETE | /teams/:id |
apiGetStadiums | GET | /stadiums |
playerApi.ts
| Function | Method | Endpoint |
|---|---|---|
apiGetPlayers | GET | /players?page&limit&search&position&nationality&teamId |
apiGetPlayer | GET | /players/:id |
apiCreatePlayer | POST | /players |
apiUpdatePlayer | PATCH | /players/:id |
apiDeletePlayer | DELETE | /players/:id |
apiImportPlayersCsv | POST | /players/import (multipart FormData) |
stadiumApi.ts
| Function | Method | Endpoint |
|---|---|---|
apiGetStadiums | GET | /stadiums |
apiGetStadium | GET | /stadiums/:id |
apiCreateStadium | POST | /stadiums |
apiUpdateStadium | PATCH | /stadiums/:id |
apiDeleteStadium | DELETE | /stadiums/:id |
seasonApi.ts
| Function | Method | Endpoint |
|---|---|---|
apiGetSeasons | GET |
Content truncated.