ClockIn is a modern personal productivity Android application that helps users stay on top of their day with a focused, priority-driven task list.
Built with classic Android Views + ViewBinding and a local Firebase-emulator REST backend, the app is designed to be simple, scalable, and production-ready.
🎯 Vision:
"Clock in to your day — track tasks, focus on what matters, and never miss a high-priority deadline."
- Firebase Auth (email/password login + signup)
- Cold-start Splash screen with one-shot routing (Tasks if logged in, else Login)
- Pure logout interceptor (
AuthStateListener) that redirects to Login when the user becomesnull - Drawer locked on auth/splash flow, unlocked on main screens
- Create, edit, delete, and complete tasks
- Tags (
Urgent/Work/Personal) and priority (HIGH/NORMAL) - Checkbox toggle for completion with instant sync
- Empty-state, loading, and error (Snackbar) UI states
- Tasks split into High Priority and Upcoming sections
- In-memory filtering of completed tasks in the ViewModel
- Sectioned
RecyclerViewwith header + task rows via a singleTasksAdapter
- Single-Activity +
DrawerLayoutarchitecture - All screen changes go through a central
Navigator - Destinations:
Splash,Login,Signup,Tasks,About - Navigation drawer with Tasks / About top-level destinations
- Edge-to-edge layout with toolbar state managed per top fragment
- REST API (Express backend in
functions/, Firestore Admin onusers/{userId}/tasks/{taskId}) - Plain dataclass model (
domain/Taskwith defaults; Moshi ignores unknown fields) - Hilt DI with real REST-backed repositories (
RepositoryModule) - Coroutines (
kotlinx-coroutines-android) for all network calls - Timber logging (never
android.util.Log)
- Kotlin (100%)
- Android Views + ViewBinding
- Material Components (M2 –
Theme.MaterialComponents.*)
- MVVM (Fragment → ViewModel → Repository)
- Repository Pattern
- Single-Activity + custom
Navigator/Destinationnavigation
- Retrofit + Moshi + OkHttp (
TaskApi/AuthApi, DTOs withtoDomain()) - Hilt DI (
NetworkModule,RepositoryModule) - Plain
domain/Taskdataclass; backend normalizes dates to millis intoTaskDto
- AGP 9.3.1, Gradle 9.5.0 (Wrapper), JDK 21 (Build), Java 11 (Source/Target)
- minSdk 24, compileSdk/targetSdk 37
- Timber, Coroutines, ViewBinding, BuildConfig
com.narang.clockin
│
├── data/
│ ├── TaskApi.kt / AuthApi.kt # Retrofit contracts
│ ├── TaskDto.kt / AuthDto.kt # Moshi DTOs + toDomain()
│ ├── TaskRepositoryImpl.kt # REST impl
│ ├── AuthRepositoryImpl.kt # REST impl
│ └── AuthInterceptor.kt
│
├── domain/
│ ├── Task.kt # plain Parcelable dataclass with defaults
│ ├── AuthUser.kt / Result.kt
│ └── TaskRepository.kt / AuthRepository.kt
│
├── di/
│ ├── NetworkModule.kt # Moshi + OkHttp + Retrofit + APIs
│ └── RepositoryModule.kt # provides real impls
│
├── navigation/
│ ├── Destination.kt
│ ├── Destinations.kt # Splash/Login/Signup/Tasks/About
│ └── Navigator.kt # navigate() + navigateToRoot()
│
├── ui/
│ ├── splash/
│ │ └── SplashFragment.kt
│ ├── auth/
│ │ ├── LoginFragment.kt
│ │ ├── SignupFragment.kt
│ │ ├── AuthUiState.kt
│ ├── viewmodel/
│ │ ├── AuthViewModel.kt (@HiltViewModel)
│ │ └── TaskViewModel.kt (@HiltViewModel)
│ ├── tasks/
│ │ ├── TaskFragment.kt # RecyclerView + FAB + menu dialog
│ │ ├── AddTaskDialogFragment.kt # create/edit sheet
│ │ ├── TaskUiState.kt
│ ├── adapter/
│ │ └── TaskAdapter.kt / TaskListItem.kt
│ └── about/
│ └── AboutFragment.kt
│
├── MainActivity.kt # Drawer + toolbar state + splash router + logout guard
├── ClockInApplication.kt # Timber init
└── MainActivity layout (activity_main.xml, fragment_tasks.xml, drawer menu)
UI (Fragments + ViewBinding)
↓
ViewModel (StateFlow<TaskUiState> / AuthUiState)
↓
Repository Layer (TaskRepository / AuthRepository REST impls)
↓
Remote Data Source (REST API: tasks + auth endpoints)
↓
UI State Updates (render() + Snackbar / empty / loading states)
- Priority-grouped task browsing system
- Add/edit dialog with date-time picker, tag, and priority
- Overflow menu (edit/delete) per task row
- Login/signup with form validation and error states
- Auth ViewModel backed by
AuthRepository(REST) - Automatic session restore on cold start
- Static info screen reachable from the drawer
- Version + app description
git clone <your-repo-url>
cd ClockIn
- Open the project folder
- Use JDK 21 (Gradle toolchain is managed)
- Wait for Gradle sync (Gradle Wrapper 9.5.0, AGP 9.3.1)
This project uses only the local Firebase emulators as its HTTP server. No Firebase console project, no google-services.json, no cloud billing — the app talks to the Functions emulator on your laptop's LAN IP (NetworkModule.BASE_URL).
- Install the Firebase CLI, then start Auth + Firestore + Functions with persisted seed data:
JAVA_TOOL_OPTIONS="-Xmx512m" firebase emulators:start --only auth,firestore,functions --import=./emulator-data --export-on-exit=./emulator-data - Demo login:
demo@clockin.app/demo1234(seeded inemulator-data/, gitignored). - If the laptop's IP changes (e.g. phone hotspot instead of home Wi-Fi), update
NetworkModule.BASE_URLand rebuild — hotspot subnets are usually192.168.43.x(Android) or172.20.10.x(iPhone).
./gradlew assembleDebug
Useful commands:
./gradlew testDebugUnitTest # JVM unit tests (incl. TaskDto mapping)
./gradlew connectedDebugAndroidTest # instrumented tests
./gradlew lint # Android lint
./gradlew check # full check
- 🔔 Due-date reminders / notifications
- 🔍 Search, tag filter, and sort options
- 📶 Offline persistence + sync status indicator
- ⭐ Recurring tasks and subtasks
- 📊 Productivity stats (completed per day/week)
- 🌙 Dark theme + dynamic color support
- 🧩 Home-screen widget for high-priority tasks
- ✔ Production-style single-Activity + Navigator navigation
- ✔ Realtime per-user Firestore task sync
- ✔ Defensive schema-less model (old/new doc versions coexist)
- ✔ No compound index needed (single-field
orderBy, in-memory filter) - ✔ Clean MVVM + Repository separation, ViewBinding-only views
- ✔ Unit-tested model layer (
TaskFromDocumentTest)
ClockIn – Android (Kotlin, Views, Firebase) task manager.
This project is for educational and portfolio purposes only.
ClockIn is a focused, local-backend (Firebase emulators) productivity app concept designed to grow into a full daily-planning product with reminders, offline-first sync, and smart prioritization.




