rebranding
This commit is contained in:
139
tasks/kordant-unified-restructure/34-android-app-foundation.md
Normal file
139
tasks/kordant-unified-restructure/34-android-app-foundation.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# 34. Android App — Jetpack Compose Foundation, Navigation, and Shared Theme
|
||||
|
||||
meta:
|
||||
id: kordant-unified-restructure-34
|
||||
feature: kordant-unified-restructure
|
||||
priority: P1
|
||||
depends_on: [kordant-unified-restructure-01, kordant-unified-restructure-02]
|
||||
tags: [android, jetpack-compose, foundation, navigation, mobile]
|
||||
|
||||
objective:
|
||||
- Establish the Android app foundation in `android/`: a Jetpack Compose project with app entry point, navigation architecture, and a shared theme system that mirrors the web app's Kordant brand palette with Material3 and dynamic dark mode support.
|
||||
|
||||
deliverables:
|
||||
- `android/` directory with complete Android project:
|
||||
- `app/build.gradle.kts` — App module configuration
|
||||
- `app/src/main/AndroidManifest.xml` — App manifest with permissions
|
||||
- `app/src/main/java/com/kordant/android/MainActivity.kt` — Entry point with `setContent`
|
||||
- `app/src/main/java/com/kordant/android/KordantApp.kt` — Application class
|
||||
- `android/app/src/main/java/com/kordant/android/ui/theme/` — Theme system:
|
||||
- `Color.kt` — All brand color tokens as `Color` constants:
|
||||
- `BrandPrimary`, `BrandPrimaryLight`, `BrandPrimaryDark`
|
||||
- `BrandAccent`, `BrandAccentLight`, `BrandAccentDark`
|
||||
- `BgPrimary`, `BgSecondary`, `BgTertiary` (light and dark variants)
|
||||
- `TextPrimary`, `TextSecondary`, `TextTertiary`
|
||||
- `Success`, `Warning`, `Error`, `Info`
|
||||
- `Type.kt` — Typography scale using Material3 `Typography`
|
||||
- `Shape.kt` — Corner radius shapes (small, medium, large)
|
||||
- `Theme.kt` — `KordantTheme` composable:
|
||||
- `lightColorScheme()` and `darkColorScheme()` using Material3
|
||||
- `dynamicColor` support for Android 12+ (optional)
|
||||
- Manual theme override state
|
||||
- `android/app/src/main/java/com/kordant/android/navigation/` — Navigation:
|
||||
- `AppNavigation.kt` — Navigation host with all routes
|
||||
- `Screen.kt` — Sealed class of all destinations with arguments
|
||||
- `BottomNavBar.kt` — Bottom navigation with 5 items: Dashboard, Services, Alerts, Settings, Account
|
||||
- `NavGraph.kt` — Compose Navigation graph definition
|
||||
- `android/app/src/main/res/` — Resources:
|
||||
- `mipmap-xxxhdpi/` — App icons for all densities
|
||||
- `values/themes.xml` — Base theme definitions
|
||||
- `drawable/` — Vector icons and logos
|
||||
- Project configuration:
|
||||
- `build.gradle.kts` (project level) with Kotlin 2.0, Compose BOM
|
||||
- `settings.gradle.kts` including app module
|
||||
- Min SDK: 26 (Android 8.0), Target SDK: 35, Compile SDK: 35
|
||||
- Kotlin version: 2.0.0
|
||||
- Compose BOM: 2024.05.00 or latest stable
|
||||
|
||||
steps:
|
||||
1. Create `android/` directory with standard Android project structure.
|
||||
2. Set up Gradle files:
|
||||
- Root `build.gradle.kts`: plugins block with `com.android.application`, `org.jetbrains.kotlin.android`
|
||||
- `gradle/libs.versions.toml` for version catalog (recommended)
|
||||
- App `build.gradle.kts`:
|
||||
```kotlin
|
||||
android {
|
||||
compileSdk = 35
|
||||
defaultConfig {
|
||||
minSdk = 26
|
||||
targetSdk = 35
|
||||
applicationId = "com.kordant.android"
|
||||
}
|
||||
buildFeatures { compose = true }
|
||||
composeOptions { kotlinCompilerExtensionVersion = "1.5.14" }
|
||||
}
|
||||
dependencies {
|
||||
implementation(platform("androidx.compose:compose-bom:2024.05.00"))
|
||||
implementation("androidx.compose.ui:ui")
|
||||
implementation("androidx.compose.material3:material3")
|
||||
implementation("androidx.navigation:navigation-compose:2.7.7")
|
||||
// ... other deps
|
||||
}
|
||||
```
|
||||
3. Create theme system:
|
||||
- `Color.kt`: Define all colors as `val BrandPrimary = Color(0xFF4F46E5)` etc.
|
||||
- `Type.kt`: Create `Typography` with Inter font (download and add to `res/font/`)
|
||||
- `Shape.kt`: `Shapes` with `small = RoundedCornerShape(8.dp)`, `medium = 12.dp`, `large = 16.dp`
|
||||
- `Theme.kt`:
|
||||
```kotlin
|
||||
@Composable
|
||||
fun KordantTheme(
|
||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||
dynamicColor: Boolean = false, // disable for brand consistency
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val colorScheme = when {
|
||||
dynamicColor && Build.VERSION.SDK_INT >= 31 -> {
|
||||
if (darkTheme) dynamicDarkColorScheme(LocalContext.current)
|
||||
else dynamicLightColorScheme(LocalContext.current)
|
||||
}
|
||||
darkTheme -> DarkColorScheme
|
||||
else -> LightColorScheme
|
||||
}
|
||||
MaterialTheme(colorScheme = colorScheme, typography = Typography, shapes = Shapes, content = content)
|
||||
}
|
||||
```
|
||||
4. Create navigation:
|
||||
- `Screen` sealed class: `Dashboard`, `Services`, `Alerts`, `Settings`, `Account`, `Login`, `Signup`, `Onboarding`, `ServiceDetail(val service: String)`
|
||||
- `AppNavigation.kt`: `NavHost` with `rememberNavController()`
|
||||
- `BottomNavBar.kt`: `NavigationBar` with 5 items, each with icon and label
|
||||
- Handle auth state: if unauthenticated, show Login as start destination
|
||||
5. Create `MainActivity.kt`:
|
||||
- `setContent { KordantTheme { AppNavigation() } }`
|
||||
- Handle window insets for edge-to-edge display
|
||||
6. Create `KordantApp.kt`:
|
||||
- Application class for initialization (dependency injection setup, if used)
|
||||
7. Add app icons:
|
||||
- Convert Kordant logo SVG to vector drawable (`res/drawable/ic_logo.xml`)
|
||||
- Generate mipmap icons using Android Studio's Image Asset Studio
|
||||
8. Build and run on Android Emulator to verify app launches.
|
||||
|
||||
steps:
|
||||
- Unit: Theme switches correctly between light and dark modes
|
||||
- Unit: Navigation graph contains all expected destinations
|
||||
- Visual: App launches with correct bottom navigation and branding
|
||||
- Visual: Theme colors match web app palette in both modes
|
||||
|
||||
acceptance_criteria:
|
||||
- [ ] Android app builds and launches without crashes
|
||||
- [ ] Bottom navigation has 5 tabs with correct icons and labels
|
||||
- [ ] Theme colors match web app palette in both light and dark modes
|
||||
- [ ] Navigation between screens works with native Android transitions
|
||||
- [ ] App icon displays correctly on launcher
|
||||
- [ ] Theme supports manual override (light/dark/system)
|
||||
- [ ] Project uses modern Android stack: Kotlin 2.0, Compose, Material3
|
||||
|
||||
validation:
|
||||
- Build app in Android Studio and run on Pixel 7 emulator (API 34)
|
||||
- Toggle device dark mode and verify all colors shift
|
||||
- Navigate through all bottom tabs and verify transitions
|
||||
- Verify app icon on emulator home screen
|
||||
- Run `./gradlew test` for unit tests
|
||||
|
||||
notes:
|
||||
- The Android app should feel native to Android, not like an iOS port. Use Material3 components, bottom sheets, floating action buttons, and Android-specific patterns.
|
||||
- Dynamic colors (Material You) are disabled by default to maintain brand consistency. Can be enabled as a user preference later.
|
||||
- Use Jetpack Compose Navigation with type-safe navigation arguments (Kotlin DSL or Navigation Compose 2.8+ typed navigation).
|
||||
- Consider using Hilt for dependency injection, but keep it simple for the initial setup.
|
||||
- The `android/` directory is not part of the pnpm workspace. It is a standalone Gradle project.
|
||||
- For font loading, add Inter font files to `res/font/` and reference them in `Type.kt`.
|
||||
Reference in New Issue
Block a user