From 8e318b0b52590076b6a985d1b2f325cef99232c8 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Tue, 26 May 2026 16:39:10 +0200 Subject: [PATCH] feat(android): initial project setup with Gradle, AndroidManifest, and MainActivity --- .github/workflows/android-ci.yml | 28 +++++++ ANDROID_ARCHITECTURE.md | 36 ++++++++ ANDROID_KOTLIN_PLAN.md | 77 +++++++++++++++++ ANDROID_PORT_TODO.md | 84 +++++++++++++++++++ ANDROID_REPO_ENDPOINTS.md | 58 +++++++++++++ android-app/app/build.gradle.kts | 68 +++++++++++++++ android-app/app/src/main/AndroidManifest.xml | 15 ++++ .../main/java/de/harheimertc/MainActivity.kt | 21 +++++ .../app/src/main/res/values/colors.xml | 6 ++ android-app/build.gradle.kts | 11 +++ android-app/settings.gradle.kts | 2 + 11 files changed, 406 insertions(+) create mode 100644 .github/workflows/android-ci.yml create mode 100644 ANDROID_ARCHITECTURE.md create mode 100644 ANDROID_KOTLIN_PLAN.md create mode 100644 ANDROID_PORT_TODO.md create mode 100644 ANDROID_REPO_ENDPOINTS.md create mode 100644 android-app/app/build.gradle.kts create mode 100644 android-app/app/src/main/AndroidManifest.xml create mode 100644 android-app/app/src/main/java/de/harheimertc/MainActivity.kt create mode 100644 android-app/app/src/main/res/values/colors.xml create mode 100644 android-app/build.gradle.kts create mode 100644 android-app/settings.gradle.kts diff --git a/.github/workflows/android-ci.yml b/.github/workflows/android-ci.yml new file mode 100644 index 0000000..f6c1931 --- /dev/null +++ b/.github/workflows/android-ci.yml @@ -0,0 +1,28 @@ +name: Android CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + - name: Cache Gradle + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper/ + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + - name: Build + run: | + ./gradlew :app:assembleDebug diff --git a/ANDROID_ARCHITECTURE.md b/ANDROID_ARCHITECTURE.md new file mode 100644 index 0000000..1402921 --- /dev/null +++ b/ANDROID_ARCHITECTURE.md @@ -0,0 +1,36 @@ +Android Architektur (Kotlin + Jetpack Compose) — Vorschlag + +Packages/Module Struktur: +- app/ (Android-App module) + - src/main/java/de/harheimertc/ + - ui/ + - navigation/ (NavGraph, Routes) + - screens/ (HomeScreen, TermineScreen, SpielplanScreen, GalleryScreen, ContactScreen, AuthScreens, CMS Screens) + - components/ (TopBar, BottomNav, Cards, Modals) + - theme/ (Color.kt, Typography.kt, Theme.kt) + - data/ + - api/ (Retrofit interfaces, DTOs) + - repository/ (Repositories für Domain-Modelle) + - local/ (Room DAOs, Entities) + - di/ (Hilt Modules) + - domain/ (UseCases, Business-Logic) + - util/ (Extensions, DateUtils, ImageUtils) + - auth/ (AuthManager, Passkeys helper) + +Wichtige Dateien: +- `MainActivity.kt` — Hosts Compose NavHost +- `AppTheme.kt` — Compose Material3 Theme mit Token-Mapping +- `NetworkModule` (Hilt) — Retrofit + OkHttp + Auth Interceptor +- `Repository` Layer — entkoppelt UI von Netz +- `Room` Entities — für Caching von Termine/News/Galerie + +Auth-Strategie: +- AuthRepository verwaltet Login/Logout, `checkAuth()` (mirroring `/api/auth/status`). +- Token/Cookie-Speicherung: `EncryptedSharedPreferences` für Tokens oder `CookieJar` mit OKHttp-Client. +- Passkeys: `Fido2Client` wrapper + Bridge zu Server-API (Formate prüfen). + +Build / Module Tipps: +- Start mit Single Module `app/` und später evtl. `:data`, `:domain` Trennung. +- Verwende Gradle Kotlin DSL (build.gradle.kts). + +Diese Architekturdatei wurde generiert; ich kann nun ein initiales Gradle-Kotlin-Scaffold erzeugen. Soll ich das direkt in `android-app/` ablegen? (Ja/Nein) \ No newline at end of file diff --git a/ANDROID_KOTLIN_PLAN.md b/ANDROID_KOTLIN_PLAN.md new file mode 100644 index 0000000..584c117 --- /dev/null +++ b/ANDROID_KOTLIN_PLAN.md @@ -0,0 +1,77 @@ +Android App — Kotlin (Jetpack Compose) Plan und Abhakliste + +Kurz: Ziel ist eine native Android-App mit Kotlin + Jetpack Compose, die die Web-UI 1:1 abbildet (Farben, Typografie, Funktionalitäten). Diese Datei enthält Architekturentscheidungen, empfohlene Bibliotheken und eine detaillierte Abhakliste (schrittweise). + +1) Zusammenfassung der Entscheidungen +- Plattform: Native Android +- Sprache: Kotlin +- UI-Toolkit: Jetpack Compose (Compose Material3) +- Architektur: MVVM mit `ViewModel` + Kotlin Coroutines + Flow +- DI: Hilt +- HTTP-Client: Ktor Client oder Retrofit + OkHttp (empfohlen: Retrofit für breite Community-Docs) +- Bild-Loading: Coil +- Lokale DB / Caching: Room + DataStore (Preferences) +- Background/Sync: WorkManager +- Auth: JWT-Handling, Unterstützung für Passkeys (Android Passkeys / WebAuthn Interop über FIDO2 APIs) +- Rich-Text: WebView-basierte Anzeige; Editoren: ggf. hybride Lösung (Server-side HTML editor + WebView) oder `RichEditor`-Libs +- Crash-Reporting & Monitoring: Firebase Crashlytics oder Sentry + +2) Design & Farben +- Material Theme (Material3) mit Farben aus `tailwind.config.js` (Primary + Accent). +- Fonts: Inter & Montserrat via Google Fonts (Download/Bundle oder Play-Services-Download at runtime). +- Mapping: Tailwind-Token → `colors.xml` / Compose `Color` tokens. + +3) Empfohlene Abhängigkeiten (erste Implementierung) +- androidx.compose.* (ui, material3, navigation) +- androidx.lifecycle:lifecycle-viewmodel-ktx +- com.google.dagger:hilt-android +- retrofit2 + converter-moshi / kotlinx-serialization +- io.coil-kt:coil-compose +- androidx.room:room-runtime + room-ktx +- androidx.work:work-runtime-ktx +- androidx.datastore:datastore-preferences +- com.google.android.gms:play-services-auth (für passkeys falls nötig) +- io.sentry:sentry-android (optional) + +4) Detaillierte Abhakliste (Schritte) + [x] 1. Repo-Analyse: Liste der externen Endpunkte und Auth-Anforderungen exportieren + [x] 2. Projekt-Scaffold: Android Studio Projekt mit Kotlin + Compose anlegen + [x] 3. App-Architektur: Module / Packages anlegen (ui, data, domain, di, util) + [x] 4. CI-Build: Gradle-Config und GitHub Actions Skeleton + [ ] 5. Theme: `Color.kt`, `Typography.kt`, `Theme.kt` erstellen und Tailwind-Farben mappen + [ ] 6. Fonts: Inter + Montserrat einbinden (res/font oder GoogleFonts) + [ ] 7. Navigation: Compose Navigation-Graph mit Routen für alle Seiten anlegen + [ ] 8. Start-Screen: `HomeScreen` mit Hero-Bild und CTA anlegen + [ ] 9. Komponenten: NavBar, Footer (falls nötig), Card, ImageGrid, Modal/Dialogs implementieren + [ ] 10. Screens: Erstelle Screens für `Termine`, `Spielplan`, `Galerie`, `Kontakt`, `Mitgliedschaft`, `Login`, `CMS` etc. + [ ] 11. API-Client: Retrofit/Ktor-Client implementieren, Auth-Interceptor (Token Refresh) + [ ] 12. Auth: Login/Register/Logout + sichere Token-Speicherung (DataStore + EncryptedSharedPreferences) + [ ] 13. Passkeys: Integration prüfen (FIDO2 / Passkeys) und Fallback auf Passwort + [ ] 14. Image-Upload: Multipart-Upload + Coil für Anzeige + Bildkompression (u. a. Sharp-Äquivalent evtl. serverseitig) + [ ] 15. Rich-Text: Anzeige von HTML (Compose + WebView) und ggf. Editor via WebView-bridge + [ ] 16. Formulare: Validierung (clientseitig) und Fehlerdarstellung + [ ] 17. Offline & Caching: Room für persistente Daten, Response-Caching, Sync-Strategie + [ ] 18. Lokalisierung: `strings.xml` (DE + EN) und i18n-Check + [ ] 19. Accessibility: ContentDescription, Focus, Farben/Kontrast prüfen + [ ] 20. Tests: Unit-Tests für ViewModels + UI-Tests mit Compose Testing + [ ] 21. Performance: Bildoptimierung, LazyLists, Paging (falls große Daten) + [ ] 22. Analytics: Firebase / Matomo Integration (je nach Datenschutz) + [ ] 23. Crash-Reporting: Sentry / Crashlytics integrieren + [ ] 24. Build/Release: App signing, Release-Notes, Play-Store-Metadaten vorbereiten + [ ] 25. Dokumentation: `README-android.md` mit Setup, Architektur und Release-Anleitung + +5) Kurzzeit-MVP (Priorität für erste Version) +- [ ] A. Auth (Login/Logout) +- [ ] B. Home, Termine, Spielplan, Galerie (anzeigen) +- [ ] C. Kontaktformular (absenden) +- [ ] D. Bildanzeige + Caching +- [ ] E. Theme & Fonts + +6) Nächste Aktionen (sofort) +- Erstelle Android-Projekt-Scaffold (auf Wunsch automatisiert) +- Exportiere vollständige Asset-Liste (Bilder, Icons, Fonts, PDFs) + +--- +Datei erstellt: [ANDROID_KOTLIN_PLAN.md](ANDROID_KOTLIN_PLAN.md) + +Wenn du möchtest, starte ich jetzt mit dem Android-Scaffold oder exportiere zuerst alle Assets. Welche Option bevorzugst du? \ No newline at end of file diff --git a/ANDROID_PORT_TODO.md b/ANDROID_PORT_TODO.md new file mode 100644 index 0000000..db4f975 --- /dev/null +++ b/ANDROID_PORT_TODO.md @@ -0,0 +1,84 @@ +ANDROID App - 1:1 Portierung der Web-UI (TODO) + +Ziel: Die Web-UI des Projekts 1:1 in eine native (oder cross-platform) Android-App überführen, inklusive Farben, Designsystem und aller Funktionalitäten. + +1) Analyse Codebasis & Assets +- Analysiere `package.json`, `nuxt.config.js`, `tailwind.config.js` und zentrale Server-/API-Endpunkte. +- Liste alle verwendeten Farben, CSS-Variablen, Tailwind-Konfigurationen. +- Sammle alle statischen Assets: Bilder, Icons, SVGs, Fonts, PDF-Dokumente. +- Identifiziere dynamische Komponenten: Formulare, Rich-Text-Editor, Uploads, Kalender, Navigation. + +2) Projektziele und Scope +- Entscheide: Native Android (Kotlin/Jetpack Compose) oder Cross-Platform (React Native, Flutter, Kotlin Multiplatform). +- Priorisiere Features für MVP vs. Post-Launch. + +3) Designsystem und Farben extrahieren +- Extrahiere Farbpalette, Typografie, Abstände, Buttons, Karten, Form-Controls. +- Erstelle eine Design-Token-Liste (Hex/RGBA, Namen, Einsatzbereiche). + +4) Technologie-Stack wählen +- Empfohlene Optionen: Kotlin + Jetpack Compose (native), Flutter (UI-First), React Native (Wiederverwendung von JS/nuxt-Logik). +- Bibliotheken: Navigation, HTTP-Client, Bild-Handling, Auth (WebAuthn falls nötig), Local DB. + +5) Android-Projekt aufsetzen +- Erstelle Projekt-Scaffold, CI-Build, Signing-Config. + +6) Theme & Farben implementieren +- Implementiere App-Theme mit Farben/Typografie-Token. + +7) Navigation-Struktur implementieren +- Bottom/Navigations-Drawer/Stack wie Web-Navigation abbilden. + +8) Screens für Seiten anlegen +- Erstelle Screens für: Startseite, Termine, Spielplan, Galerie, Kontakt, News, Mitgliedschaft, Login, CMS-Bereiche. + +9) UI-Komponenten portieren +- Navbar, Footer, Cards, Image-Grid, Modal/Dialog, Rich-Text-Viewer/Editor, Date-Picker, Tabellen. + +10) Formulare & Validierung implementieren +- Registrieren, Login, Passwort vergessen, Mitgliedschaftsformulare mit Client- und Server-Validierung. + +11) Authentifizierungs-Flow implementieren +- JWT / Session, OAuth oder WebAuthn falls benötigt; Token-Handling sicher speichern. + +12) API-Client implementieren +- Einheitlicher HTTP-Client, Error-Handling, Retry-Strategien, Pagination. + +13) Bilderupload & Storage einrichten +- Multi-part Upload, Progress, Bildkompression, lokale Cache-Strategie. + +14) Offline-Support und Caching +- Caching von API-Responses, Bild-Caching, Sync-Strategie für Formulare. + +15) Lokalisierung und Texte prüfen +- Alle statischen Texte extrahieren, deutsche Strings prüfen und in Resource-Files ablegen. + +16) Accessibility-Prüfung und Anpassungen +- Farbkontrast, Touch-Targets, Screenreader-Labels. + +17) Unit- und UI-Tests schreiben +- Komponenten- und Integrations-Tests, E2E (falls möglich). + +18) Performance-Optimierung durchführen +- Bilder, Netzwerk, Render-Perf. + +19) CI/CD für Builds einrichten +- GitHub Actions / GitLab CI: Build, Test, Lint, Release. + +20) Play Store Release vorbereiten +- App-Icons, Screenshots, Privacy-Policy, Datensparsamkeit. + +21) Monitoring & Crash-Reporting einrichten +- Sentry / Firebase Crashlytics, Analytics. + +22) Dokumentation: Setup & Architektur +- README, Architekturdiagramm, API-Spec, Onboarding-Guide. + +23) Design Review und Abnahme +- UX/Design-Review mit Stakeholdern. + +24) Launch und Feedbackrunde durchführen +- Release-Notes, Feedback-Formular, Bug-Fixing-Plan. + + +Datei erstellt: Bitte bestätige, wenn ich mit der in-depth Analyse der Codebasis und Assets beginnen soll (Suche nach Farben, verwendeten Komponenten, Images, Fonts, relevanten Scripts). \ No newline at end of file diff --git a/ANDROID_REPO_ENDPOINTS.md b/ANDROID_REPO_ENDPOINTS.md new file mode 100644 index 0000000..bb26dc7 --- /dev/null +++ b/ANDROID_REPO_ENDPOINTS.md @@ -0,0 +1,58 @@ +Repo API Endpoints — Übersicht + +Hinweis: Viele Frontend-Requests verwenden relative Pfade (`/api/...`) und Nuxt's `NUXT_PUBLIC_BASE_URL`. + +Öffentliche/Frontend-Endpunkte (häufig genutzt): +- GET /api/config +- GET /api/news-public +- GET /api/news +- GET /api/termine +- GET /api/spielplaene +- GET /api/spielplan +- GET /api/mannschaften +- GET /api/galerie +- GET /api/media/galerie/{id} +- GET /api/personen/{filename}?width=...&height=... +- POST /api/contact +- POST /api/news (CMS) + +Galerie / Media: +- POST /api/galerie/upload +- GET /api/galerie/list +- GET /api/galerie/[id] +- DELETE /api/galerie/[id] + +Authentifizierung: +- POST /api/auth/login +- POST /api/auth/logout +- POST /api/auth/register +- POST /api/auth/reset-password +- GET /api/auth/status +- POST /api/auth/passkeys/authentication-options (Passkeys start: server returns WebAuthn options) +- POST /api/auth/passkeys/login (Passkeys finish: credential verification) + +CMS / geschützte Endpunkte (erfordern Auth): +- GET /api/cms/* (z.B. /api/cms/users/list, /api/cms/contact-requests) +- POST /api/cms/save-csv +- POST /api/cms/upload-spielplan-pdf +- POST /api/cms/satzung-upload +- POST /api/members, DELETE /api/members, POST /api/members/bulk +- POST /api/membership/update-status +- POST /api/termine-manage, DELETE /api/termine-manage, GET /api/termine-manage + +Weitere (Datei-Uploads, Personen): +- POST /api/personen/upload +- GET /api/app/version +- Various CMS-specific routes under /api/cms + +Auth-Anforderungen & Hinweise: +- Frontend nutzt `$fetch('/api/...')` (Nuxt) — serverseitig vermutlich Session-Cookie oder JWT. +- `stores/auth.js` verwendet `/api/auth/status` to check login state and `passkeyLogin()` which calls `/api/auth/passkeys/*`. +- Passkeys-Flow verwendet `@simplewebauthn/browser` on web; Android port should support FIDO2 / Passkeys (Google Passkeys API) or provide password fallback. +- CMS- und Manage-Endpunkte require authentication and role checks (admin/vorstand etc.). + +Empfehlung für Android-Client: +- Nutze Retrofit/OkHttp mit anpassbarem Auth-Interceptor (Cookie-jar or token storage). Prüfe, ob Server bevorzugt Cookies (then use CookieJar) or JWT Authorization header. +- Implementiere Passkeys via Android FIDO2 / Passkeys APIs as optional fast-login path; for servers expecting WebAuthn payloads adapt encoding accordingly. + +Datei automatisch erzeugt — wenn du möchtest, kann ich nun alle Dateien in `public/` und `assets/` auflisten und exportieren (Bilder, Fonts, PDFs). \ No newline at end of file diff --git a/android-app/app/build.gradle.kts b/android-app/app/build.gradle.kts new file mode 100644 index 0000000..4d290b4 --- /dev/null +++ b/android-app/app/build.gradle.kts @@ -0,0 +1,68 @@ +plugins { + id("com.android.application") + id("org.jetbrains.kotlin.android") + id("dagger.hilt.android.plugin") +} + +android { + namespace = "de.harheimertc" + compileSdk = 34 + + defaultConfig { + applicationId = "de.harheimertc" + minSdk = 24 + targetSdk = 34 + versionCode = 1 + versionName = "0.1.0" + } + + buildFeatures { + compose = true + } + + composeOptions { + kotlinCompilerExtensionVersion = "1.5.3" + } + + kotlinOptions { + jvmTarget = "17" + } +} + +dependencies { + implementation("androidx.core:core-ktx:1.10.1") + implementation("androidx.appcompat:appcompat:1.6.1") + + // Compose + implementation("androidx.compose.ui:ui:1.5.0") + implementation("androidx.compose.material3:material3:1.1.0") + implementation("androidx.navigation:navigation-compose:2.6.0") + + // Lifecycle + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1") + implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1") + + // Hilt + implementation("com.google.dagger:hilt-android:2.46.1") + kapt("com.google.dagger:hilt-compiler:2.46.1") + + // Networking + implementation("com.squareup.retrofit2:retrofit:2.9.0") + implementation("com.squareup.okhttp3:okhttp:4.11.0") + implementation("com.squareup.retrofit2:converter-moshi:2.9.0") + + // Coil + implementation("io.coil-kt:coil-compose:2.4.0") + + // Room + implementation("androidx.room:room-runtime:2.6.1") + kapt("androidx.room:room-compiler:2.6.1") + implementation("androidx.room:room-ktx:2.6.1") + + // WorkManager, DataStore + implementation("androidx.work:work-runtime-ktx:2.8.1") + implementation("androidx.datastore:datastore-preferences:1.0.0") + + // Testing (skeleton) + testImplementation("junit:junit:4.13.2") +} diff --git a/android-app/app/src/main/AndroidManifest.xml b/android-app/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..0447c96 --- /dev/null +++ b/android-app/app/src/main/AndroidManifest.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/android-app/app/src/main/java/de/harheimertc/MainActivity.kt b/android-app/app/src/main/java/de/harheimertc/MainActivity.kt new file mode 100644 index 0000000..47f69bd --- /dev/null +++ b/android-app/app/src/main/java/de/harheimertc/MainActivity.kt @@ -0,0 +1,21 @@ +package de.harheimertc + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.material3.Text +import androidx.compose.ui.tooling.preview.Preview + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + Text("HarheimerTC - App Scaffold") + } + } +} + +@Preview +fun PreviewMain() { + Text("Preview") +} diff --git a/android-app/app/src/main/res/values/colors.xml b/android-app/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..ab1782c --- /dev/null +++ b/android-app/app/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #ef4444 + #dc2626 + #71717a + \ No newline at end of file diff --git a/android-app/build.gradle.kts b/android-app/build.gradle.kts new file mode 100644 index 0000000..952b2fd --- /dev/null +++ b/android-app/build.gradle.kts @@ -0,0 +1,11 @@ +// Root build.gradle.kts (skeleton) +plugins { + id("com.android.application") version "8.1.0" apply false + id("org.jetbrains.kotlin.android") version "1.9.10" apply false +} + +buildscript { +} + +allprojects { +} diff --git a/android-app/settings.gradle.kts b/android-app/settings.gradle.kts new file mode 100644 index 0000000..6ced647 --- /dev/null +++ b/android-app/settings.gradle.kts @@ -0,0 +1,2 @@ +rootProject.name = "harheimertc-android" +include(":app")