A production-ready, feature-rich Android application showcasing modern app development practices
Features β’ Architecture β’ Tech Stack β’ Screenshots β’ Installation
CleanSafi is a fully functional laundry service application built with 100% Kotlin and Jetpack Compose. This portfolio project demonstrates enterprise-level Android development, featuring Clean Architecture, dependency injection, local persistence, M-PESA payment simulation, and a polished Material 3 UI with dark mode support.
- β Production-Ready - 95% complete with error handling, offline support, and accessibility features
- ποΈ Clean Architecture - Separation of concerns with Domain, Data, and Presentation layers
- π¨ Modern UI/UX - Material 3 design system with dynamic theming and smooth animations
- π Dependency Injection - Hilt for scalable and testable code
- πΎ Local Database - Room for robust offline-first functionality
- π Reactive Programming - Kotlin Coroutines + Flow for asynchronous operations
- π± M-PESA Integration - Payment flow simulation with realistic order progression
- π Authentication - User registration and login with validation
- π§Ί Place Orders - Select laundry items, service types (Wash/Iron/Both), and schedule pickup
- π Smart Cart - Dynamic pricing, item suggestions, and swipe-to-delete
- π³ Payment Flow - M-PESA simulation with phone number validation (254XXXXXXXXX format)
- π¦ Order Tracking - Real-time status updates with 8-stage progression system
- π Order History - Complete order timeline with filter and search
- π€ User Profile - Statistics, theme toggle, and settings management
- π Network Monitoring - Real-time connectivity detection with offline indicators
β οΈ Error Handling - Comprehensive error states with retry mechanisms- π Empty States - Contextual empty views for better UX
- βΏ Accessibility - Content descriptions and proper semantic structure
- π Dark Mode - Persistent theme switching with Material 3 dynamic colors
- β Form Validation - Client-side validation for all user inputs
- π³ Haptic Feedback - Tactile responses for user interactions
- β¨ Animations - Smooth transitions, shimmer loading, and confetti celebrations
- π¬ Onboarding - 4-page introduction flow for first-time users
- π Runtime Permissions - Proper notification permission handling (Android 13+)
CleanSafi follows Clean Architecture principles with MVVM pattern for maintainability and testability:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Presentation Layer β
β (UI - Jetpack Compose + ViewModels + StateFlow) β
βββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββΌββββββββββββββββββββββββββββββββββββ
β Domain Layer β
β (Business Logic - Models + Repositories) β
βββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββΌββββββββββββββββββββββββββββββββββββ
β Data Layer β
β (Room Database + Repository Implementations) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
com.cleansafi/
βββ presentation/ # UI Layer (Compose Screens + ViewModels)
β βββ splash/
β βββ onboarding/
β βββ auth/ # Login & Signup
β βββ home/ # Dashboard
β βββ order/placeorder/ # Order creation
β βββ cart/ # Shopping cart
β βββ checkout/ # Order scheduling
β βββ payment/ # M-PESA simulation
β βββ orders/ # Order history
β βββ profile/ # User profile
β βββ navigation/ # Navigation graph
βββ domain/ # Business Logic
β βββ model/ # Domain models
β βββ repository/ # Repository interfaces
βββ data/ # Data Layer
β βββ local/ # Room Database
β β βββ dao/ # Data Access Objects
β β βββ entity/ # Database entities
β β βββ CleanSafiDatabase.kt
β βββ repository/ # Repository implementations
βββ core/ # Shared Infrastructure
βββ di/ # Hilt modules
βββ theme/ # Material 3 theme
βββ ui/ # Reusable components
βββ error/ # Error handling
βββ network/ # Connectivity monitoring
βββ validation/ # Form validators
βββ util/ # Utilities
- Language: Kotlin 1.9.21
- UI Framework: Jetpack Compose (BOM 2023.10.01)
- Design System: Material 3
- Min SDK: 26 (Android 8.0) | Target SDK: 34 (Android 14)
- ViewModel - UI state management
- Navigation Compose - Type-safe screen navigation
- Hilt 2.50 - Dependency injection
- Room 2.6.1 - Local database with SQLite
- Coroutines + Flow - Asynchronous operations
- StateFlow - Reactive state management
- WorkManager 2.9.0 - Background tasks
- KSP - Kotlin Symbol Processing for annotation processing
- Gradle Version Catalogs - Dependency management
- Material Icons Extended - Comprehensive icon set
// Compose & UI
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.material:material-icons-extended")
// Architecture
implementation("com.google.dagger:hilt-android:2.50")
implementation("androidx.hilt:hilt-navigation-compose:1.1.0")
implementation("androidx.room:room-ktx:2.6.1")
// Lifecycle & Navigation
implementation("androidx.navigation:navigation-compose:2.7.6")
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.7.0")- Android Studio: Hedgehog (2023.1.1) or later
- JDK: 17 or higher
- Android SDK: API Level 34
- Gradle: 8.2+ (included via wrapper)
-
Clone the repository
git clone https://github.com/muchaisam/Cleansafi.git cd Cleansafi -
Open in Android Studio
- Open Android Studio
- Select "Open an Existing Project"
- Navigate to the cloned directory
-
Sync Gradle
- Android Studio will automatically sync Gradle
- Wait for dependencies to download
-
Run the app
./gradlew assembleDebug # Build debug APK ./gradlew installDebug # Install on connected device
Or use the
βΆοΈ Run button in Android Studio
./gradlew assembleDebug # Debug build
./gradlew assembleRelease # Release build (requires signing)
./gradlew test # Run unit tests
./gradlew clean build # Clean buildFor demo purposes, you can use any credentials to sign up/login:
- Email: Any valid email format (e.g.,
demo@cleansafi.com) - Password: Minimum 6 characters
- Phone: 10-digit number (e.g.,
0712345678)
When making a payment:
- Use format:
254XXXXXXXXX(e.g.,254712345678) - Payment is simulated - no real money transactions
- Order progresses through realistic stages automatically
Demo Mode (Hidden Feature)
Long-press the app logo on the Home screen to enable Demo Mode:
- Speeds up order progression from minutes to seconds
- Perfect for showcasing the full order lifecycle quickly
- Great for demos and portfolio presentations
enum class ServiceType {
WASH_ONLY, // Base price
IRON_ONLY, // -20% from wash price
WASH_AND_IRON // +25% from wash price
}
// Dynamic pricing per item type
LaundryItemType.TOPS // KSh 40-50
LaundryItemType.TROUSERS // KSh 50-60
LaundryItemType.BEDSHEETS // KSh 60-70
LaundryItemType.OTHERS // KSh 70-80PENDING β CONFIRMED β PICKED_UP β PROCESSING β
READY β OUT_FOR_DELIVERY β DELIVERED β COMPLETED
Each stage includes:
- Timestamp tracking
- Status history
- Email notifications (simulated)
- Real-time UI updates
All data is persisted locally using Room database, making the app fully functional without an internet connection:
// Room Database with multiple DAOs for complete offline functionality
@Database(
entities = [UserEntity, OrderEntity, OrderItemEntity, CartItemEntity, PaymentEntity],
version = 1
)
abstract class CleanSafiDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
abstract fun orderDao(): OrderDao
abstract fun cartDao(): CartDao
abstract fun paymentDao(): PaymentDao
}What works offline:
- β User registration and login (credentials stored locally)
- β Browse services and add items to cart
- β Place orders and schedule pickups
- β View complete order history with status timeline
- β Track spending statistics (Profile & Orders screens)
- β M-PESA payment simulation
- β Theme preferences persist across sessions
Why this matters:
- π Instant app startup - No network calls needed
- π± Works in low-connectivity areas - Critical for Kenya/Africa markets
- πΎ Data never lost - SQLite persistence survives app kills
- π Reactive UI updates - Flow-based observation of database changes
sealed class AppError {
data class NetworkError(val message: String)
data class DatabaseError(val message: String)
data class ValidationError(val message: String)
data class UnknownError(val throwable: Throwable)
}Every screen includes:
- β Loading states with shimmer effects
β οΈ Error states with retry functionality- π Empty states with actionable guidance
Edit PricingCalculator.kt:
object PricingCalculator {
fun calculateItemPrice(
itemType: LaundryItemType,
serviceType: ServiceType
): Int {
// Modify base prices here
val basePrice = when (itemType) {
LaundryItemType.TOPS -> 40
LaundryItemType.TROUSERS -> 50
// ...
}
// Adjust multipliers as needed
}
}Modify Color.kt and Theme.kt in core/theme/:
val md_theme_light_primary = Color(0xFF006C4C)
val md_theme_dark_primary = Color(0xFF6FDBAC)
// Full Material 3 color scheme- UserEntity - User accounts
- OrderEntity - Orders with status and scheduling
- OrderItemEntity - Individual items per order
- CartItemEntity - Temporary shopping cart
- PaymentEntity - Payment records with transaction IDs
- OrderStatusHistoryEntity - Complete status timeline
User (1) βββ (N) Orders
Order (1) βββ (N) OrderItems
Order (1) βββ (1) Payment
Order (1) βββ (N) StatusHistory./gradlew test # Unit tests
./gradlew connectedAndroidTest # Instrumented tests
./gradlew testDebugUnitTest # Debug unit tests only- ViewModel logic testing
- Repository pattern testing
- Database migration testing
- Validation logic testing
- β Lazy column for efficient list rendering
- β Remember and derivedStateOf for composition optimization
- β Database indexes on frequently queried columns
- β Flow-based reactive updates (no unnecessary recompositions)
- β Image loading optimization
- β Minimal overdraw with proper layout hierarchy
β οΈ Passwords stored in plain text (Room database)β οΈ No server-side authenticationβ οΈ Simulated payment system
- π Implement password hashing (BCrypt/Argon2)
- π Add JWT/OAuth authentication
- π Integrate real M-PESA/payment gateway
- π Enable ProGuard/R8 obfuscation
- π Add SSL pinning for network requests
- π Implement biometric authentication
- User authentication
- Order placement and management
- Cart functionality
- Payment simulation
- Order tracking
- Profile management
- Error handling system
- Offline support
- Empty states
- Network monitoring
- Form validation
- Accessibility features
- Backend API integration
- Real M-PESA Daraja API
- Push notifications (FCM)
- Order rating and reviews
- Promo codes and discounts
- Multiple delivery addresses
- In-app chat support
- Analytics integration
- Multi-language support (i18n)
- Wear OS companion app
- Widget for quick order status
- Share order receipts
- Subscription plans
- AI-powered laundry tips
This is a portfolio project, but feedback and suggestions are welcome!
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Sam Muchai
- π GitHub: @muchaisam
- Material Design 3 - Design system and components
- Google Codelabs - Android development best practices
- Android Developer Documentation - Official guides and references
- Stack Overflow Community - Problem-solving assistance
For questions or support:
- π Issues: GitHub Issues
- π¬ Discussions: GitHub Discussions







