Files
website/README.md
T
2026-09-23 11:44:36 +02:00

3.4 KiB

Diary

A password-protected diary of reviews (books, movies, albums) and notes, built with Nuxt 4 + Nuxt UI on top of two self-hosted Baserow tables.

pnpm install
cp .env.example .env
pnpm dev

Configuration

Variable Purpose
NUXT_BASEROW_URL Baserow instance, no trailing slash
NUXT_BASEROW_TOKEN Database token with read and create access to both tables
NUXT_BASEROW_REVIEWS_TABLE_ID Reviews table
NUXT_BASEROW_NOTES_TABLE_ID Notes table
NUXT_DIARY_PASSWORD Password that unlocks the diary
NUXT_SESSION_SECRET Signs the login cookie, at least 32 characters (openssl rand -hex 32)

In app/app.config.ts, showCovers: true shows a generated title tile next to each review.

What it does

  • / is the only page: reviews and notes on one timeline, newest first, grouped by year.
  • Only entries with text are shown. Long text is collapsed behind "Read more".
  • Search matches every word against the kind (review, note), the medium (book, movie, album), the date (aug 2025, 2025-08), the title, the author and the text. Matches in the text are highlighted.
  • "Log" opens a form with a Note / Review switch.
  • Until the password is entered, only a password prompt is shown and every API route except /api/session and /api/login returns 401. A correct password sets a signed, http-only cookie valid for 30 days. Changing NUXT_SESSION_SECRET logs out every browser.

Code layout

app/
  app.vue                     password gate around the page
  pages/index.vue             the diary page
  components/
    DiaryEntry.vue            one timeline entry (date, title, text, read more)
    LogModal.vue              Note / Review switch around the two forms
    NoteForm.vue, ReviewForm.vue
    PasswordModal.vue
    CoverTile.vue             generated cover, used when showCovers is on
  composables/
    useDiary.ts               loads reviews + notes, searches, sorts and groups them by year
    useSaveEntry.ts           shared submit logic of the forms
    useLog.ts                 open/close state of the Log modal
  utils/                      dates, icons, search highlighting, error messages
  types/entry.ts              a timeline entry (review or note)
server/
  middleware/auth.ts          locks /api/* until unlocked
  api/                        session, login, reviews and notes (GET list, POST create)
  utils/
    baserow.ts                Baserow client: listRows, createRow, listFields
    review.ts, note.ts        Baserow row -> app type
    auth.ts                   session cookie and password check
    validation.ts             readValidBody(event, zodSchema)
shared/
  types/                      Review, Note
  utils/medium.ts             the review media: label and creator label
  utils/schemas.ts            zod schemas used by both forms and API

Baserow tables

Reviews: title, date (ISO date), author_or_director, review (long text) and medium (single select: Book / Movie / Album).

Notes: Datum (date) and Notes (long text).

Rows without a date are skipped. Text is plain text: line breaks are kept and it is never rendered as HTML.

Adding a medium

  1. Add the option to the medium single select in Baserow.
  2. Add it to Medium in shared/types/review.ts, to MEDIUMS in shared/utils/medium.ts (its label must match the Baserow option) and to MEDIUM_ICONS in app/utils/icons.ts.