{"id":20115562,"url":"https://github.com/mutualmobile/harvesttimekmp","last_synced_at":"2025-05-06T13:32:57.864Z","repository":{"id":37791928,"uuid":"495292087","full_name":"mutualmobile/HarvestTimeKMP","owner":"mutualmobile","description":"A Kotlin multiplatform playground project for getharvest time logger clone.","archived":false,"fork":false,"pushed_at":"2022-06-22T19:54:23.000Z","size":16183,"stargazers_count":46,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-09T12:42:52.056Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mutualmobile.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-05-23T06:54:42.000Z","updated_at":"2025-03-12T23:49:21.000Z","dependencies_parsed_at":"2022-06-22T16:23:59.404Z","dependency_job_id":null,"html_url":"https://github.com/mutualmobile/HarvestTimeKMP","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mutualmobile%2FHarvestTimeKMP","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mutualmobile%2FHarvestTimeKMP/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mutualmobile%2FHarvestTimeKMP/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mutualmobile%2FHarvestTimeKMP/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mutualmobile","download_url":"https://codeload.github.com/mutualmobile/HarvestTimeKMP/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252693746,"owners_count":21789751,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T18:35:39.878Z","updated_at":"2025-05-06T13:32:55.039Z","avatar_url":"https://github.com/mutualmobile.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv id=\"top\"\u003e\u003c/div\u003e\n\n# 🕓 HarvestTime KMP\n\u003cp align=\"left\"\u003e Multi-Platform Harvest Time Tracking clone project built with SwiftUI, Jetpack Compose, Kotlin/Js \u003c/p\u003e\n\n[Access the Web App built with React + MUI here](https://harvestkmp.web.app)\n\n\n\u003cp align=\"left\"\u003e\n    \u003ca href=\"https://kotlinlang.org/docs/releases.html\"\u003e\n      \u003cimg alt=\"Kotlin\" src=\"https://img.shields.io/badge/Kotlin-1.6.21-blue.svg?color=blue\u0026style=for-the-badge\"/\u003e\n    \u003c/a\u003e\n    \u003ca href = \"https://github.com/mutualmobile/HarvestTimeKMP/stargazers\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/stars/mutualmobile/HarvestTimeKMP?color=green\u0026style=for-the-badge\" /\u003e\n    \u003c/a\u003e\n    \u003ca href = \"https://github.com/mutualmobile/HarvestTimeKMP/network/members\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/forks/mutualmobile/HarvestTimeKMP?color=green\u0026style=for-the-badge\" /\u003e\n    \u003c/a\u003e\n    \u003ca href = \"https://github.com/mutualmobile/HarvestTimeKMP/issues\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/issues/mutualmobile/HarvestTimeKMP?color=orange\u0026style=for-the-badge\" /\u003e\n    \u003c/a\u003e\n    \u003ca href = \"https://github.com/mutualmobile/HarvestTimeKMP/watchers\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/watchers/mutualmobile/HarvestTimeKMP?color=yellowgreen\u0026style=for-the-badge\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"left\"\u003e\n    \u003ca href=\"https://opensource.org/licenses/Apache-2.0\"\u003e\n      \u003cimg alt=\"License\" src=\"https://img.shields.io/badge/License-Apache%202.0-blue.svg?color=yellowgreen\u0026style=for-the-badge\"/\u003e\n    \u003c/a\u003e\n    \u003ca href=\"\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/PRs-WELCOME-brightgreen.svg?color=yellow\u0026style=for-the-badge\"/\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n### The purpose of this repository:\n\n- Build cross-platform applications and share common code between Android, iOS, Web and Desktop.\n- Provide support for different platform with respective Native UI for each, and sharing the common business logic.\n- Dependency Injection using Koin.\n- Usage of latest Ktor client for Networking.\n- Performing background task with Kotlin Coroutines.\n\n### Currently running on:\n\n- [x] \u003ccode\u003e\u003cimg height=\"20\" src=\"https://raw.githubusercontent.com/github/explore/80688e429a7d4ef2fca1e82350fe8e3517d3494d/topics/android/android.png\"\u003e\u003c/code\u003e Android (Jetpack Compose)\n- [x] \u003ccode\u003e\u003cimg height=\"20\" src=\"https://raw.githubusercontent.com/github/explore/80688e429a7d4ef2fca1e82350fe8e3517d3494d/topics/react/react.png\"\u003e\u003c/code\u003e Web (Kotlin/JS + React + MUI)\n- [x] \u003ccode\u003e\u003cimg height=\"20\" src=\"https://raw.githubusercontent.com/github/explore/80688e429a7d4ef2fca1e82350fe8e3517d3494d/topics/swift/swift.png\"\u003e\u003c/code\u003e iOS (SwiftUI)\n- [ ] \u003ccode\u003e\u003cimg height=\"20\" src=\"https://3.bp.blogspot.com/-VVp3WvJvl84/X0Vu6EjYqDI/AAAAAAAAPjU/ZOMKiUlgfg8ok8DY8Hc-ocOvGdB0z86AgCLcBGAsYHQ/s1600/jetpack%2Bcompose%2Bicon_RGB.png\"\u003e\u003c/code\u003e Desktop JVM (Jetpack Compose)\n- [x] \u003ccode\u003e\u003cimg height=\"20\" src=\"https://raw.githubusercontent.com/github/explore/80688e429a7d4ef2fca1e82350fe8e3517d3494d/topics/swift/swift.png\"\u003e\u003c/code\u003e MacOS (SwiftUI)\n\nBuilt using [PraxisKMP](https://github.com/mutualmobile/PraxisKMP) as the base project.\n\n\u003cp align=\"right\"\u003e[\u003ca href=\"#top\"\u003eBack to top\u003c/a\u003e]\u003c/p\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003eTable of content\u003c/summary\u003e\n  \u003cul\u003e\n    \u003cli\u003e\u003ca href=\"#%EF%B8%8F-architecture\"\u003eArchitecture\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#-api\"\u003eAPI\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#%EF%B8%8F%EF%B8%8F-built-with-%EF%B8%8F-using-kotlin\"\u003eTech stack\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#-screenshots\"\u003eScreenshots\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#-license\"\u003eLicense\u003c/a\u003e\u003c/li\u003e\n  \u003c/ul\u003e\n\u003c/details\u003e\n\n## 🏛️ Architecture\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/architecture/harvest_kmp_architecture.png\" /\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\nArchitecture Diagram: [Here](https://drive.google.com/file/d/1aLgdk-3PUmAriNR_Z_mPNZBK-IrFpP1G/view?usp=sharing)\n\n\u003cp align=\"right\"\u003e[\u003ca href=\"#top\"\u003eBack to top\u003c/a\u003e]\u003c/p\u003e\n\n## 🌐 API\nThe Harvest API is written in Kotlin with SpringBoot. Find the repo [here](https://github.com/mutualmobile/HarvestAPISpring).\n\n- Authentication :lock:\n  - [x] Find Organization\n  - [x] Sign In User\n  - [x] Sign Up User\n  - [x] Login User\n  - [x] Forgot Password\n  - [x] Change Password\n\n- List Projects 📽\n  - [x] Org admin can create projects\n  - [x] Org admin can list,search projects\n  - [x] Org admin can assign projects to users\n  - [ ] more are.. 🚧 WIP\n\n- Logging Time :office:\n  - [ ] Log Time 🚧 WIP\n  - [ ] an other\n\n\u003cp align=\"right\"\u003e[\u003ca href=\"#top\"\u003eBack to top\u003c/a\u003e]\u003c/p\u003e\n\n## 🏗️️ Built with ❤️ using Kotlin\n| What            | How                        |\n|----------------\t|------------------------------\t|\n| 🎭 Android UI   | [Jetpack Compose](https://developer.android.com/jetpack/compose)                |\n| 🎭 IOS UI   | [Swift UI](https://developer.apple.com/documentation/swiftui/)                |\n| 🎭 Web UI   | [React JS with MUI](https://mui.com/)                |\n| 🏗 Architecture    | [Clean](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)                            |\n| 💉 DI                | [Koin](https://insert-koin.io/)                        |\n| 🌊 Async            | [Coroutines, Flows, KMP Native Coroutines](https://github.com/rickclephas/KMP-NativeCoroutines)                |\n| 🌐 Networking        | [Ktor](https://ktor.io/)                        |\n| ð Storage       | [Key Value, SqlDelight](https://github.com/russhwolf/multiplatform-settings)                        |\n\n\u003cp align=\"right\"\u003e[\u003ca href=\"#top\"\u003eBack to top\u003c/a\u003e]\u003c/p\u003e\n\n## 📷 Screenshots\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"#android-screenshots\"\u003eAndroid\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#web-screenshots-reactjs\"\u003eReact\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#ios-screenshots\"\u003eIOS\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#\"\u003eDesktop 🚧 WIP\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#\"\u003eMacOS 🚧 WIP\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\n### Android Screenshots\n- [OnBoarding](#android-onboarding-screens)\n- [Authenticate](#android-authentication-screens)\n- [Home](#android-home-screens)\n- [Settings](#android-settings-screens)\n\n\u003cp align=\"right\"\u003e[\u003ca href=\"#top\"\u003eBack to top\u003c/a\u003e]\u003c/p\u003e\n\n#### Android OnBoarding Screens\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eOnBoarding One\u003c/th\u003e\n    \u003cth\u003eOnBoarding Two\u003c/th\u003e \n    \u003cth\u003eOnBoarding Three\u003c/th\u003e\n    \u003cth\u003eOnBoarding Four\u003c/th\u003e \n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/android_screenshots/android_onboarding_one.png\" width=240/\u003e\u003c/td\u003e \n    \u003ctd\u003e\u003cimg src = \"art/android_screenshots/android_onboarding_two.png\" width=240/\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cimg src = \"art/android_screenshots/android_onboarding_three.png\" width=240/\u003e\u003c/td\u003e \n    \u003ctd\u003e\u003cimg src = \"art/android_screenshots/android_onboarding_four.png\" width=240/\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### Android Authentication Screens\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eEnter Organization Screen\u003c/th\u003e\n    \u003cth\u003eSign up Screen\u003c/th\u003e \n    \u003cth\u003eSign In Screen\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/android_screenshots/android_enter_org_screen.png\" width=240/\u003e\u003c/td\u003e \n    \u003ctd\u003e\u003cimg src = \"art/android_screenshots/android_sign_up.png\" width=240/\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cimg src = \"art/android_screenshots/android_harvest_sign_in.png\" width=240/\u003e\u003c/td\u003e \n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### Android Home Screens\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eHome Screen\u003c/th\u003e\n    \u003cth\u003eNew Entry Screen\u003c/th\u003e \n    \u003cth\u003eHome Drawer\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/android_screenshots/android_home_screen.png\" width=240/\u003e\u003c/td\u003e \n    \u003ctd\u003e\u003cimg src = \"art/android_screenshots/android_new_entry_screen.png\" width=240/\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cimg src = \"art/android_screenshots/android_home_drawer.png\" width=240/\u003e\u003c/td\u003e \n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### Android Settings Screens\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eSettings Screen\u003c/th\u003e\n    \u003cth\u003eReport Screen\u003c/th\u003e \n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/android_screenshots/android_setting_screen.png\" width=240/\u003e\u003c/td\u003e \n    \u003ctd\u003e\u003cimg src = \"art/android_screenshots/android_report_screen.png\" width=240/\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cp align=\"right\"\u003e[\u003ca href=\"#top\"\u003eBack to top\u003c/a\u003e]\u003c/p\u003e\n\n### Web Screenshots (ReactJS)\n- Authentication Screens\n  - [Verify Organization Screen](#verify-organization-screen)\n  - [Sign Up Screen](#sign-up-screen)\n  - [Sign In Screen](#sign-in-screen)\n  - [Log In Screen](#log-in-screen)\n  - [Forgot Password Screen](#forgot-password-screen)\n- Home Screens\n  - [Home Screen](#home-screen)\n  - [Home Drawer Screen](#home-drawer-screen)\n  - [All User Screen](#all-user-screen)\n  - [All Projects Screen](#all-project-assignment-screen)\n  - [Settings Screen](#settings-screen)\n\n#### Verify Organization Screen\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eVerify Organization\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/react/web_enter_org_screen.png\" /\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### Sign Up Screen\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eSign Up\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/react/web_sign_up_screen.png\" /\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### Sign In Screen\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eSign In\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/react/web_sign_in_form.png\" /\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### Log In Screen\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eLog In\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/react/web_login_screen.png\" /\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### Forgot Password Screen\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eForgot Password\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/react/web_forgot_password_screen.png\" /\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### Home Screen\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eHome\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/react/web_home_Screen.png\" /\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### Home Drawer Screen\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eHome Drawer\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/react/web_drawer_screen.png\" /\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### All User Screen\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eAll User\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/react/web_all_users.png\" /\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### All Project Assignment Screen\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eAll Project Assignment\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/react/web_project_assignments_screen.png\" /\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### Settings Screen\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eSettings\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/react/web_settings_screen.png\" /\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cp align=\"right\"\u003e[\u003ca href=\"#top\"\u003eBack to top\u003c/a\u003e]\u003c/p\u003e\n\n### iOS Screenshots\n- [Authentications](#ios-authentications-screen)\n- [Home](#ios-home-screens)\n\n#### iOS Authentications Screen\n\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eOn Boarding Screen\u003c/th\u003e\n    \u003cth\u003eSign In Screen\u003c/th\u003e \n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/ios/ios_onBoarding_one.png\" width=240/\u003e\u003c/td\u003e \n    \u003ctd\u003e\u003cimg src = \"art/ios/ios_sign_in.jpg\" width=240/\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cp align=\"right\"\u003e[\u003ca href=\"#top\"\u003eBack to top\u003c/a\u003e]\u003c/p\u003e\n\n#### iOS Home Screens\n\n\u003ctable style=\"width:100%\"\u003e\n  \u003ctr\u003e\n    \u003cth\u003eHome Screen\u003c/th\u003e\n    \u003cth\u003eNew Entry List\u003c/th\u003e \n    \u003cth\u003eNew Entry Time\u003c/th\u003e \n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src = \"art/ios/ios_main_home_screen.png\" width=240/\u003e\u003c/td\u003e \n    \u003ctd\u003e\u003cimg src = \"art/ios/ios_new_entry_list_screen.png\" width=240/\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cimg src = \"art/ios/ios_new_entry_screen.png\" width=240/\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n### 🪪 License\n```\nCopyright 2022 Mutual Mobile\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n  ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmutualmobile%2Fharvesttimekmp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmutualmobile%2Fharvesttimekmp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmutualmobile%2Fharvesttimekmp/lists"}