docs
React frontend
Operational guide for the React + Vite + Tauri UI workspace.
React frontend (Tauri 2)
Operational guide for the Kefer desktop UI (React + Vite + Tauri).
Prerequisites
- Node.js (see team
.nvmrcor local convention). - Rust toolchain for
cargo tauri build/cargo tauri dev. - Python sidecar: built binary expected at
src-tauri/binaries/kefer-backend(see Tauribundle.resourcesinsrc-tauri/tauri.conf.json).
Workspace DuckDB storage (currently off)
The duckdb crate and src-tauri/src/storage/duckdb.rs were removed to avoid heavy native builds during UI work. src-tauri/src/commands/storage.rs still exposes the same Tauri commands (init_storage, query_positions, etc.); they are no-ops or return empty lists (see file header). Chart data still flows through YAML + Python compute; only the DuckDB time-series layer is inactive. To restore, re-add the duckdb dependency, bring back storage/duckdb.rs from version control history, and wire commands/storage.rs to DuckDBStorage again.
Commands
npm install
npm run dev # Vite only, http://localhost:1420
npm run tauri dev # Desktop app with hot reload
npm run build # Frontend → apps/web-react/dist/
npm run tauri build # Full app bundle
npm run check # TypeScript (app + vite config)
npm run lint # Prettier + ESLint
npm run i18n:sync # Regenerate `apps/web-react/src/locales/*.json` from `translations.csv`
Layout
| Path | Purpose |
|---|---|
apps/web-react/src/main.tsx | React root; mounts <App /> and <Toaster /> (sonner). |
apps/web-react/src/app/App.tsx | Main shell: sidebar, views, workspace open/save handlers. |
apps/web-react/src/app/components/ | Feature components and the shared React UI layer. Prefer the Radix/shadcn-style primitives under ui/. |
apps/web-react/src/styles/ | index.css → Tailwind 4, theme tokens, fonts. |
apps/web-react/src/lib/tauri/ | Tauri bridge: types, chart payloads, workspace helpers. |
static/ (repo root) | Shared public assets: app-shell/**, glyphs/**, favicon.png. Used by Vite publicDir and copied into dist/ on build. |
apps/web-react/src/locales/ | i18n JSON (cs, en, fr, es) — generated from translations.csv; imported by the app (not served from static/). |
apps/web-react/src/lib/i18n/ | i18next init, LANGUAGE_STORAGE_KEY (kefer-language in localStorage). |
UI component strategy
- Prefer the existing shadcn-style primitives in
apps/web-react/src/app/components/ui/before building custom controls. - Styling work should usually happen through tokens, variants, composition, and shared wrappers.
- Reach for bespoke component CSS only when the shared component layer cannot express the needed behavior.
Internationalization (i18n)
Do you need JSON under static/? No. Locale files live in apps/web-react/src/locales/ and are bundled by Vite, which works offline in Tauri and avoids extra fetch / CSP concerns. Reserve repo root static/ (shared across frontends) for assets you reference by URL (glyphs, favicon).
- Source of truth: repo root
translations.csv(columnsinternal_name,czech,english,french,spanish). In a collaborative setup, maintain the sheet in Google Sheets, then File → Download → CSV (or a scheduled export) and replacetranslations.csvin the repo. - Regenerate JSON:
npm run i18n:syncrunsscripts/csv-to-locales.mjs, which writes the same four locale files to every path listed inlocaleOutputDirs(React and Svelte today). One command keeps all frontends on the same keys and strings. - Staying in sync: After updating the CSV, run
npm run i18n:syncand commit bothtranslations.csvand the generated**/locales/*.json. Optionally add CI that fails if someone edits JSON by hand without syncing, or that runs the script and checks for a cleangit diff. - Runtime:
react-i18next+i18next; wrap is inapps/web-react/src/main.tsx(I18nextProvider). UseuseTranslation()andt('key')wherekeyisinternal_namefrom the CSV. - Settings UI:
apps/web-react/src/app/components/settings-view.tsx— language, location, house system, aspects, appearance, manual, plus Cancel / Confirm footer. Language is stored underkefer-language; glyph set choice writesglyph_setinlocalStorage. Other fields are UI state until workspace/theme hooks are ported. Open settings from the sidebar’s last main nav item (translatedsettings). - Conventions: See ui-conventions for the full i18n workflow and transits/settings layout notes.
Tauri bridge (apps/web-react/src/lib/tauri/)
types.ts— TypeScript shapes aligned with commoninvokeresponses (workspace, chart details, compute result).chartPayload.ts—AppChart, workspace defaults,chartDataToComputePayload()(JSON shape expected bysave_workspace).workspace.ts—openFolderDialog,loadWorkspace,initStorage,getWorkspaceDefaults,getChartDetails,computeChart,saveWorkspace, andopenWorkspaceFolder()(full open flow: load charts, init storage, compute each chart).
Wired in the UI
In App.tsx, sidebar actions:
- Otevřít (
otevrit) — runsopenWorkspaceFolder()afteropen_folder_dialog; merges workspace defaults; stores charts in React state; toasts success/failure. - Uložit (
ulozit) — if there are in-memory charts, saves viasave_workspace+init_storage; prompts for folder when noworkspacePathyet.
Other views (horoscope dashboard, transits, aspectarium) are still mostly presentational until you thread charts / computed state into them.
Shared static assets
Keep shared source assets under repo-root static/. apps/web-react points Vite publicDir at that folder, so assets are copied into the app build and resolved through the active Vite base path.
Current source-of-truth layout:
static/app-shell/icons/default/*.svgstatic/app-shell/icons/modern/*.svgstatic/app-shell/logo-full-*.svgstatic/app-shell/logo-mark-*.svgstatic/glyphs/default/planets/*.svgstatic/glyphs/default/zodiac/*.svgstatic/glyphs/classic/planets/*.svgstatic/glyphs/classic/zodiac/*.svg
For docs builds, the app is published under /apps/web-react/, so shared asset URLs must be based on import.meta.env.BASE_URL rather than hard-coded root-absolute paths.
Example glyph paths:
<img src={`${import.meta.env.BASE_URL}glyphs/default/planets/sun.svg`} alt="" />
<img src={`${import.meta.env.BASE_URL}glyphs/classic/zodiac/aries.svg`} alt="" />
Do not rely on old dist/ copies for source of truth; dist/ is build output and is gitignored.
Theming
- App-level themes (
sunrise|noon|twilight|midnight) are local React state inApp.tsxand the sidebar. Main content backgrounds (including twilight image and midnight radial) live inApp.tsx; sidebar and secondary rails sharesidebarThemeStylesexported fromapps/web-react/src/app/components/astrology-sidebar.tsx(see ui-conventions). apps/web-react/src/styles/theme.cssholds CSS variables for shadcn-style components.apps/web-react/index.htmlincludes a small script to setdarkon<html>fromlocalStorage/prefers-color-schemefor future use.sonner:apps/web-react/src/app/components/ui/sonner.tsxdoes not usenext-themes; it uses thedarkclass on<html>for toast theme.
Figma / Make export fixes
figma:asset/....png style imports are replaced with @/assets/....png (Vite resolves @ → apps/web-react/src/). PNG files live in apps/web-react/src/assets/.
TypeScript strictness
apps/web-react/tsconfig.app.json uses noUnusedLocals: false and noUnusedParameters: false to keep the large UI tree building cleanly. Tighten these when you refactor unused Figma placeholders.
Related backend docs
- architecture — workspace YAML, DuckDB, command responsibilities.
- integration-examples —
invokeexamples (@tauri-apps/api/core; same from React).