Files
coconut-leaf/frontend

coleaf-frontend

The web frontend of coconut-leaf — a light, self-hosted, multi-account calendar system. This package is a from-scratch rewrite of the legacy JavaScript + jQuery frontend (frontend-legacy/) on a modern toolchain.

Tech Stack

  • Framework: Vue 3 (<script setup> + TypeScript)
  • Build tool: Vite
  • State management: Pinia (with pinia-plugin-persistedstate)
  • Routing: Vue Router (navigation guards + per-route window titles)
  • Internationalization: vue-i18n (en-US / zh-CN, message files under src/locales/)
  • Styling: Bulma 0.9 (imported via SCSS) + Font Awesome icons
  • Linting: oxlint + ESLint

Requires Node ^20.19 or >=22.12 (see package.jsonengines).

Project Layout

src/
├── api/          # backend client (fetch-based apiWrapper + typed endpoints)
├── components/   # reusable UI (calendar/, collection/, todo/, admin/, DateTimePicker, MessageBox)
├── locales/      # i18n messages (enUS.ts, zhCN.ts)
├── router/       # route table + beforeEach guard (auth check + document.title)
├── stores/       # Pinia stores (token, language)
├── utils/        # datetime recurrence engine, i18n bootstrap, helpers
└── views/        # page-level views (Home, Login, Collection, Todo, Calendar, CalendarEvent, Admin, NotFound)

Development Server

vite.config.ts is preconfigured:

  • base: '/web/' — matches the /web prefix routed by the production Nginx.
  • Dev port: 5173, opens /web/ on start.
  • API proxy: /api/<path>http://127.0.0.1:8848/<path> (the local backend), with the /api prefix stripped on the fly.

Start the backend (listening on 127.0.0.1:8848) before launching the frontend.

Project Setup

pnpm install

Compile and Hot-Reload for Development

pnpm dev

Type-Check, Compile and Minify for Production

pnpm build

Lint with ESLint

pnpm lint

Internationalization

  • Translation strings live in src/locales/enUS.ts and src/locales/zhCN.ts (keys omit the legacy ccn-i18n- prefix).
  • The active language is held in the Pinia language store (persisted under the ccn-i18n localStorage key) and synced to i18n.global.locale via a watcher in src/App.vue.
  • Switch languages from the navbar dropdown; all visible text — including the window title (driven by each route's meta.title) — updates immediately.

License

Source code is licensed under AGPL v3. See the repository root for details.