Skip to content

Repository files navigation

CampusEV — Student App

CI

The student-facing app of the CampusEV campus live-tracking system. Students open it and watch campus electric vehicles, vans and buses move on a live map, tap a vehicle for its route and driver, and filter by type. It's a view-only companion to the driver app and backend service.

Kotlin Multiplatform + Compose Multiplatform — shared UI across Android & iOS. Currently Android-first; the iOS target is scaffolded but not yet built (needs a Mac).


✨ Features

  • Live map of all active campus vehicles, updated continuously.
  • Buttery-smooth motion — markers glide between position updates (client-side interpolation) instead of jumping, for an Uber/Ola-style feel.
  • Tap a vehicle → details sheet (label, type, route, driver, speed).
  • Filter by type — EV / VAN / BUS, colour-coded.
  • Campus overlay — stops, blocks, gates and landmarks drawn on the map.
  • Switchable map renderer — Google Maps or MapLibre + OpenStreetMap (a one-line flag).
  • Polished, modern UI — translucent "glass" panels, a live indicator, clean loading / empty / error states.

🧱 Tech stack

Area Choice
Language Kotlin (Multiplatform)
UI Compose Multiplatform (Material 3), shared across Android & iOS
Architecture MVVM + Repository, unidirectional data flow with StateFlow
DI Manual (AppContainer) — no framework
Networking Ktor client (OkHttp on Android, Darwin on iOS)
Serialization kotlinx.serialization (snake_case JSON)
Maps Google Maps SDK or MapLibre + OpenStreetMap (switchable)
Concurrency Kotlin coroutines + Flow
Lifecycle/VM AndroidX Lifecycle (multiplatform ViewModel)
Build Gradle (Kotlin DSL) + version catalog
CI GitHub Actions (Android build + shared unit tests)
Min SDK 26 (Android 8.0)

The map is the only platform-specific UI (behind an expect/actual); everything else — networking, domain logic, interpolation, view models, and the rest of the UI — lives in shared code.


🗂️ Project structure

shared/                 the Kotlin Multiplatform module (most of the app)
  commonMain/           data (Ktor + repository) · domain (models + interpolation)
                        · ui (theme / components / map) · di
  androidMain/          Google + MapLibre map renderers, Android HTTP engine
  iosMain/              map stub + iOS HTTP engine
androidApp/             thin Android host (launches the shared UI)
iosApp/                 Xcode project (iOS, later)
docs/                   architecture, specs, and design docs

Deeper detail: docs/ARCHITECTURE.md.


✅ Prerequisites

  • Android Studio (latest stable) with the Android SDK.
  • JDK 21 (the bundled JetBrains Runtime is fine).
  • An Android device or emulator running API 26+ (a physical device is best for GPS-driven demos).
  • Internet access — the app reads live data from the backend service.
  • (Only if using the Google Maps renderer) a Google Maps SDK for Android API key.
  • A reachable instance of the CampusEV backend (see that project's README to run it).

⚙️ Setup & configuration

1. Clone & open

Clone the repo and open the project folder in Android Studio; let Gradle sync.

2. Secrets — local.properties (never committed)

Sensitive values live in local.properties, which is git-ignored (see Secrets & .gitignore). Add your Google Maps key there:

MAPS_API_KEY=your_google_maps_android_api_key
  • Get a key from the Google Cloud Console (Maps SDK for Android) and restrict it to this app's package name + your signing SHA-1, and to Maps SDK for Android only.
  • No key? No problem — switch to the free MapLibre renderer (next step); it needs no key.

3. Choose the map renderer

A single flag selects the renderer, in shared/src/androidMain/kotlin/.../map/VehicleMapActual.android.kt:

private const val USE_GOOGLE_MAPS = true   // false → MapLibre + OpenStreetMap ($0, no key)

4. Backend endpoint

The app talks to the CampusEV backend. The base URL is set in the networking layer (shared/src/commonMain/kotlin/.../data/remote/ApiRoutes.kt) — point it at your own backend deployment. (It is intentionally not documented here; keep deployment URLs out of the public docs.)


▶️ Build & run

Android

./gradlew :androidApp:assembleDebug      # build the debug APK

…or just hit Run on the androidApp configuration in Android Studio (device/emulator with internet).

iOS — deferred; the target is scaffolded but requires a Mac (Xcode + Kotlin/Native) to build.

The backend may take a few seconds to respond to the first request if it has been idle; the app shows a loading state and then goes live.


🧪 Testing

./gradlew :shared:testAndroidHostTest    # shared unit tests

Covered: coordinate/bearing interpolation, DTO→domain mapping, and JSON (snake_case) parsing.


🔁 CI

GitHub Actions builds the Android app and runs the shared unit tests on every push and PR (.github/workflows/ci.yml). iOS is not built in CI (needs a macOS runner). No secrets are required to compile — the Maps key gracefully defaults to empty when absent.


🔐 Secrets & .gitignore

The repo's .gitignore already excludes everything that shouldn't be published:

  • local.propertiesholds the Maps API key; never commit it.
  • .idea/, *.iml — IDE files.
  • build/, .gradle/, .kotlin/ — build output & caches.

Before pushing, sanity-check that local.properties is not staged. Keep API keys, backend URLs, and any deployment details out of committed files and out of this README.


🤝 Contributing

This project uses spec-driven development — non-trivial work starts as a written spec that's reviewed before coding.


🗺️ Status & roadmap

  • ✅ Live vehicle map with smooth interpolation and details/filter — spec 0001
  • 🔜 Campus-places overlay fetched from the backend — spec 0002
  • ⬜ Student login (institutional Google sign-in)
  • ⬜ ETA to stop
  • ⬜ iOS runtime

License

TBD — add a LICENSE file before making the repository public if you intend to set usage terms.


Part of the CampusEV system: Driver app · Student app · Backend service.

About

Student app of the CampusEV live-tracking system — Kotlin Multiplatform + Compose Multiplatform (Android/iOS). Watch campus EVs, vans & buses move on a live map, tap for route/driver, filter by type. Smooth interpolation, switchable MapLibre/Google Maps, reads the backend's real-time feed. $0 stack.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages