Files
languard-servers-manager/frontend
Tran G. (Revernomad) Khoa d45345a094 feat: fix mods tab, add client/server split, and scaffold server dirs
Mods tab bug fixes:
- mod_manager: fix wrong kwargs in set_enabled_mods, fix scan dir to use
  mods/ subdir instead of server root, migrate old string-list format to
  dict format on read
- service: replace dead server_mods SQL JOIN with get_enabled_mods()
  call through the mod_manager capability; pass is_server_mod to
  build_mod_args
- mods_router: accept list[EnabledModEntry] objects (name + is_server_mod)
  instead of bare strings

Client/server mod split:
- Mods now stored as list[{"name": str, "is_server_mod": bool}]; old
  string-list format auto-migrated on read
- is_server_mod=true routes to -serverMod= arg; false to -mod= arg
- ModList UI: amber Client/Server badge in selected pane; toggle button
  in split-pane selector

Directory scaffold:
- process_config: adds "mods" to dir layout; provides get_dir_readme()
  with per-directory README.txt content
- file_utils: ensure_server_dirs() gains readme_provider kwarg; writes
  README.txt idempotently if absent
- service.create_server: passes readme_provider via hasattr probe
- main.py startup: backfills all existing servers with correct subdirs
  and README files (idempotent)

Docs: API.md and FRONTEND.md updated for new mod schema and types
Test __init__.py files added for pytest discovery
2026-04-20 10:54:56 +07:00
..

Languard Server Manager — Frontend

React 19 + TypeScript + Vite frontend for the Languard game server management panel.

Stack

  • React 19 with hooks
  • TypeScript strict mode
  • Vite dev server + build
  • TanStack Query for server state (all API calls)
  • Zustand for client state (auth, UI notifications)
  • react-hook-form + Zod for form validation
  • Tailwind CSS with custom neumorphic design tokens
  • Vitest for unit tests

Dev Server

# From this directory
npx vite --host
# → http://localhost:5173

Tests

npx vitest run          # run once
npx vitest              # watch mode
npx tsc --noEmit        # type check only

Project Structure

src/
├── components/
│   ├── layout/         # Sidebar
│   ├── servers/        # ServerCard, ConfigEditor, PlayerTable, MissionList, ModList, LogViewer, BanTable
│   ├── settings/       # PasswordChange, UserManager
│   └── ui/             # StatusLed, (planned) TagListEditor, ConfirmModal
├── hooks/
│   ├── useServers.ts       # Dashboard server list + start/stop/restart mutations
│   ├── useServerDetail.ts  # All per-server queries and mutations
│   ├── useAuth.ts
│   └── useWebSocket.ts     # Real-time events (logs, status changes)
├── pages/
│   ├── LoginPage.tsx
│   ├── DashboardPage.tsx
│   ├── ServerDetailPage.tsx
│   ├── CreateServerPage.tsx
│   └── SettingsPage.tsx
├── store/
│   ├── auth.store.ts   # JWT + user role
│   └── ui.store.ts     # Notification queue
└── lib/
    ├── api.ts          # Axios instance with JWT interceptor + 401 redirect
    └── logger.ts

CSS Conventions

Custom utility classes defined in src/index.css (do not add new CSS files):

Class Use
neu-card Card surface with neumorphic raised shadow
neu-input Input with recessed shadow
btn-primary Amber accent button
btn-ghost Text-only button with hover background
btn-danger Red destructive button

Tailwind design tokens in tailwind.config.js: surface-{base,raised,recessed,overlay}, text-{primary,secondary,muted}, status-{running,stopped,crashed,starting,restarting}, accent.