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) => ( +