diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..7f8943e --- /dev/null +++ b/.env.example @@ -0,0 +1,14 @@ +# API origin. Leave empty for same-origin/local Vite proxy. +VITE_API_URL= + +# Reown / WalletConnect project id. Required for WalletConnect QR/mobile login. +VITE_WALLETCONNECT_PROJECT_ID= + +# Public production deploy disables admin routes. +VITE_DISABLE_ADMIN=false + +# Admin-only build mode. +VITE_ADMIN_ONLY=false + +# Optional admin UI base path. Leave empty to use default app behavior. +VITE_ADMIN_UI_PREFIX= diff --git a/.pi/skills/arkie-frontend-onboarding/SKILL.md b/.pi/skills/arkie-frontend-onboarding/SKILL.md new file mode 100644 index 0000000..d0eae46 --- /dev/null +++ b/.pi/skills/arkie-frontend-onboarding/SKILL.md @@ -0,0 +1,62 @@ +--- +name: arkie-frontend-onboarding +description: Onboard an AI agent to the Arkie Library frontend repo. Use when starting work in this repository, checking branch/deploy rules, or refreshing project context before coding. +--- + +# Arkie Frontend Onboarding + +Use this skill before making non-trivial changes in the Arkie Library frontend repo. + +## 1. Read project context + +Read these files in order: + +1. `README.md` +2. `AGENTS.md` +3. `docs/workflow.md` +4. `docs/deploy.md` if the task touches deploy, CI, environment variables, or `main` branch pushes. + +## 2. Check current git state + +Run: + +```bash +git status --short --branch +git branch --show-current +``` + +Rules: + +- `main` is the production deploy branch. +- `terry-staging` is the staging/work branch. +- Do not commit or push unless Terry explicitly asks. + +## 3. Recall memory + +Search project memory for relevant context before decisions, especially for: + +- branch/deploy workflow +- frontend conventions +- admin UI behavior +- TypeScript/format failures +- prior fixes touching the same files + +## 4. Validate before finishing + +For code changes, run: + +```bash +npx tsc --noEmit +npm run format:check +``` + +Run `npm run build` when changes affect routes, config, build, deploy, env vars, or dependencies. + +## 5. Report clearly + +Summarize: + +- files changed +- commands run and results +- current branch/status +- whether anything needs pull/push/deploy diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..143b393 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,76 @@ +# AI Agent Instructions + +This file is the first-stop context for AI coding agents working in this repo. + +## Repository identity + +- Project: Arkie Library Frontend / ARK database web UI. +- Package name: `ark-database-web`. +- Stack: React 18, TypeScript, Vite, Tailwind CSS, React Router, RainbowKit/Wagmi. +- Backend API is expected at `/api`; uploaded assets under `/uploads`. + +## Branch rules + +- Current deploy branch: `main`. +- Work/staging branch available: `terry-staging`. +- Do not commit or push unless Terry explicitly asks. +- Pushing to `main` triggers production frontend deploy via Gitea Actions. +- Before branch-changing or pulling, run `git status --short --branch` and preserve local work. + +## Required checks + +Before proposing a push or deploy, run: + +```bash +npx tsc --noEmit +npm run format:check +``` + +If code formatting is needed, run: + +```bash +npm run format +``` + +Notes: + +- `tsconfig.json` has `strict`, `noUnusedLocals`, and `noUnusedParameters`; unused imports fail CI. +- `dist/` is build output and should not be edited manually. + +## App structure quick map + +- `src/main.tsx` chooses normal app vs admin-only build using `VITE_ADMIN_ONLY`. +- `src/App.tsx` contains public routes and conditionally exposes admin routes unless `VITE_DISABLE_ADMIN === "true"`. +- `src/api.ts` defines `apiBase`, fetch helpers, and shared resource/category types. +- `src/i18n.tsx` contains all UI copy for `zh-TW`, `zh-CN`, and `en`. +- `src/pages/admin/` contains admin UI screens. +- `src/adminPaths.ts` handles admin path prefix logic. Keep it in sync with backend/nginx admin host config if changed. + +## Environment variables + +See `.env.example` and `README.md` for details. Do not commit real secrets or private deployment keys. + +Common production public build env: + +```bash +VITE_API_URL=https://api.ark-library.com +VITE_DISABLE_ADMIN=true +``` + +## Deployment context + +`.gitea/workflows/deploy.yml` deploys on push to `main`: + +1. `npm ci` +2. `npx tsc --noEmit` +3. `npm run format:check` +4. `npm run build` with production public env +5. rsync `dist/` to both frontend servers +6. compare remote `index.html` checksums + +## Agent behavior preferences + +- Answer Terry in concise Chinese unless the task requires code/docs in English. +- Prefer small, direct fixes over broad refactors. +- Update README/docs/memory when learning non-obvious project facts. +- Search existing project memory before making decisions about workflow, deploy, or conventions. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5167314 --- /dev/null +++ b/README.md @@ -0,0 +1,95 @@ +# Arkie Library Frontend + +React + Vite frontend for the ARK Library / ARK database site. The app serves public resource browsing, search, favorites, wallet login UI, and an optional admin UI for resource management. + +## Tech stack + +- React 18 + TypeScript +- Vite 5 +- React Router +- Tailwind CSS +- RainbowKit / Wagmi / Viem for wallet connection +- Gitea Actions deploy workflow on `main` + +## Quick start + +```bash +npm ci +npm run dev +``` + +Local dev server: + +In development, Vite proxies these paths to the backend at `http://127.0.0.1:8080`: + +- `/api` +- `/uploads` + +If `VITE_API_URL` is set, API calls use that absolute base URL instead. + +## Useful commands + +```bash +npm run dev # start Vite dev server +npx tsc --noEmit # TypeScript check; CI requires this +npm run format:check # Prettier check; CI requires this +npm run format # format source files +npm run build # production build to dist/ +npm run preview # preview built app locally +``` + +Before pushing, run at least: + +```bash +npx tsc --noEmit +npm run format:check +``` + +## Environment variables + +Create a local `.env` only when needed. Do not commit secrets. See `.env.example` for a template. + +| Variable | Purpose | +| --- | --- | +| `VITE_API_URL` | API/upload origin. Empty means same-origin and Vite dev proxy handles local `/api` and `/uploads`. Production deploy currently uses `https://api.ark-library.com`. | +| `VITE_WALLETCONNECT_PROJECT_ID` | Reown / WalletConnect project id. Needed for QR/mobile wallet connection. | +| `VITE_DISABLE_ADMIN` | When set to `"true"`, public build redirects admin routes away. Production public deploy sets this to `"true"`. | +| `VITE_ADMIN_ONLY` | When set to `"true"`, builds the admin-only app entry instead of the public app. | +| `VITE_ADMIN_UI_PREFIX` | Optional admin UI base path. If absent in admin-only mode, code uses the secret prefix from `src/adminPaths.ts`. | + +## Project layout + +```text +src/ + main.tsx # app entry; switches public vs admin-only build + App.tsx # public app + optional admin routes + AppAdminOnly.tsx # admin-only app entry + api.ts # fetch helpers and shared API types + i18n.tsx # zh-TW / zh-CN / en copy dictionary + adminPaths.ts # admin UI prefix logic + adminRouteTree.tsx # admin routes + components/ # reusable public components + layouts/ # public/admin layout shells + pages/ # public pages + pages/admin/ # admin pages + utils/ # formatting/display helpers +``` + +Important config files: + +- `vite.config.ts` — Vite build and local backend proxy. +- `tailwind.config.js` — ARK color palette and font stack. +- `Dockerfile` / `nginx.conf` — container build and static SPA serving. +- `.gitea/workflows/deploy.yml` — deploys `main` to both frontend servers. + +## Branch and deploy workflow + +- `main` is the deploy branch. Pushing to `main` triggers `.gitea/workflows/deploy.yml`. +- `terry-staging` exists as a staging/work branch for later work. +- The deploy workflow runs `npm ci`, `npx tsc --noEmit`, `npm run format:check`, `npm run build`, then rsyncs `dist/` to both frontend servers and verifies matching checksums. + +See also: + +- `AGENTS.md` — instructions for AI coding agents. +- `docs/workflow.md` — recommended day-to-day workflow. +- `docs/deploy.md` — deploy details and troubleshooting. diff --git a/docs/deploy.md b/docs/deploy.md new file mode 100644 index 0000000..9425cda --- /dev/null +++ b/docs/deploy.md @@ -0,0 +1,75 @@ +# Deployment + +Production frontend deploy is handled by Gitea Actions in `.gitea/workflows/deploy.yml`. + +## Trigger + +A push to `main` triggers the deploy workflow. + +```yaml +on: + push: + branches: + - main +``` + +## CI/deploy steps + +1. Checkout code. +2. Install dependencies with `npm ci`. +3. Type check with `npx tsc --noEmit`. +4. Check formatting with `npm run format:check`. +5. Build with `npm run build` using: + + ```bash + VITE_API_URL=https://api.ark-library.com + VITE_DISABLE_ADMIN=true + ``` + +6. Configure SSH key from `DEPLOY_KEY` secret. +7. `rsync --delete` built `dist/` to both frontend servers: + + ```text + ec2-user@FRONTEND_1_HOST:/var/www/ark-library/ + ec2-user@FRONTEND_2_HOST:/var/www/ark-library/ + ``` + +8. Verify both servers have matching `index.html` SHA-256 checksums. +9. Remove temporary SSH key. + +## Required repository secrets + +The workflow expects these Gitea secrets: + +- `DEPLOY_KEY` +- `FRONTEND_1_HOST` +- `FRONTEND_2_HOST` + +## Common failures + +### TypeScript fails on unused imports + +This repo uses `noUnusedLocals` and `noUnusedParameters`. Remove unused imports/variables and rerun: + +```bash +npx tsc --noEmit +``` + +### Format check fails + +Run: + +```bash +npm run format +npm run format:check +``` + +Then commit the formatting changes. + +### Build uses wrong API + +Check `VITE_API_URL` in `.gitea/workflows/deploy.yml` or local `.env`. + +### One frontend server differs from the other + +The workflow compares remote `index.html` checksums. If it fails, inspect the rsync step and both `FRONTEND_*_HOST` values. diff --git a/docs/workflow.md b/docs/workflow.md new file mode 100644 index 0000000..41aa722 --- /dev/null +++ b/docs/workflow.md @@ -0,0 +1,83 @@ +# Development Workflow + +This repo is intentionally simple: make changes, validate locally, then push only when ready. + +## Start a session + +```bash +git status --short --branch +git fetch origin main +``` + +If working on staging: + +```bash +git switch terry-staging +git pull --ff-only +``` + +If working directly on production deploy branch: + +```bash +git switch main +git pull --ff-only origin main +``` + +## Make changes + +Use the existing structure: + +- Public pages: `src/pages/` +- Admin pages: `src/pages/admin/` +- Shared components: `src/components/` +- API helpers/types: `src/api.ts` +- Translations/copy: `src/i18n.tsx` +- Display helpers: `src/utils/` + +Avoid editing generated `dist/` files. + +## Validate + +Run: + +```bash +npx tsc --noEmit +npm run format:check +npm run build +``` + +For formatting fixes: + +```bash +npm run format +``` + +## Commit + +Check the diff first: + +```bash +git diff +git status --short +``` + +Use concise commits, for example: + +```bash +git add +git commit -m "fix: remove unused imports" +``` + +## Push + +Only push when Terry asks. + +```bash +git push origin main +``` + +or for staging: + +```bash +git push origin terry-staging +```