feat: Implement initial admin and mobile application UI, including styling, layouts, authentication, and legal page components.

This commit is contained in:
Timo Knuth
2026-03-03 16:54:11 +01:00
parent 59f3efaaed
commit b7d826e29c
15 changed files with 265 additions and 33 deletions

View File

@@ -106,6 +106,74 @@ Required in `apps/admin/.env` (see `.env.example`):
- `EXPO_PUBLIC_API_URL` — Mobile points to admin API
- `UPLOAD_DIR` / `UPLOAD_MAX_SIZE_MB` — File storage
## Planned: SQLite → PostgreSQL Migration
The current schema uses **SQLite** (`packages/shared/prisma/schema.prisma`). The migration target is **PostgreSQL** (production-grade, enables JSONB and native arrays).
### What changes in `schema.prisma`
```prisma
datasource db {
provider = "postgresql" // was: "sqlite"
url = env("DATABASE_URL")
}
```
### Fields to convert to `@db.JsonB`
These fields are currently stored as JSON-encoded `String?` in SQLite and must become proper JSONB columns in PostgreSQL:
| Model | Field | Prisma annotation |
|---|---|---|
| `Organization` | `landingPageFeatures` | `@db.JsonB` |
| `Organization` | `landingPageFooter` | `@db.JsonB` |
Example after migration:
```prisma
landingPageFeatures Json? @map("landing_page_features") @db.JsonB
landingPageFooter Json? @map("landing_page_footer") @db.JsonB
```
### Fields to convert to native PostgreSQL arrays
`Organization.sparten` is stored as `String?` (comma-separated or JSON) in SQLite. In PostgreSQL it becomes:
```prisma
sparten String[] @default([])
```
### Migration steps
1. Provision a PostgreSQL instance (Supabase, Neon, or self-hosted via Docker).
2. Set `DATABASE_URL` to a `postgresql://` connection string.
3. Update `schema.prisma`: change `provider`, add `@db.JsonB` and `String[]` types.
4. Run `pnpm db:generate` to regenerate the Prisma client.
5. Create a fresh migration: `pnpm db:migrate` (this creates `packages/shared/prisma/migrations/…`).
6. All code that currently parses `landingPageFeatures` / `landingPageFooter` as `JSON.parse(string)` must switch to reading them directly as objects (Prisma returns them as `unknown` / `JsonValue`).
### Docker Compose (local PostgreSQL)
Add a `postgres` service to `docker-compose.yml`:
```yaml
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: innungsapp
POSTGRES_USER: innungsapp
POSTGRES_PASSWORD: secret
volumes:
- pg_data:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
pg_data:
```
Then set `DATABASE_URL=postgresql://innungsapp:secret@localhost:5432/innungsapp`.
## Key Conventions
- **Styling**: Tailwind CSS in admin; NativeWind v4 (Tailwind syntax) in mobile
@@ -114,3 +182,4 @@ Required in `apps/admin/.env` (see `.env.example`):
- **Icons**: `lucide-react` (admin), `@expo/vector-icons` (mobile)
- **Schema changes**: Always run `pnpm db:generate` after editing `packages/shared/prisma/schema.prisma`
- **tRPC client (mobile)**: configured in `apps/mobile/lib/trpc.ts`, uses `superjson` transformer
- **Enum fields**: Stored as `String` in SQLite (enforced via Zod); after PostgreSQL migration, consider converting to native `enum` types