From 3c990e5ab6f2695caf8947fe0e5402cca12e3d8b Mon Sep 17 00:00:00 2001 From: Tuan-Dat Tran Date: Sat, 22 Nov 2025 00:05:50 +0100 Subject: [PATCH] feat: Implement live editing (HTMX) and refine UI hierarchy Integrates HTMX for real-time updates of Experience and Education forms in the admin dashboard, eliminating full page reloads on save and enabling instant addition of new entries. Adjusted the visual prominence of 'Role' in Experience and 'Degree' in Education sections. Fixes: - Corrected database query parameter passing, resolving text field clearing issue on save. - Enabled live 'Add New' functionality for Experience and Education entries. --- GEMINI.md | 85 +++++++++++++++++ src/components/AdminForms.tsx | 75 +++++++++++++++ src/components/BaseHtml.tsx | 1 + src/components/Sections.tsx | 11 +-- src/db/queries.ts | 27 ++++++ src/routes/admin.tsx | 169 +++++++++++----------------------- 6 files changed, 249 insertions(+), 119 deletions(-) create mode 100644 GEMINI.md create mode 100644 src/components/AdminForms.tsx diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..e2e01e4 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,85 @@ +# Project Context: ElysiaJS CV Website + +## Project Overview +This project is a high-performance, server-side rendered (SSR) CV/Portfolio website built on the **Bun** runtime using **ElysiaJS**. It features a custom Content Management System (CMS) for managing multi-language content (English/German) and uses **SQLite** for data persistence. Authentication for the CMS is handled via **Keycloak** (OpenID Connect) using the **Arctic** library. + +## Key Technologies +* **Runtime:** [Bun](https://bun.sh/) +* **Web Framework:** [ElysiaJS](https://elysiajs.com/) +* **Templating:** JSX via `@kitajs/ts-html-plugin` / `typed-html` +* **Database:** `bun:sqlite` (Native SQLite driver) +* **Authentication:** [Arctic](https://arctic.js.org/) (OIDC Client) + [Keycloak](https://www.keycloak.org/) (Identity Provider) +* **Styling:** [TailwindCSS](https://tailwindcss.com/) +* **Testing:** `bun:test` + +## Architecture + +### Directory Structure +* `src/components`: Reusable UI components (e.g., `Layout.tsx`, `Sections.tsx`). +* `src/db`: Database logic. + * `schema.ts`: Table definitions. + * `queries.ts`: Read operations (including Admin data fetchers). + * `mutations.ts`: Write operations (Admin actions). + * `seed.ts`: Initial data population script. +* `src/routes`: Route handlers. + * `public.tsx`: Public-facing CV pages (`/:lang`). + * `admin.tsx`: Protected CMS routes (`/admin/*`) and Auth flows. +* `src/index.tsx`: Main application entry point and server configuration. +* `tests`: Unit tests (currently covering DB queries). + +### Database Schema +The database uses a "Translation Table" pattern to support i18n: +* **Structural Tables:** `profile`, `experience`, `education`, `skills` (contain IDs, dates, URLs, sort order). +* **Translation Tables:** `profile_translations`, `experience_translations`, etc. (contain language-specific text keyed by `language_code` and parent ID). + +### Authentication Flow +1. User visits `/admin/login` -> Redirects to Keycloak Authorization URL. +2. Keycloak validates credentials -> Redirects back to `/admin/callback` with `code`. +3. Server exchanges `code` for tokens using Arctic (PKCE enabled). +4. Session cookie is set. +5. Protected routes check for valid session cookie. + +## Development Workflow + +### Prerequisites +* Bun installed. +* Docker installed (for Keycloak). + +### Setup & Installation +1. **Install Dependencies:** + ```bash + bun install + ``` +2. **Initialize Database:** + ```bash + bun run src/db/seed.ts + ``` +3. **Start Keycloak:** + ```bash + docker compose up -d + ``` + * Admin Console: `http://localhost:8080` (admin/admin) + * *Note:* Ensure a Realm `myrealm` and Client `cv-app` are configured. + +### Running the Application +* **Development Server:** + ```bash + bun run src/index.tsx + ``` + Access at `http://localhost:3000`. + +### Testing +* **Run Unit Tests:** + ```bash + bun test + ``` + +## Configuration +* **Environment Variables:** Managed in `.env` (contains Keycloak secrets and URLs). +* **Tailwind:** Configured in `tailwind.config.js` (includes custom animations like `fade-in`). +* **TypeScript:** Configured in `tsconfig.json` (supports JSX). + +## Conventions +* **Routing:** Always use `return Response.redirect(...)` for redirects in Elysia, not `set.redirect = ...`. +* **Styling:** Use Tailwind utility classes. Dark mode is supported via the `dark:` prefix and a toggler in `Layout.tsx`. +* **Data Access:** Separate Read (`queries.ts`) and Write (`mutations.ts`) logic. diff --git a/src/components/AdminForms.tsx b/src/components/AdminForms.tsx new file mode 100644 index 0000000..9db00d7 --- /dev/null +++ b/src/components/AdminForms.tsx @@ -0,0 +1,75 @@ +import * as elements from "typed-html"; + +export const InputGroup = ({ label, name, value, type = "text", required = false }: any) => ( +
+ + +
+); + +export const TextAreaGroup = ({ label, name, value }: any) => ( +
+ + +
+); + +export const ExperienceForm = ({ exp }: any) => ( +
+
+ + + +
+
+
+
ENGLISH
+ + + +
+
+
GERMAN
+ + + +
+
+
+ {/* Delete button: We use hx-confirm to ask first */} + + +
+ + {/* Success Message Indicator (HTMX can swap this in, but for now just visual feedback on button) */} +
+); + +export const EducationForm = ({ edu }: any) => ( +
+
+ + + +
+
+
+
ENGLISH
+ + + +
+
+
GERMAN
+ + + +
+
+
+ + +
+
+); diff --git a/src/components/BaseHtml.tsx b/src/components/BaseHtml.tsx index ab83c7c..042b8b5 100644 --- a/src/components/BaseHtml.tsx +++ b/src/components/BaseHtml.tsx @@ -8,6 +8,7 @@ export const BaseHtml = ({ children }: elements.Children) => ` CV Website +