From 1957ef52d0bfa0fab182f7d1cbac65b6a3b022e5 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sat, 28 Jun 2025 10:12:30 +0530 Subject: [PATCH 01/13] create client resolved --- .../com/mifos/room/entities/client/ClientPayloadEntity.kt | 2 +- .../feature/client/createNewClient/CreateNewClientScreen.kt | 2 ++ .../feature/client/createNewClient/CreateNewClientViewModel.kt | 1 + gradle/libs.versions.toml | 2 +- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/core/database/src/commonMain/kotlin/com/mifos/room/entities/client/ClientPayloadEntity.kt b/core/database/src/commonMain/kotlin/com/mifos/room/entities/client/ClientPayloadEntity.kt index 448c321d2e5..f66eeff86f3 100644 --- a/core/database/src/commonMain/kotlin/com/mifos/room/entities/client/ClientPayloadEntity.kt +++ b/core/database/src/commonMain/kotlin/com/mifos/room/entities/client/ClientPayloadEntity.kt @@ -72,5 +72,5 @@ data class ClientPayloadEntity( // TODO add legal form id field // 1 for Person (Individual client) -// val legalFormId: Int? = 1, + val legalFormId: Int ?=null, ) : Parcelable diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt index 8b8a8c1c287..4f27cc8ec7e 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt @@ -669,6 +669,7 @@ private fun createClientPayload( firstname = firstName, lastname = lastName, officeId = selectedOfficeId, + legalFormId=1, // Optional fields with default values active = isActive, @@ -676,6 +677,7 @@ private fun createClientPayload( dateOfBirth = formatDate(dateOfBirth), dateFormat = dateFormat, locale = locale, + ) // Optional fields diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt index d040192901e..95d7663223f 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt @@ -19,6 +19,7 @@ import androidclient.feature.client.generated.resources.feature_client_failed_to import androidclient.feature.client.generated.resources.feature_client_waiting_for_checker_approval import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import co.touchlab.kermit.Logger import com.mifos.core.common.utils.MFErrorParser import com.mifos.core.data.repository.CreateNewClientRepository import com.mifos.feature.client.utils.createImageRequestBody diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6e0d57dd4ec..4228eef9e53 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ androidxAppCompat = "1.7.0" androidxArchCore = '2.2.0' androidxComposeBom = "2025.01.00" androidxComposeCompiler = "1.5.8" -androidxComposeUi = "1.8.2" +androidxComposeUi = "1.7.6" androidxComposeRuntime = "1.7.6" androidxComposeRuntimeTracing = "1.7.6" androidxComposeMaterial3 = "1.3.1" From 9b197d70e2c979723f398809b17a39519687eaaf Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sat, 28 Jun 2025 12:46:36 +0530 Subject: [PATCH 02/13] resolved client file Picker issue --- .../CreateNewClientScreen.android.kt | 5 ++- .../createNewClient/CreateNewClientScreen.kt | 37 ++++++++++++------- .../CreateNewClientViewModel.kt | 25 +++++++++---- .../CreateNewClientScreen.desktop.kt | 3 +- .../CreateNewClientScreen.native.kt | 3 +- 5 files changed, 49 insertions(+), 24 deletions(-) diff --git a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.android.kt b/feature/client/src/androidMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.android.kt index 077cbd7f1e7..8d2cb71a3a5 100644 --- a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.android.kt +++ b/feature/client/src/androidMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.android.kt @@ -15,6 +15,7 @@ import androidx.compose.runtime.Composable import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.rememberPermissionState import com.mifos.feature.client.utils.PlatformCameraLauncher +import io.github.vinceglb.filekit.PlatformFile import io.github.vinceglb.filekit.dialogs.compose.rememberCameraPickerLauncher import io.github.vinceglb.filekit.path @@ -27,12 +28,12 @@ actual object PhoneNumberUtil { @OptIn(ExperimentalPermissionsApi::class) @Composable actual fun rememberPlatformCameraLauncher( - onImageCapturedPath: (String?) -> Unit, + onImageCapturedPath: (PlatformFile?) -> Unit, ): PlatformCameraLauncher { val permissionState = rememberPermissionState(Manifest.permission.CAMERA) val launcher = rememberCameraPickerLauncher { file -> - onImageCapturedPath(file?.path) + onImageCapturedPath(file) } return PlatformCameraLauncher( diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt index 4f27cc8ec7e..5bbf8318c5b 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt @@ -128,6 +128,7 @@ import kotlinx.datetime.Clock import org.jetbrains.compose.resources.getString import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource +import org.jetbrains.compose.ui.tooling.preview.Preview import org.jetbrains.compose.ui.tooling.preview.PreviewParameter import org.jetbrains.compose.ui.tooling.preview.PreviewParameterProvider import org.koin.compose.viewmodel.koinViewModel @@ -158,10 +159,13 @@ internal fun CreateNewClientScreen( navigateBack = navigateBack, loadStaffInOffice = { viewmodel.loadStaffInOffices(it) }, createClient = { viewmodel.createClient(clientPayload = it) }, - uploadImage = { id, selectedFilePath -> - viewmodel.uploadImage(id, PlatformFile(selectedFilePath)) + uploadImage = { id -> + viewmodel.uploadImage(id) }, hasDatatables = hasDatatables, + onImageSelected = { + viewmodel.updateSelectedImage(it) + } ) } @@ -173,12 +177,12 @@ internal fun CreateNewClientScreen( staffInOffices: List, loadStaffInOffice: (officeId: Int) -> Unit, navigateBack: () -> Unit, + onImageSelected:(PlatformFile?)->Unit, createClient: (clientPayload: ClientPayloadEntity) -> Unit, - uploadImage: (id: Int, imageFilePath: String) -> Unit, + uploadImage: (id: Int) -> Unit, hasDatatables: (datatables: List, clientPayload: ClientPayloadEntity) -> Unit, ) { var createClientWithImage by rememberSaveable { mutableStateOf(false) } - var clientImagePath by rememberSaveable { mutableStateOf(null) } val snackbarHostState = remember { SnackbarHostState() } val scope = rememberCoroutineScope() @@ -209,16 +213,16 @@ internal fun CreateNewClientScreen( onHasDatatables = hasDatatables, setFileForUpload = { filePath -> filePath?.let { - clientImagePath = it createClientWithImage = true } }, + onImageSelected = onImageSelected ) } is CreateNewClientUiState.SetClientId -> { if (createClientWithImage) { - clientImagePath?.let { uploadImage(uiState.id, it) } + uploadImage(uiState.id) } else { navigateBack.invoke() } @@ -281,6 +285,7 @@ private fun CreateNewClientContent( staffInOffices: List, clientTemplate: ClientsTemplateEntity, loadStaffInOffice: (Int) -> Unit, + onImageSelected:(PlatformFile?)->Unit, createClient: (ClientPayloadEntity) -> Unit, onHasDatatables: (List, ClientPayloadEntity) -> Unit, setFileForUpload: (filePath: String?) -> Unit, @@ -316,12 +321,18 @@ private fun CreateNewClientContent( val galleryLauncher = rememberFilePickerLauncher( type = FileKitType.Image, ) { file -> - file?.let { selectedImagePath = file.path } + file?.let { + selectedImagePath = file.path + onImageSelected(file) + } } val cameraLauncher = rememberPlatformCameraLauncher { - filePath -> - filePath?.let { selectedImagePath = filePath } + file -> + file?.let { + selectedImagePath = file.path + onImageSelected(file) + } } val hasDatatables by rememberSaveable { @@ -986,7 +997,7 @@ internal expect object PhoneNumberUtil { @Composable expect fun rememberPlatformCameraLauncher( - onImageCapturedPath: (String?) -> Unit, + onImageCapturedPath: (PlatformFile?) -> Unit, ): PlatformCameraLauncher private class CreateNewClientScreenPreviewProvider : @@ -1013,11 +1024,10 @@ private class CreateNewClientScreenPreviewProvider : } @Composable -@DevicePreview +@Preview private fun PreviewCreateNewClientScreen( @PreviewParameter(CreateNewClientScreenPreviewProvider::class) createNewClientUiState: CreateNewClientUiState, ) { - // ToDo : FIX Preview CreateNewClientScreen( uiState = createNewClientUiState, @@ -1027,7 +1037,8 @@ private fun PreviewCreateNewClientScreen( loadStaffInOffice = { }, navigateBack = { }, createClient = { }, - uploadImage = { _, _ -> }, + uploadImage = { _-> }, + onImageSelected = {} ) { _, _ -> } } diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt index 95d7663223f..64d91c31b0b 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt @@ -20,6 +20,7 @@ import androidclient.feature.client.generated.resources.feature_client_waiting_f import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import co.touchlab.kermit.Logger +import com.mifos.core.common.utils.DataState import com.mifos.core.common.utils.MFErrorParser import com.mifos.core.data.repository.CreateNewClientRepository import com.mifos.feature.client.utils.createImageRequestBody @@ -50,6 +51,12 @@ class CreateNewClientViewModel( private val _showOffices = MutableStateFlow>(emptyList()) val showOffices: StateFlow> get() = _showOffices + private val selectedImage = MutableStateFlow(null) + + fun updateSelectedImage(image:PlatformFile?){ + selectedImage.value=image + } + fun loadOfficeAndClientTemplate() { _createNewClientUiState.value = CreateNewClientUiState.ShowProgressbar // todo combine these 2 @@ -83,13 +90,14 @@ class CreateNewClientViewModel( fun loadStaffInOffices(officeId: Int) { viewModelScope.launch { - repository.getStaffInOffice(officeId) - .catch { - _createNewClientUiState.value = + repository.getStaffInOffice(officeId).collect { result-> + when(result) { + is DataState.Error -> _createNewClientUiState.value = CreateNewClientUiState.ShowError(Res.string.feature_client_failed_to_fetch_staffs) - }.collect { staffs -> - _staffInOffices.value = staffs.data ?: emptyList() + DataState.Loading -> Unit + is DataState.Success -> _staffInOffices.value = result.data } + } } } @@ -116,13 +124,16 @@ class CreateNewClientViewModel( } } - fun uploadImage(id: Int, imageFile: PlatformFile) { + fun uploadImage(id: Int) { + if(selectedImage.value==null){ + return + } _createNewClientUiState.value = CreateNewClientUiState.ShowProgress("Uploading Client's Picture...") viewModelScope.launch { try { - val requestFile = createImageRequestBody(imageFile) + val requestFile = createImageRequestBody(selectedImage.value!!) repository.uploadClientImage(id, requestFile) diff --git a/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.desktop.kt b/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.desktop.kt index 5f45812a559..0fa6a387e97 100644 --- a/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.desktop.kt +++ b/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.desktop.kt @@ -11,6 +11,7 @@ package com.mifos.feature.client.createNewClient import androidx.compose.runtime.Composable import com.mifos.feature.client.utils.PlatformCameraLauncher +import io.github.vinceglb.filekit.PlatformFile actual object PhoneNumberUtil { actual fun isGlobalPhoneNumber(phoneNumber: String): Boolean { @@ -20,6 +21,6 @@ actual object PhoneNumberUtil { } @Composable -actual fun rememberPlatformCameraLauncher(onImageCapturedPath: (String?) -> Unit): PlatformCameraLauncher { +actual fun rememberPlatformCameraLauncher(onImageCapturedPath: (PlatformFile?) -> Unit): PlatformCameraLauncher { TODO("Not yet implemented") } diff --git a/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.native.kt b/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.native.kt index 5f45812a559..0fa6a387e97 100644 --- a/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.native.kt +++ b/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.native.kt @@ -11,6 +11,7 @@ package com.mifos.feature.client.createNewClient import androidx.compose.runtime.Composable import com.mifos.feature.client.utils.PlatformCameraLauncher +import io.github.vinceglb.filekit.PlatformFile actual object PhoneNumberUtil { actual fun isGlobalPhoneNumber(phoneNumber: String): Boolean { @@ -20,6 +21,6 @@ actual object PhoneNumberUtil { } @Composable -actual fun rememberPlatformCameraLauncher(onImageCapturedPath: (String?) -> Unit): PlatformCameraLauncher { +actual fun rememberPlatformCameraLauncher(onImageCapturedPath: (PlatformFile?) -> Unit): PlatformCameraLauncher { TODO("Not yet implemented") } From 1ac0463e4b0132815df13b3a404994493d1372da Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sat, 28 Jun 2025 13:23:50 +0530 Subject: [PATCH 03/13] spotless issue --- .../demoDebugRuntimeClasspath.txt | 60 +++++++++---------- .../demoReleaseRuntimeClasspath.txt | 36 +++++------ .../prodDebugRuntimeClasspath.txt | 60 +++++++++---------- .../prodReleaseRuntimeClasspath.txt | 36 +++++------ .../entities/client/ClientPayloadEntity.kt | 2 +- .../CreateNewClientScreen.android.kt | 1 - .../createNewClient/CreateNewClientScreen.kt | 16 +++-- .../CreateNewClientViewModel.kt | 16 ++--- 8 files changed, 112 insertions(+), 115 deletions(-) diff --git a/cmp-android/dependencies/demoDebugRuntimeClasspath.txt b/cmp-android/dependencies/demoDebugRuntimeClasspath.txt index 8d501db2ba7..74a3dd22019 100644 --- a/cmp-android/dependencies/demoDebugRuntimeClasspath.txt +++ b/cmp-android/dependencies/demoDebugRuntimeClasspath.txt @@ -12,14 +12,14 @@ androidx.autofill:autofill:1.0.0 androidx.collection:collection-jvm:1.5.0 androidx.collection:collection-ktx:1.5.0 androidx.collection:collection:1.5.0 -androidx.compose.animation:animation-android:1.8.2 -androidx.compose.animation:animation-core-android:1.8.2 -androidx.compose.animation:animation-core:1.8.2 -androidx.compose.animation:animation:1.8.2 -androidx.compose.foundation:foundation-android:1.8.2 -androidx.compose.foundation:foundation-layout-android:1.8.2 -androidx.compose.foundation:foundation-layout:1.8.2 -androidx.compose.foundation:foundation:1.8.2 +androidx.compose.animation:animation-android:1.8.0 +androidx.compose.animation:animation-core-android:1.8.0 +androidx.compose.animation:animation-core:1.8.0 +androidx.compose.animation:animation:1.8.0 +androidx.compose.foundation:foundation-android:1.8.0 +androidx.compose.foundation:foundation-layout-android:1.8.0 +androidx.compose.foundation:foundation-layout:1.8.0 +androidx.compose.foundation:foundation:1.8.0 androidx.compose.material3:material3-android:1.3.1 androidx.compose.material3:material3:1.3.1 androidx.compose.material:material-android:1.7.6 @@ -30,28 +30,28 @@ androidx.compose.material:material-icons-extended:1.7.6 androidx.compose.material:material-ripple-android:1.7.6 androidx.compose.material:material-ripple:1.7.6 androidx.compose.material:material:1.7.6 -androidx.compose.runtime:runtime-android:1.8.2 -androidx.compose.runtime:runtime-saveable-android:1.8.2 -androidx.compose.runtime:runtime-saveable:1.8.2 -androidx.compose.runtime:runtime:1.8.2 -androidx.compose.ui:ui-android:1.8.2 -androidx.compose.ui:ui-geometry-android:1.8.2 -androidx.compose.ui:ui-geometry:1.8.2 -androidx.compose.ui:ui-graphics-android:1.8.2 -androidx.compose.ui:ui-graphics:1.8.2 -androidx.compose.ui:ui-text-android:1.8.2 -androidx.compose.ui:ui-text:1.8.2 -androidx.compose.ui:ui-tooling-android:1.8.2 -androidx.compose.ui:ui-tooling-data-android:1.8.2 -androidx.compose.ui:ui-tooling-data:1.8.2 -androidx.compose.ui:ui-tooling-preview-android:1.8.2 -androidx.compose.ui:ui-tooling-preview:1.8.2 -androidx.compose.ui:ui-tooling:1.8.2 -androidx.compose.ui:ui-unit-android:1.8.2 -androidx.compose.ui:ui-unit:1.8.2 -androidx.compose.ui:ui-util-android:1.8.2 -androidx.compose.ui:ui-util:1.8.2 -androidx.compose.ui:ui:1.8.2 +androidx.compose.runtime:runtime-android:1.8.0 +androidx.compose.runtime:runtime-saveable-android:1.8.0 +androidx.compose.runtime:runtime-saveable:1.8.0 +androidx.compose.runtime:runtime:1.8.0 +androidx.compose.ui:ui-android:1.8.0 +androidx.compose.ui:ui-geometry-android:1.8.0 +androidx.compose.ui:ui-geometry:1.8.0 +androidx.compose.ui:ui-graphics-android:1.8.0 +androidx.compose.ui:ui-graphics:1.8.0 +androidx.compose.ui:ui-text-android:1.8.0 +androidx.compose.ui:ui-text:1.8.0 +androidx.compose.ui:ui-tooling-android:1.8.0 +androidx.compose.ui:ui-tooling-data-android:1.8.0 +androidx.compose.ui:ui-tooling-data:1.8.0 +androidx.compose.ui:ui-tooling-preview-android:1.8.0 +androidx.compose.ui:ui-tooling-preview:1.8.0 +androidx.compose.ui:ui-tooling:1.8.0 +androidx.compose.ui:ui-unit-android:1.8.0 +androidx.compose.ui:ui-unit:1.8.0 +androidx.compose.ui:ui-util-android:1.8.0 +androidx.compose.ui:ui-util:1.8.0 +androidx.compose.ui:ui:1.8.0 androidx.compose:compose-bom:2025.01.00 androidx.concurrent:concurrent-futures:1.1.0 androidx.core:core-ktx:1.15.0 diff --git a/cmp-android/dependencies/demoReleaseRuntimeClasspath.txt b/cmp-android/dependencies/demoReleaseRuntimeClasspath.txt index 89c65282221..81553a4fa4f 100644 --- a/cmp-android/dependencies/demoReleaseRuntimeClasspath.txt +++ b/cmp-android/dependencies/demoReleaseRuntimeClasspath.txt @@ -30,24 +30,24 @@ androidx.compose.material:material-icons-extended:1.7.6 androidx.compose.material:material-ripple-android:1.7.6 androidx.compose.material:material-ripple:1.7.6 androidx.compose.material:material:1.7.6 -androidx.compose.runtime:runtime-android:1.8.2 -androidx.compose.runtime:runtime-saveable-android:1.8.2 -androidx.compose.runtime:runtime-saveable:1.8.2 -androidx.compose.runtime:runtime:1.8.2 -androidx.compose.ui:ui-android:1.8.2 -androidx.compose.ui:ui-geometry-android:1.8.2 -androidx.compose.ui:ui-geometry:1.8.2 -androidx.compose.ui:ui-graphics-android:1.8.2 -androidx.compose.ui:ui-graphics:1.8.2 -androidx.compose.ui:ui-text-android:1.8.2 -androidx.compose.ui:ui-text:1.8.2 -androidx.compose.ui:ui-tooling-preview-android:1.8.2 -androidx.compose.ui:ui-tooling-preview:1.8.2 -androidx.compose.ui:ui-unit-android:1.8.2 -androidx.compose.ui:ui-unit:1.8.2 -androidx.compose.ui:ui-util-android:1.8.2 -androidx.compose.ui:ui-util:1.8.2 -androidx.compose.ui:ui:1.8.2 +androidx.compose.runtime:runtime-android:1.8.0 +androidx.compose.runtime:runtime-saveable-android:1.8.0 +androidx.compose.runtime:runtime-saveable:1.8.0 +androidx.compose.runtime:runtime:1.8.0 +androidx.compose.ui:ui-android:1.8.0 +androidx.compose.ui:ui-geometry-android:1.8.0 +androidx.compose.ui:ui-geometry:1.8.0 +androidx.compose.ui:ui-graphics-android:1.8.0 +androidx.compose.ui:ui-graphics:1.8.0 +androidx.compose.ui:ui-text-android:1.8.0 +androidx.compose.ui:ui-text:1.8.0 +androidx.compose.ui:ui-tooling-preview-android:1.8.0 +androidx.compose.ui:ui-tooling-preview:1.8.0 +androidx.compose.ui:ui-unit-android:1.8.0 +androidx.compose.ui:ui-unit:1.8.0 +androidx.compose.ui:ui-util-android:1.8.0 +androidx.compose.ui:ui-util:1.8.0 +androidx.compose.ui:ui:1.8.0 androidx.compose:compose-bom:2025.01.00 androidx.concurrent:concurrent-futures:1.1.0 androidx.core:core-ktx:1.15.0 diff --git a/cmp-android/dependencies/prodDebugRuntimeClasspath.txt b/cmp-android/dependencies/prodDebugRuntimeClasspath.txt index 8d501db2ba7..74a3dd22019 100644 --- a/cmp-android/dependencies/prodDebugRuntimeClasspath.txt +++ b/cmp-android/dependencies/prodDebugRuntimeClasspath.txt @@ -12,14 +12,14 @@ androidx.autofill:autofill:1.0.0 androidx.collection:collection-jvm:1.5.0 androidx.collection:collection-ktx:1.5.0 androidx.collection:collection:1.5.0 -androidx.compose.animation:animation-android:1.8.2 -androidx.compose.animation:animation-core-android:1.8.2 -androidx.compose.animation:animation-core:1.8.2 -androidx.compose.animation:animation:1.8.2 -androidx.compose.foundation:foundation-android:1.8.2 -androidx.compose.foundation:foundation-layout-android:1.8.2 -androidx.compose.foundation:foundation-layout:1.8.2 -androidx.compose.foundation:foundation:1.8.2 +androidx.compose.animation:animation-android:1.8.0 +androidx.compose.animation:animation-core-android:1.8.0 +androidx.compose.animation:animation-core:1.8.0 +androidx.compose.animation:animation:1.8.0 +androidx.compose.foundation:foundation-android:1.8.0 +androidx.compose.foundation:foundation-layout-android:1.8.0 +androidx.compose.foundation:foundation-layout:1.8.0 +androidx.compose.foundation:foundation:1.8.0 androidx.compose.material3:material3-android:1.3.1 androidx.compose.material3:material3:1.3.1 androidx.compose.material:material-android:1.7.6 @@ -30,28 +30,28 @@ androidx.compose.material:material-icons-extended:1.7.6 androidx.compose.material:material-ripple-android:1.7.6 androidx.compose.material:material-ripple:1.7.6 androidx.compose.material:material:1.7.6 -androidx.compose.runtime:runtime-android:1.8.2 -androidx.compose.runtime:runtime-saveable-android:1.8.2 -androidx.compose.runtime:runtime-saveable:1.8.2 -androidx.compose.runtime:runtime:1.8.2 -androidx.compose.ui:ui-android:1.8.2 -androidx.compose.ui:ui-geometry-android:1.8.2 -androidx.compose.ui:ui-geometry:1.8.2 -androidx.compose.ui:ui-graphics-android:1.8.2 -androidx.compose.ui:ui-graphics:1.8.2 -androidx.compose.ui:ui-text-android:1.8.2 -androidx.compose.ui:ui-text:1.8.2 -androidx.compose.ui:ui-tooling-android:1.8.2 -androidx.compose.ui:ui-tooling-data-android:1.8.2 -androidx.compose.ui:ui-tooling-data:1.8.2 -androidx.compose.ui:ui-tooling-preview-android:1.8.2 -androidx.compose.ui:ui-tooling-preview:1.8.2 -androidx.compose.ui:ui-tooling:1.8.2 -androidx.compose.ui:ui-unit-android:1.8.2 -androidx.compose.ui:ui-unit:1.8.2 -androidx.compose.ui:ui-util-android:1.8.2 -androidx.compose.ui:ui-util:1.8.2 -androidx.compose.ui:ui:1.8.2 +androidx.compose.runtime:runtime-android:1.8.0 +androidx.compose.runtime:runtime-saveable-android:1.8.0 +androidx.compose.runtime:runtime-saveable:1.8.0 +androidx.compose.runtime:runtime:1.8.0 +androidx.compose.ui:ui-android:1.8.0 +androidx.compose.ui:ui-geometry-android:1.8.0 +androidx.compose.ui:ui-geometry:1.8.0 +androidx.compose.ui:ui-graphics-android:1.8.0 +androidx.compose.ui:ui-graphics:1.8.0 +androidx.compose.ui:ui-text-android:1.8.0 +androidx.compose.ui:ui-text:1.8.0 +androidx.compose.ui:ui-tooling-android:1.8.0 +androidx.compose.ui:ui-tooling-data-android:1.8.0 +androidx.compose.ui:ui-tooling-data:1.8.0 +androidx.compose.ui:ui-tooling-preview-android:1.8.0 +androidx.compose.ui:ui-tooling-preview:1.8.0 +androidx.compose.ui:ui-tooling:1.8.0 +androidx.compose.ui:ui-unit-android:1.8.0 +androidx.compose.ui:ui-unit:1.8.0 +androidx.compose.ui:ui-util-android:1.8.0 +androidx.compose.ui:ui-util:1.8.0 +androidx.compose.ui:ui:1.8.0 androidx.compose:compose-bom:2025.01.00 androidx.concurrent:concurrent-futures:1.1.0 androidx.core:core-ktx:1.15.0 diff --git a/cmp-android/dependencies/prodReleaseRuntimeClasspath.txt b/cmp-android/dependencies/prodReleaseRuntimeClasspath.txt index 89c65282221..81553a4fa4f 100644 --- a/cmp-android/dependencies/prodReleaseRuntimeClasspath.txt +++ b/cmp-android/dependencies/prodReleaseRuntimeClasspath.txt @@ -30,24 +30,24 @@ androidx.compose.material:material-icons-extended:1.7.6 androidx.compose.material:material-ripple-android:1.7.6 androidx.compose.material:material-ripple:1.7.6 androidx.compose.material:material:1.7.6 -androidx.compose.runtime:runtime-android:1.8.2 -androidx.compose.runtime:runtime-saveable-android:1.8.2 -androidx.compose.runtime:runtime-saveable:1.8.2 -androidx.compose.runtime:runtime:1.8.2 -androidx.compose.ui:ui-android:1.8.2 -androidx.compose.ui:ui-geometry-android:1.8.2 -androidx.compose.ui:ui-geometry:1.8.2 -androidx.compose.ui:ui-graphics-android:1.8.2 -androidx.compose.ui:ui-graphics:1.8.2 -androidx.compose.ui:ui-text-android:1.8.2 -androidx.compose.ui:ui-text:1.8.2 -androidx.compose.ui:ui-tooling-preview-android:1.8.2 -androidx.compose.ui:ui-tooling-preview:1.8.2 -androidx.compose.ui:ui-unit-android:1.8.2 -androidx.compose.ui:ui-unit:1.8.2 -androidx.compose.ui:ui-util-android:1.8.2 -androidx.compose.ui:ui-util:1.8.2 -androidx.compose.ui:ui:1.8.2 +androidx.compose.runtime:runtime-android:1.8.0 +androidx.compose.runtime:runtime-saveable-android:1.8.0 +androidx.compose.runtime:runtime-saveable:1.8.0 +androidx.compose.runtime:runtime:1.8.0 +androidx.compose.ui:ui-android:1.8.0 +androidx.compose.ui:ui-geometry-android:1.8.0 +androidx.compose.ui:ui-geometry:1.8.0 +androidx.compose.ui:ui-graphics-android:1.8.0 +androidx.compose.ui:ui-graphics:1.8.0 +androidx.compose.ui:ui-text-android:1.8.0 +androidx.compose.ui:ui-text:1.8.0 +androidx.compose.ui:ui-tooling-preview-android:1.8.0 +androidx.compose.ui:ui-tooling-preview:1.8.0 +androidx.compose.ui:ui-unit-android:1.8.0 +androidx.compose.ui:ui-unit:1.8.0 +androidx.compose.ui:ui-util-android:1.8.0 +androidx.compose.ui:ui-util:1.8.0 +androidx.compose.ui:ui:1.8.0 androidx.compose:compose-bom:2025.01.00 androidx.concurrent:concurrent-futures:1.1.0 androidx.core:core-ktx:1.15.0 diff --git a/core/database/src/commonMain/kotlin/com/mifos/room/entities/client/ClientPayloadEntity.kt b/core/database/src/commonMain/kotlin/com/mifos/room/entities/client/ClientPayloadEntity.kt index f66eeff86f3..ac3881d994a 100644 --- a/core/database/src/commonMain/kotlin/com/mifos/room/entities/client/ClientPayloadEntity.kt +++ b/core/database/src/commonMain/kotlin/com/mifos/room/entities/client/ClientPayloadEntity.kt @@ -72,5 +72,5 @@ data class ClientPayloadEntity( // TODO add legal form id field // 1 for Person (Individual client) - val legalFormId: Int ?=null, + val legalFormId: Int? = null, ) : Parcelable diff --git a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.android.kt b/feature/client/src/androidMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.android.kt index 8d2cb71a3a5..f8caa7eb9e3 100644 --- a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.android.kt +++ b/feature/client/src/androidMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.android.kt @@ -17,7 +17,6 @@ import com.google.accompanist.permissions.rememberPermissionState import com.mifos.feature.client.utils.PlatformCameraLauncher import io.github.vinceglb.filekit.PlatformFile import io.github.vinceglb.filekit.dialogs.compose.rememberCameraPickerLauncher -import io.github.vinceglb.filekit.path actual object PhoneNumberUtil { actual fun isGlobalPhoneNumber(phoneNumber: String): Boolean { diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt index 5bbf8318c5b..37938b4a6a9 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt @@ -111,7 +111,6 @@ import com.mifos.core.designsystem.component.MifosOutlinedTextField import com.mifos.core.designsystem.component.MifosScaffold import com.mifos.core.designsystem.component.MifosSweetError import com.mifos.core.designsystem.component.MifosTextFieldDropdown -import com.mifos.core.ui.util.DevicePreview import com.mifos.feature.client.utils.PlatformCameraLauncher import com.mifos.room.entities.client.ClientPayloadEntity import com.mifos.room.entities.noncore.DataTableEntity @@ -165,7 +164,7 @@ internal fun CreateNewClientScreen( hasDatatables = hasDatatables, onImageSelected = { viewmodel.updateSelectedImage(it) - } + }, ) } @@ -177,7 +176,7 @@ internal fun CreateNewClientScreen( staffInOffices: List, loadStaffInOffice: (officeId: Int) -> Unit, navigateBack: () -> Unit, - onImageSelected:(PlatformFile?)->Unit, + onImageSelected: (PlatformFile?) -> Unit, createClient: (clientPayload: ClientPayloadEntity) -> Unit, uploadImage: (id: Int) -> Unit, hasDatatables: (datatables: List, clientPayload: ClientPayloadEntity) -> Unit, @@ -216,7 +215,7 @@ internal fun CreateNewClientScreen( createClientWithImage = true } }, - onImageSelected = onImageSelected + onImageSelected = onImageSelected, ) } @@ -285,7 +284,7 @@ private fun CreateNewClientContent( staffInOffices: List, clientTemplate: ClientsTemplateEntity, loadStaffInOffice: (Int) -> Unit, - onImageSelected:(PlatformFile?)->Unit, + onImageSelected: (PlatformFile?) -> Unit, createClient: (ClientPayloadEntity) -> Unit, onHasDatatables: (List, ClientPayloadEntity) -> Unit, setFileForUpload: (filePath: String?) -> Unit, @@ -680,7 +679,7 @@ private fun createClientPayload( firstname = firstName, lastname = lastName, officeId = selectedOfficeId, - legalFormId=1, + legalFormId = 1, // Optional fields with default values active = isActive, @@ -1028,7 +1027,6 @@ private class CreateNewClientScreenPreviewProvider : private fun PreviewCreateNewClientScreen( @PreviewParameter(CreateNewClientScreenPreviewProvider::class) createNewClientUiState: CreateNewClientUiState, ) { - CreateNewClientScreen( uiState = createNewClientUiState, onRetry = { }, @@ -1037,8 +1035,8 @@ private fun PreviewCreateNewClientScreen( loadStaffInOffice = { }, navigateBack = { }, createClient = { }, - uploadImage = { _-> }, - onImageSelected = {} + uploadImage = { _ -> }, + onImageSelected = {}, ) { _, _ -> } } diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt index 64d91c31b0b..9209212a81c 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt @@ -19,7 +19,6 @@ import androidclient.feature.client.generated.resources.feature_client_failed_to import androidclient.feature.client.generated.resources.feature_client_waiting_for_checker_approval import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import co.touchlab.kermit.Logger import com.mifos.core.common.utils.DataState import com.mifos.core.common.utils.MFErrorParser import com.mifos.core.data.repository.CreateNewClientRepository @@ -53,8 +52,8 @@ class CreateNewClientViewModel( private val selectedImage = MutableStateFlow(null) - fun updateSelectedImage(image:PlatformFile?){ - selectedImage.value=image + fun updateSelectedImage(image: PlatformFile?) { + selectedImage.value = image } fun loadOfficeAndClientTemplate() { @@ -90,10 +89,11 @@ class CreateNewClientViewModel( fun loadStaffInOffices(officeId: Int) { viewModelScope.launch { - repository.getStaffInOffice(officeId).collect { result-> - when(result) { - is DataState.Error -> _createNewClientUiState.value = - CreateNewClientUiState.ShowError(Res.string.feature_client_failed_to_fetch_staffs) + repository.getStaffInOffice(officeId).collect { result -> + when (result) { + is DataState.Error -> + _createNewClientUiState.value = + CreateNewClientUiState.ShowError(Res.string.feature_client_failed_to_fetch_staffs) DataState.Loading -> Unit is DataState.Success -> _staffInOffices.value = result.data } @@ -125,7 +125,7 @@ class CreateNewClientViewModel( } fun uploadImage(id: Int) { - if(selectedImage.value==null){ + if (selectedImage.value == null) { return } _createNewClientUiState.value = From 19a6c18ad9f80e7a7c212dc3dd86e5b8f1ad36bb Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sat, 28 Jun 2025 17:34:44 +0530 Subject: [PATCH 04/13] client image update --- .../core/domain/useCases/UploadClientImageUseCase.kt | 12 +++++------- .../client/clientDetails/ClientDetailsScreen.kt | 10 +++++++--- .../client/clientDetails/ClientDetailsUiState.kt | 2 +- .../client/clientDetails/ClientDetailsViewModel.kt | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt b/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt index 974401a7e89..9b671fc6062 100644 --- a/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt +++ b/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt @@ -10,6 +10,7 @@ package com.mifos.core.domain.useCases import com.mifos.core.common.utils.DataState +import com.mifos.core.common.utils.asDataStateFlow import com.mifos.core.data.repository.ClientDetailsRepository import core.domain.generated.resources.Res import core.domain.generated.resources.core_domain_client_image_uploaded_successfully @@ -26,13 +27,10 @@ class UploadClientImageUseCase( private val repository: ClientDetailsRepository, ) { - operator fun invoke(id: Int, image: MultiPartFormDataContent): Flow> = flow { - try { - emit(DataState.Loading) + operator fun invoke(id: Int, image: MultiPartFormDataContent): Flow>{ + return flow { repository.uploadClientImage(id, image) - DataState.Success(getString(Res.string.core_domain_client_image_uploaded_successfully)) - } catch (e: Exception) { - DataState.Error(e) - } + emit(getString(Res.string.core_domain_client_image_uploaded_successfully)) + }.asDataStateFlow() } } diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt index 070fd617d73..c09c3e508d9 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt @@ -329,6 +329,9 @@ internal fun ClientDetailsScreen( padding = padding, loanAccountSelected = loanAccountSelected, savingsAccountSelected = savingsAccountSelected, + onClick = { + showSelectImageDialog=true + } ) } } @@ -339,15 +342,14 @@ internal fun ClientDetailsScreen( private fun MifosClientDetailsScreen( loanAccountSelected: (Int) -> Unit, padding: PaddingValues, + onClick:()->Unit, savingsAccountSelected: (Int, SavingAccountDepositTypeEntity) -> Unit, clientDetailsViewModel: ClientDetailsViewModel = koinViewModel(), ) { val client = clientDetailsViewModel.client.collectAsStateWithLifecycle().value - val scope = rememberCoroutineScope() val loanAccounts = clientDetailsViewModel.loanAccount.collectAsStateWithLifecycle().value val savingsAccounts = clientDetailsViewModel.savingsAccounts.collectAsStateWithLifecycle().value val profileImage = clientDetailsViewModel.profileImage.collectAsStateWithLifecycle() - var showSelectImageDialog by remember { mutableStateOf(false) } Column( modifier = Modifier @@ -362,7 +364,9 @@ private fun MifosClientDetailsScreen( ) { MifosUserImage( bitmap = profileImage.value, - modifier = Modifier.size(100.dp), + modifier = Modifier + .size(100.dp) + .clickable(onClick=onClick), username = client?.displayName ?: "", ) } diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsUiState.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsUiState.kt index 461be2df2a0..f5879f35c79 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsUiState.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsUiState.kt @@ -14,7 +14,7 @@ package com.mifos.feature.client.clientDetails */ sealed class ClientDetailsUiState { - data class ShowUploadImageSuccessfully(val response: String, val imagePath: String?) : + data class ShowUploadImageSuccessfully(val response: String) : ClientDetailsUiState() data object ShowClientImageDeletedSuccessfully : ClientDetailsUiState() diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt index b14a6c9ef00..17d2b7a9ebd 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt @@ -86,8 +86,8 @@ class ClientDetailsViewModel( is DataState.Success -> { _clientDetailsUiState.value = ClientDetailsUiState.ShowUploadImageSuccessfully( result.data, - imageFile.absolutePath(), ) + getUserProfile() _showLoading.value = false } } From fc6530db31e8a4fa79c791ffd7bac53c6bd45af0 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sat, 28 Jun 2025 19:05:32 +0530 Subject: [PATCH 05/13] client image update --- .../clientDetails/ClientDetailsScreen.android.kt | 7 ++++--- .../client/clientDetails/ClientDetailsScreen.kt | 12 +++++++----- .../client/clientDetails/ClientDetailsViewModel.kt | 5 ++++- .../clientDetails/ClientDetailsScreen.desktop.kt | 7 ++----- .../clientDetails/ClientDetailsScreen.native.kt | 7 ++----- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.android.kt b/feature/client/src/androidMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.android.kt index 6b2b7a4099d..fa793e1eecd 100644 --- a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.android.kt +++ b/feature/client/src/androidMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.android.kt @@ -14,18 +14,19 @@ import androidx.compose.runtime.Composable import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.rememberPermissionState import com.mifos.feature.client.utils.PlatformCameraLauncher +import io.github.vinceglb.filekit.PlatformFile import io.github.vinceglb.filekit.dialogs.compose.rememberCameraPickerLauncher +import io.github.vinceglb.filekit.path @OptIn(ExperimentalPermissionsApi::class) @Composable actual fun rememberPlatformCameraLauncher( - clientId: Int, - viewModel: ClientDetailsViewModel, + onImageCapturedPath: (PlatformFile?) -> Unit, ): PlatformCameraLauncher { val permissionState = rememberPermissionState(Manifest.permission.CAMERA) val launcher = rememberCameraPickerLauncher { file -> - file?.let { viewModel.saveClientImage(clientId, it) } + onImageCapturedPath(file) } return PlatformCameraLauncher( diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt index c09c3e508d9..a9ba5986c83 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt @@ -108,6 +108,7 @@ import com.mifos.feature.client.utils.PlatformCameraLauncher import com.mifos.room.entities.accounts.loans.LoanAccountEntity import com.mifos.room.entities.accounts.savings.SavingAccountDepositTypeEntity import com.mifos.room.entities.accounts.savings.SavingsAccountEntity +import io.github.vinceglb.filekit.PlatformFile import io.github.vinceglb.filekit.dialogs.FileKitType import io.github.vinceglb.filekit.dialogs.compose.rememberFilePickerLauncher import org.jetbrains.compose.resources.getString @@ -156,9 +157,11 @@ internal fun ClientDetailsScreen( } } - val cameraLauncher = rememberPlatformCameraLauncher( - clientId, - clientDetailsViewModel, + val cameraLauncher = rememberPlatformCameraLauncher( onImageCapturedPath = { + file-> + showSelectImageDialog = false + clientDetailsViewModel.saveClientImage(clientId,file) + } ) LaunchedEffect(key1 = true) { @@ -864,8 +867,7 @@ private fun MifosClientDetailsText(icon: ImageVector, field: String, value: Stri @Composable expect fun rememberPlatformCameraLauncher( - clientId: Int, - viewModel: ClientDetailsViewModel, + onImageCapturedPath: (PlatformFile?) -> Unit, ): PlatformCameraLauncher @DevicePreview diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt index 17d2b7a9ebd..d23b18f2993 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt @@ -12,6 +12,7 @@ package com.mifos.feature.client.clientDetails import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import co.touchlab.kermit.Logger import com.mifos.core.common.utils.Constants import com.mifos.core.common.utils.DataState import com.mifos.core.data.repository.ClientDetailsRepository @@ -130,7 +131,8 @@ class ClientDetailsViewModel( } } - fun saveClientImage(clientId: Int, imageFile: PlatformFile) { + fun saveClientImage(clientId: Int, imageFile: PlatformFile?) { + if(imageFile==null)return viewModelScope.launch { saveAutoClientImage(clientId, imageFile) } @@ -142,6 +144,7 @@ class ClientDetailsViewModel( file = imageFile, imageFormat = ImageFormat.PNG, quality = 100, + maxHeight=150 ) val outFile = FileKit.filesDir / "client_image_$clientId.png" outFile.write(bytes) diff --git a/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.desktop.kt b/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.desktop.kt index cff5e70dafa..4c0cf428a89 100644 --- a/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.desktop.kt +++ b/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.desktop.kt @@ -13,9 +13,6 @@ import androidx.compose.runtime.Composable import com.mifos.feature.client.utils.PlatformCameraLauncher @Composable -actual fun rememberPlatformCameraLauncher( - clientId: Int, - viewModel: ClientDetailsViewModel, -): PlatformCameraLauncher { +actual fun rememberPlatformCameraLauncher(onImageCapturedPath: (String?) -> Unit): PlatformCameraLauncher { TODO("Not yet implemented") -} +} \ No newline at end of file diff --git a/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.native.kt b/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.native.kt index cff5e70dafa..4c0cf428a89 100644 --- a/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.native.kt +++ b/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.native.kt @@ -13,9 +13,6 @@ import androidx.compose.runtime.Composable import com.mifos.feature.client.utils.PlatformCameraLauncher @Composable -actual fun rememberPlatformCameraLauncher( - clientId: Int, - viewModel: ClientDetailsViewModel, -): PlatformCameraLauncher { +actual fun rememberPlatformCameraLauncher(onImageCapturedPath: (String?) -> Unit): PlatformCameraLauncher { TODO("Not yet implemented") -} +} \ No newline at end of file From 2234ed65518c42b69eed1c80c8c6184dade976ed Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sat, 28 Jun 2025 19:12:40 +0530 Subject: [PATCH 06/13] moved repetable logic to utils --- .../ClientDetailsScreen.android.kt | 36 ------------------- .../utils/PlatformCameraLauncher.android.kt | 22 ++++++++++++ .../clientDetails/ClientDetailsScreen.kt | 6 +--- .../client/utils/PlatformCameraLauncher.kt | 8 +++++ .../ClientDetailsScreen.desktop.kt | 18 ---------- .../utils/PlatformCameraLauncher.desktop.kt | 8 +++++ .../ClientDetailsScreen.native.kt | 18 ---------- .../utils/PlatformCameraLauncher.native.kt | 8 +++++ 8 files changed, 47 insertions(+), 77 deletions(-) delete mode 100644 feature/client/src/androidMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.android.kt delete mode 100644 feature/client/src/desktopMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.desktop.kt delete mode 100644 feature/client/src/nativeMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.native.kt diff --git a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.android.kt b/feature/client/src/androidMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.android.kt deleted file mode 100644 index fa793e1eecd..00000000000 --- a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.android.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2025 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/android-client/blob/master/LICENSE.md - */ -package com.mifos.feature.client.clientDetails - -import android.Manifest -import androidx.compose.runtime.Composable -import com.google.accompanist.permissions.ExperimentalPermissionsApi -import com.google.accompanist.permissions.rememberPermissionState -import com.mifos.feature.client.utils.PlatformCameraLauncher -import io.github.vinceglb.filekit.PlatformFile -import io.github.vinceglb.filekit.dialogs.compose.rememberCameraPickerLauncher -import io.github.vinceglb.filekit.path - -@OptIn(ExperimentalPermissionsApi::class) -@Composable -actual fun rememberPlatformCameraLauncher( - onImageCapturedPath: (PlatformFile?) -> Unit, -): PlatformCameraLauncher { - val permissionState = rememberPermissionState(Manifest.permission.CAMERA) - - val launcher = rememberCameraPickerLauncher { file -> - onImageCapturedPath(file) - } - - return PlatformCameraLauncher( - permissionState = permissionState, - launcher = launcher, - ) -} diff --git a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.android.kt b/feature/client/src/androidMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.android.kt index 28674616315..b4559608985 100644 --- a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.android.kt +++ b/feature/client/src/androidMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.android.kt @@ -9,10 +9,15 @@ */ package com.mifos.feature.client.utils +import android.Manifest +import androidx.compose.runtime.Composable import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.PermissionState import com.google.accompanist.permissions.isGranted +import com.google.accompanist.permissions.rememberPermissionState +import io.github.vinceglb.filekit.PlatformFile import io.github.vinceglb.filekit.dialogs.compose.PhotoResultLauncher +import io.github.vinceglb.filekit.dialogs.compose.rememberCameraPickerLauncher @OptIn(ExperimentalPermissionsApi::class) actual class PlatformCameraLauncher @@ -28,3 +33,20 @@ internal constructor( } } } + +@OptIn(ExperimentalPermissionsApi::class) +@Composable +actual fun rememberPlatformCameraLauncher( + onImageCapturedPath: (PlatformFile?) -> Unit, +): PlatformCameraLauncher { + val permissionState = rememberPermissionState(Manifest.permission.CAMERA) + + val launcher = rememberCameraPickerLauncher { file -> + onImageCapturedPath(file) + } + + return PlatformCameraLauncher( + permissionState = permissionState, + launcher = launcher, + ) +} \ No newline at end of file diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt index a9ba5986c83..84fb4532d09 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt @@ -105,6 +105,7 @@ import com.mifos.core.designsystem.icon.MifosIcons import com.mifos.core.ui.components.MifosUserImage import com.mifos.core.ui.util.DevicePreview import com.mifos.feature.client.utils.PlatformCameraLauncher +import com.mifos.feature.client.utils.rememberPlatformCameraLauncher import com.mifos.room.entities.accounts.loans.LoanAccountEntity import com.mifos.room.entities.accounts.savings.SavingAccountDepositTypeEntity import com.mifos.room.entities.accounts.savings.SavingsAccountEntity @@ -865,11 +866,6 @@ private fun MifosClientDetailsText(icon: ImageVector, field: String, value: Stri } } -@Composable -expect fun rememberPlatformCameraLauncher( - onImageCapturedPath: (PlatformFile?) -> Unit, -): PlatformCameraLauncher - @DevicePreview @Composable private fun ClientDetailsScreenPreview() { diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.kt index 406f5ba45e1..b856363aa67 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.kt @@ -9,6 +9,14 @@ */ package com.mifos.feature.client.utils +import androidx.compose.runtime.Composable +import io.github.vinceglb.filekit.PlatformFile + expect class PlatformCameraLauncher { fun launch() } + +@Composable +expect fun rememberPlatformCameraLauncher( + onImageCapturedPath: (PlatformFile?) -> Unit, +): PlatformCameraLauncher \ No newline at end of file diff --git a/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.desktop.kt b/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.desktop.kt deleted file mode 100644 index 4c0cf428a89..00000000000 --- a/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.desktop.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2025 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/android-client/blob/master/LICENSE.md - */ -package com.mifos.feature.client.clientDetails - -import androidx.compose.runtime.Composable -import com.mifos.feature.client.utils.PlatformCameraLauncher - -@Composable -actual fun rememberPlatformCameraLauncher(onImageCapturedPath: (String?) -> Unit): PlatformCameraLauncher { - TODO("Not yet implemented") -} \ No newline at end of file diff --git a/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.desktop.kt b/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.desktop.kt index d810cf3eef4..74c51885f42 100644 --- a/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.desktop.kt +++ b/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.desktop.kt @@ -9,7 +9,15 @@ */ package com.mifos.feature.client.utils +import androidx.compose.runtime.Composable +import io.github.vinceglb.filekit.PlatformFile + actual class PlatformCameraLauncher { actual fun launch() { } } + +@Composable +actual fun rememberPlatformCameraLauncher(onImageCapturedPath: (PlatformFile?) -> Unit): PlatformCameraLauncher { + TODO("Not yet implemented") +} \ No newline at end of file diff --git a/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.native.kt b/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.native.kt deleted file mode 100644 index 4c0cf428a89..00000000000 --- a/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.native.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2025 Mifos Initiative - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * See https://github.com/openMF/android-client/blob/master/LICENSE.md - */ -package com.mifos.feature.client.clientDetails - -import androidx.compose.runtime.Composable -import com.mifos.feature.client.utils.PlatformCameraLauncher - -@Composable -actual fun rememberPlatformCameraLauncher(onImageCapturedPath: (String?) -> Unit): PlatformCameraLauncher { - TODO("Not yet implemented") -} \ No newline at end of file diff --git a/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.native.kt b/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.native.kt index d810cf3eef4..74c51885f42 100644 --- a/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.native.kt +++ b/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.native.kt @@ -9,7 +9,15 @@ */ package com.mifos.feature.client.utils +import androidx.compose.runtime.Composable +import io.github.vinceglb.filekit.PlatformFile + actual class PlatformCameraLauncher { actual fun launch() { } } + +@Composable +actual fun rememberPlatformCameraLauncher(onImageCapturedPath: (PlatformFile?) -> Unit): PlatformCameraLauncher { + TODO("Not yet implemented") +} \ No newline at end of file From 5e651bd7c8fc4c38a2b6b7f6748ac11fe2a344e8 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sat, 28 Jun 2025 19:18:48 +0530 Subject: [PATCH 07/13] removed the logic from craete client as we can use from utils --- .../CreateNewClientScreen.android.kt | 17 ----------------- .../createNewClient/CreateNewClientScreen.kt | 6 +----- .../CreateNewClientScreen.desktop.kt | 5 ----- .../CreateNewClientScreen.native.kt | 5 ----- 4 files changed, 1 insertion(+), 32 deletions(-) diff --git a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.android.kt b/feature/client/src/androidMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.android.kt index f8caa7eb9e3..3c62d8ba4d4 100644 --- a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.android.kt +++ b/feature/client/src/androidMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.android.kt @@ -23,20 +23,3 @@ actual object PhoneNumberUtil { return PhoneNumberUtils.isGlobalPhoneNumber(phoneNumber) } } - -@OptIn(ExperimentalPermissionsApi::class) -@Composable -actual fun rememberPlatformCameraLauncher( - onImageCapturedPath: (PlatformFile?) -> Unit, -): PlatformCameraLauncher { - val permissionState = rememberPermissionState(Manifest.permission.CAMERA) - - val launcher = rememberCameraPickerLauncher { file -> - onImageCapturedPath(file) - } - - return PlatformCameraLauncher( - permissionState = permissionState, - launcher = launcher, - ) -} diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt index 37938b4a6a9..e07418ad6dc 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt @@ -112,6 +112,7 @@ import com.mifos.core.designsystem.component.MifosScaffold import com.mifos.core.designsystem.component.MifosSweetError import com.mifos.core.designsystem.component.MifosTextFieldDropdown import com.mifos.feature.client.utils.PlatformCameraLauncher +import com.mifos.feature.client.utils.rememberPlatformCameraLauncher import com.mifos.room.entities.client.ClientPayloadEntity import com.mifos.room.entities.noncore.DataTableEntity import com.mifos.room.entities.organisation.OfficeEntity @@ -994,11 +995,6 @@ internal expect object PhoneNumberUtil { fun isGlobalPhoneNumber(phoneNumber: String): Boolean } -@Composable -expect fun rememberPlatformCameraLauncher( - onImageCapturedPath: (PlatformFile?) -> Unit, -): PlatformCameraLauncher - private class CreateNewClientScreenPreviewProvider : PreviewParameterProvider { override val values: Sequence diff --git a/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.desktop.kt b/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.desktop.kt index 0fa6a387e97..45c3ea10bbe 100644 --- a/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.desktop.kt +++ b/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.desktop.kt @@ -19,8 +19,3 @@ actual object PhoneNumberUtil { return phoneNumber.isNotBlank() && phoneNumber.all { it.isDigit() || it == '+' } } } - -@Composable -actual fun rememberPlatformCameraLauncher(onImageCapturedPath: (PlatformFile?) -> Unit): PlatformCameraLauncher { - TODO("Not yet implemented") -} diff --git a/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.native.kt b/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.native.kt index 0fa6a387e97..45c3ea10bbe 100644 --- a/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.native.kt +++ b/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.native.kt @@ -19,8 +19,3 @@ actual object PhoneNumberUtil { return phoneNumber.isNotBlank() && phoneNumber.all { it.isDigit() || it == '+' } } } - -@Composable -actual fun rememberPlatformCameraLauncher(onImageCapturedPath: (PlatformFile?) -> Unit): PlatformCameraLauncher { - TODO("Not yet implemented") -} From f5f6918720b39c23c9892be64d4303f452517f5a Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sat, 28 Jun 2025 19:54:32 +0530 Subject: [PATCH 08/13] updated --- .../useCases/UploadClientImageUseCase.kt | 2 +- .../clientDetails/ClientDetailsViewModel.kt | 21 +++++-------------- .../CreateNewClientViewModel.kt | 4 +++- .../feature/client/utils/CompressImage.kt | 21 +++++++++++++++++++ 4 files changed, 30 insertions(+), 18 deletions(-) create mode 100644 feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/CompressImage.kt diff --git a/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt b/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt index 9b671fc6062..baf8b276330 100644 --- a/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt +++ b/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt @@ -27,7 +27,7 @@ class UploadClientImageUseCase( private val repository: ClientDetailsRepository, ) { - operator fun invoke(id: Int, image: MultiPartFormDataContent): Flow>{ + operator fun invoke(id: Int, image: MultiPartFormDataContent): Flow> { return flow { repository.uploadClientImage(id, image) emit(getString(Res.string.core_domain_client_image_uploaded_successfully)) diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt index d23b18f2993..fa8a929b57b 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt @@ -12,25 +12,18 @@ package com.mifos.feature.client.clientDetails import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import co.touchlab.kermit.Logger import com.mifos.core.common.utils.Constants import com.mifos.core.common.utils.DataState import com.mifos.core.data.repository.ClientDetailsRepository import com.mifos.core.domain.useCases.GetClientDetailsUseCase import com.mifos.core.domain.useCases.UploadClientImageUseCase import com.mifos.core.ui.util.imageToByteArray +import com.mifos.feature.client.utils.compressImage import com.mifos.feature.client.utils.createImageRequestBody import com.mifos.room.entities.accounts.loans.LoanAccountEntity import com.mifos.room.entities.accounts.savings.SavingsAccountEntity import com.mifos.room.entities.client.ClientEntity -import io.github.vinceglb.filekit.FileKit -import io.github.vinceglb.filekit.ImageFormat import io.github.vinceglb.filekit.PlatformFile -import io.github.vinceglb.filekit.absolutePath -import io.github.vinceglb.filekit.compressImage -import io.github.vinceglb.filekit.div -import io.github.vinceglb.filekit.filesDir -import io.github.vinceglb.filekit.write import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch @@ -102,6 +95,7 @@ class ClientDetailsViewModel( _clientDetailsUiState.value = ClientDetailsUiState.ShowClientImageDeletedSuccessfully + _profileImage.value=null _showLoading.value = false } catch (e: Exception) { _clientDetailsUiState.value = @@ -140,16 +134,11 @@ class ClientDetailsViewModel( suspend fun saveAutoClientImage(clientId: Int, imageFile: PlatformFile) { try { - val bytes = FileKit.compressImage( - file = imageFile, - imageFormat = ImageFormat.PNG, - quality = 100, - maxHeight=150 - ) - val outFile = FileKit.filesDir / "client_image_$clientId.png" - outFile.write(bytes) + _showLoading.value = true + val outFile= compressImage(imageFile,clientId) uploadImage(clientId, outFile) } catch (e: Exception) { + _showLoading.value = false _clientDetailsUiState.value = ClientDetailsUiState.ShowError(e.message.toString()) } } diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt index 9209212a81c..c05c539b055 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt @@ -22,6 +22,7 @@ import androidx.lifecycle.viewModelScope import com.mifos.core.common.utils.DataState import com.mifos.core.common.utils.MFErrorParser import com.mifos.core.data.repository.CreateNewClientRepository +import com.mifos.feature.client.utils.compressImage import com.mifos.feature.client.utils.createImageRequestBody import com.mifos.room.entities.client.ClientPayloadEntity import com.mifos.room.entities.organisation.OfficeEntity @@ -133,7 +134,8 @@ class CreateNewClientViewModel( viewModelScope.launch { try { - val requestFile = createImageRequestBody(selectedImage.value!!) + val compressedImage= compressImage(selectedImage.value!!,id) + val requestFile = createImageRequestBody(compressedImage) repository.uploadClientImage(id, requestFile) diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/CompressImage.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/CompressImage.kt new file mode 100644 index 00000000000..d78e00331e9 --- /dev/null +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/CompressImage.kt @@ -0,0 +1,21 @@ +package com.mifos.feature.client.utils + +import io.github.vinceglb.filekit.FileKit +import io.github.vinceglb.filekit.ImageFormat +import io.github.vinceglb.filekit.PlatformFile +import io.github.vinceglb.filekit.compressImage +import io.github.vinceglb.filekit.div +import io.github.vinceglb.filekit.filesDir +import io.github.vinceglb.filekit.write + +suspend fun compressImage(imageFile: PlatformFile, clientId:Int):PlatformFile{ + val bytes = FileKit.compressImage( + file = imageFile, + imageFormat = ImageFormat.PNG, + quality = 100, + maxHeight=150 + ) + val outFile = FileKit.filesDir / "client_image_$clientId.png" + outFile.write(bytes) + return outFile +} \ No newline at end of file From 9587a311753a770557974f8e9223d507fef86ccf Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sat, 28 Jun 2025 20:42:10 +0530 Subject: [PATCH 09/13] updated --- feature/center/build.gradle.kts | 1 + .../createCenter/CreateNewCenterScreen.kt | 55 ++++++++----------- .../center/navigation/CenterNavigation.kt | 3 + .../createNewClient/CreateNewClientScreen.kt | 2 +- .../createNewGroup/CreateNewGroupScreen.kt | 6 +- .../groups/navigation/GroupNavGraph.kt | 3 + 6 files changed, 36 insertions(+), 34 deletions(-) diff --git a/feature/center/build.gradle.kts b/feature/center/build.gradle.kts index 3022cc671ab..605147ae554 100644 --- a/feature/center/build.gradle.kts +++ b/feature/center/build.gradle.kts @@ -23,6 +23,7 @@ kotlin{ implementation(projects.core.domain) implementation(compose.material3) implementation(compose.components.resources) + implementation(compose.components.uiToolingPreview) implementation(compose.ui) implementation(libs.androidx.paging.common) implementation(libs.coil.kt.compose) diff --git a/feature/center/src/commonMain/kotlin/com/mifos/feature/center/createCenter/CreateNewCenterScreen.kt b/feature/center/src/commonMain/kotlin/com/mifos/feature/center/createCenter/CreateNewCenterScreen.kt index 5125df82edf..448c6396f8b 100644 --- a/feature/center/src/commonMain/kotlin/com/mifos/feature/center/createCenter/CreateNewCenterScreen.kt +++ b/feature/center/src/commonMain/kotlin/com/mifos/feature/center/createCenter/CreateNewCenterScreen.kt @@ -72,10 +72,14 @@ import com.mifos.room.entities.organisation.OfficeEntity import kotlinx.datetime.Clock import org.jetbrains.compose.resources.getString import org.jetbrains.compose.resources.stringResource +import org.jetbrains.compose.ui.tooling.preview.Preview +import org.jetbrains.compose.ui.tooling.preview.PreviewParameter +import org.jetbrains.compose.ui.tooling.preview.PreviewParameterProvider import org.koin.compose.viewmodel.koinViewModel @Composable internal fun CreateNewCenterScreen( + onBackPressed: () -> Unit, onCreateSuccess: () -> Unit, viewModel: CreateNewCenterViewModel = koinViewModel(), ) { @@ -94,6 +98,7 @@ internal fun CreateNewCenterScreen( viewModel.createNewCenter(it) }, onCreateSuccess = onCreateSuccess, + onBackPressed=onBackPressed ) } @@ -103,13 +108,14 @@ internal fun CreateNewCenterScreen( onRetry: () -> Unit, createCenter: (CenterPayloadEntity) -> Unit, onCreateSuccess: () -> Unit, + onBackPressed: () -> Unit, ) { val snackbarHostState = remember { SnackbarHostState() } MifosScaffold( title = stringResource(Res.string.feature_center_create_new_center), snackbarHostState = snackbarHostState, - onBackPressed = {}, + onBackPressed = onBackPressed, ) { paddingValues -> Column(modifier = Modifier.padding(paddingValues)) { when (state) { @@ -306,46 +312,31 @@ private fun CreateNewCenterContent( } } -@DevicePreview -@Composable -private fun CreateNewCenterLoadingPreview() { - CreateNewCenterScreen( - state = CreateNewCenterUiState.Loading, - onRetry = {}, - createCenter = {}, - onCreateSuccess = {}, - ) -} -@DevicePreview -@Composable -private fun CreateNewCenterErrorPreview() { - CreateNewCenterScreen( - state = CreateNewCenterUiState.Error(Res.string.feature_center_failed_to_load_offices), - onRetry = {}, - createCenter = {}, - onCreateSuccess = {}, - ) -} +class CreateNewCenterUiStateProvider : PreviewParameterProvider { -@DevicePreview -@Composable -private fun CreateNewCenterOfficesPreview() { - CreateNewCenterScreen( - state = CreateNewCenterUiState.Offices(emptyList()), - onRetry = {}, - createCenter = {}, - onCreateSuccess = {}, + override val values = sequenceOf( + CreateNewCenterUiState.Loading, + CreateNewCenterUiState.Error(Res.string.feature_center_failed_to_load_offices), + CreateNewCenterUiState.Offices(sampleOfficeList), + CreateNewCenterUiState.CenterCreatedSuccessfully, ) } -@DevicePreview +@Preview @Composable -private fun CreateNewCenterCenterCreatedSuccessfullyPreview() { +private fun CreateNewCenterPreview( + @PreviewParameter(CreateNewCenterUiStateProvider::class) state: CreateNewCenterUiState, +) { CreateNewCenterScreen( - state = CreateNewCenterUiState.CenterCreatedSuccessfully, + state = state, onRetry = {}, createCenter = {}, onCreateSuccess = {}, + onBackPressed = {}, ) } + +val sampleOfficeList = List(10) { + OfficeEntity(id=it) +} \ No newline at end of file diff --git a/feature/center/src/commonMain/kotlin/com/mifos/feature/center/navigation/CenterNavigation.kt b/feature/center/src/commonMain/kotlin/com/mifos/feature/center/navigation/CenterNavigation.kt index 6762076e205..29dfd90ea36 100644 --- a/feature/center/src/commonMain/kotlin/com/mifos/feature/center/navigation/CenterNavigation.kt +++ b/feature/center/src/commonMain/kotlin/com/mifos/feature/center/navigation/CenterNavigation.kt @@ -49,6 +49,7 @@ fun NavGraphBuilder.centerNavGraph( loadClientsOfGroup = { }, ) createCenterScreenRoute( + onBackPressed = navController::popBackStack, onCreateSuccess = navController::popBackStack, ) } @@ -105,6 +106,7 @@ fun NavGraphBuilder.centerGroupListScreenRoute( } fun NavGraphBuilder.createCenterScreenRoute( + onBackPressed: () -> Unit, onCreateSuccess: () -> Unit, ) { composable( @@ -112,6 +114,7 @@ fun NavGraphBuilder.createCenterScreenRoute( ) { CreateNewCenterScreen( onCreateSuccess = onCreateSuccess, + onBackPressed=onBackPressed ) } } diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt index e07418ad6dc..657a56bfeaa 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt @@ -189,7 +189,7 @@ internal fun CreateNewClientScreen( MifosScaffold( title = stringResource(Res.string.feature_client_create_new_client), snackbarHostState = snackbarHostState, - onBackPressed = {}, + onBackPressed = navigateBack, ) { paddingValues -> Column(modifier = Modifier.padding(paddingValues)) { when (uiState) { diff --git a/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/createNewGroup/CreateNewGroupScreen.kt b/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/createNewGroup/CreateNewGroupScreen.kt index 3c59a51c7b3..c549e5256fe 100644 --- a/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/createNewGroup/CreateNewGroupScreen.kt +++ b/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/createNewGroup/CreateNewGroupScreen.kt @@ -94,6 +94,7 @@ import org.koin.compose.viewmodel.koinViewModel internal fun CreateNewGroupScreen( viewModel: CreateNewGroupViewModel = koinViewModel(), onGroupCreated: (group: SaveResponse?, userStatus: Boolean) -> Unit, + onBackPressed: () -> Unit, ) { val uiState by viewModel.createNewGroupUiState.collectAsStateWithLifecycle() val userStatus by viewModel.userStatus.collectAsStateWithLifecycle() @@ -110,6 +111,7 @@ internal fun CreateNewGroupScreen( }, onGroupCreated = { onGroupCreated(it, userStatus) }, getResponse = { viewModel.getResponse() }, + onBackPressed=onBackPressed ) } @@ -118,6 +120,7 @@ internal fun CreateNewGroupScreen( internal fun CreateNewGroupScreen( uiState: CreateNewGroupUiState, onRetry: () -> Unit, + onBackPressed: () -> Unit, invokeGroupCreation: (GroupPayloadEntity) -> Unit, onGroupCreated: (group: SaveResponse?) -> Unit, modifier: Modifier = Modifier, @@ -128,7 +131,7 @@ internal fun CreateNewGroupScreen( MifosScaffold( modifier = modifier, title = stringResource(Res.string.feature_groups_create_new_group), - onBackPressed = {}, + onBackPressed = onBackPressed, snackbarHostState = snackbarHostState, ) { paddingValues -> Box( @@ -441,5 +444,6 @@ private fun PreviewCreateNewGroupScreen( onGroupCreated = { _ -> }, getResponse = { "" }, + onBackPressed = {} ) } diff --git a/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/navigation/GroupNavGraph.kt b/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/navigation/GroupNavGraph.kt index ec66ef8fbf4..490b014a7ba 100644 --- a/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/navigation/GroupNavGraph.kt +++ b/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/navigation/GroupNavGraph.kt @@ -69,6 +69,7 @@ fun NavGraphBuilder.groupNavGraph( groups?.groupId?.let { navController.navigateToGroupDetailsScreen(it) } } }, + onBackPressed = navController::popBackStack, ) } } @@ -121,11 +122,13 @@ fun NavGraphBuilder.groupDetailsRoute( } fun NavGraphBuilder.addNewGroupRoute( + onBackPressed: () -> Unit, onGroupCreated: (group: SaveResponse?, userStatus: Boolean) -> Unit, ) { composable(route = GroupScreen.CreateNewGroupScreen.route) { CreateNewGroupScreen( onGroupCreated = onGroupCreated, + onBackPressed=onBackPressed ) } } From e1bbab8614577f3b4a56315f7eba30d7fe658098 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sat, 28 Jun 2025 21:12:03 +0530 Subject: [PATCH 10/13] updated --- .../kotlin/cmp/navigation/navigation/FeatureNavHost.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/FeatureNavHost.kt b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/FeatureNavHost.kt index a7853990462..eda22b83eea 100644 --- a/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/FeatureNavHost.kt +++ b/cmp-navigation/src/commonMain/kotlin/cmp/navigation/navigation/FeatureNavHost.kt @@ -42,6 +42,7 @@ import com.mifos.feature.loan.navigation.addLoanAccountScreen import com.mifos.feature.loan.navigation.groupLoanScreen import com.mifos.feature.loan.navigation.loanNavGraph import com.mifos.feature.loan.navigation.navigateToGroupLoanScreen +import com.mifos.feature.loan.navigation.navigateToLoanAccountScreen import com.mifos.feature.loan.navigation.navigateToLoanAccountSummaryScreen import com.mifos.feature.note.navigation.navigateToNoteScreen import com.mifos.feature.note.navigation.noteNavGraph @@ -171,7 +172,7 @@ internal fun FeatureNavHost( clientNavGraph( navController = appState.navController, paddingValues = padding, - addLoanAccount = appState.navController::navigateToLoanAccountSummaryScreen, + addLoanAccount = appState.navController::navigateToLoanAccountScreen, addSavingsAccount = { clientId -> appState.navController.navigateToAddSavingsAccount(0, clientId, false) }, From f81ddffa313ab66342aa72b561c8bcc79419a3b6 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sat, 28 Jun 2025 21:27:50 +0530 Subject: [PATCH 11/13] updated --- .../createCenter/CreateNewCenterScreen.kt | 8 +++---- .../center/navigation/CenterNavigation.kt | 2 +- .../PhoneNumberUtil.android.kt} | 10 +-------- .../utils/PlatformCameraLauncher.android.kt | 2 +- .../clientDetails/ClientDetailsScreen.kt | 22 +++++++++---------- .../clientDetails/ClientDetailsViewModel.kt | 6 ++--- .../createNewClient/CreateNewClientScreen.kt | 6 +---- .../CreateNewClientViewModel.kt | 2 +- .../feature/client/utils/CompressImage.kt | 15 ++++++++++--- .../feature/client/utils/PhoneNumberUtil.kt | 14 ++++++++++++ .../client/utils/PlatformCameraLauncher.kt | 2 +- .../PhoneNumberUtil.desktop.kt} | 6 +---- .../utils/PlatformCameraLauncher.desktop.kt | 2 +- .../PhoneNumberUtil.native.kt} | 6 +---- .../utils/PlatformCameraLauncher.native.kt | 2 +- .../createNewGroup/CreateNewGroupScreen.kt | 4 ++-- .../groups/navigation/GroupNavGraph.kt | 2 +- 17 files changed, 55 insertions(+), 56 deletions(-) rename feature/client/src/androidMain/kotlin/com/mifos/feature/client/{createNewClient/CreateNewClientScreen.android.kt => utils/PhoneNumberUtil.android.kt} (53%) create mode 100644 feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/PhoneNumberUtil.kt rename feature/client/src/desktopMain/kotlin/com/mifos/feature/client/{createNewClient/CreateNewClientScreen.desktop.kt => utils/PhoneNumberUtil.desktop.kt} (74%) rename feature/client/src/nativeMain/kotlin/com/mifos/feature/client/{createNewClient/CreateNewClientScreen.native.kt => utils/PhoneNumberUtil.native.kt} (74%) diff --git a/feature/center/src/commonMain/kotlin/com/mifos/feature/center/createCenter/CreateNewCenterScreen.kt b/feature/center/src/commonMain/kotlin/com/mifos/feature/center/createCenter/CreateNewCenterScreen.kt index 448c6396f8b..2915ca31c1d 100644 --- a/feature/center/src/commonMain/kotlin/com/mifos/feature/center/createCenter/CreateNewCenterScreen.kt +++ b/feature/center/src/commonMain/kotlin/com/mifos/feature/center/createCenter/CreateNewCenterScreen.kt @@ -66,7 +66,6 @@ import com.mifos.core.designsystem.component.MifosScaffold import com.mifos.core.designsystem.component.MifosSweetError import com.mifos.core.designsystem.component.MifosTextFieldDropdown import com.mifos.core.ui.components.MifosAlertDialog -import com.mifos.core.ui.util.DevicePreview import com.mifos.room.entities.center.CenterPayloadEntity import com.mifos.room.entities.organisation.OfficeEntity import kotlinx.datetime.Clock @@ -98,7 +97,7 @@ internal fun CreateNewCenterScreen( viewModel.createNewCenter(it) }, onCreateSuccess = onCreateSuccess, - onBackPressed=onBackPressed + onBackPressed = onBackPressed, ) } @@ -312,7 +311,6 @@ private fun CreateNewCenterContent( } } - class CreateNewCenterUiStateProvider : PreviewParameterProvider { override val values = sequenceOf( @@ -338,5 +336,5 @@ private fun CreateNewCenterPreview( } val sampleOfficeList = List(10) { - OfficeEntity(id=it) -} \ No newline at end of file + OfficeEntity(id = it) +} diff --git a/feature/center/src/commonMain/kotlin/com/mifos/feature/center/navigation/CenterNavigation.kt b/feature/center/src/commonMain/kotlin/com/mifos/feature/center/navigation/CenterNavigation.kt index 29dfd90ea36..8f9dfa4f7f5 100644 --- a/feature/center/src/commonMain/kotlin/com/mifos/feature/center/navigation/CenterNavigation.kt +++ b/feature/center/src/commonMain/kotlin/com/mifos/feature/center/navigation/CenterNavigation.kt @@ -114,7 +114,7 @@ fun NavGraphBuilder.createCenterScreenRoute( ) { CreateNewCenterScreen( onCreateSuccess = onCreateSuccess, - onBackPressed=onBackPressed + onBackPressed = onBackPressed, ) } } diff --git a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.android.kt b/feature/client/src/androidMain/kotlin/com/mifos/feature/client/utils/PhoneNumberUtil.android.kt similarity index 53% rename from feature/client/src/androidMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.android.kt rename to feature/client/src/androidMain/kotlin/com/mifos/feature/client/utils/PhoneNumberUtil.android.kt index c3f6c76cf5c..39ac52b9b09 100644 --- a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.android.kt +++ b/feature/client/src/androidMain/kotlin/com/mifos/feature/client/utils/PhoneNumberUtil.android.kt @@ -7,17 +7,9 @@ * * See https://github.com/openMF/android-client/blob/master/LICENSE.md */ -package com.mifos.feature.client.createNewClient +package com.mifos.feature.client.utils -import android.Manifest import android.telephony.PhoneNumberUtils -import androidx.compose.runtime.Composable -import com.google.accompanist.permissions.ExperimentalPermissionsApi -import com.google.accompanist.permissions.rememberPermissionState -import com.mifos.feature.client.utils.PlatformCameraLauncher -import io.github.vinceglb.filekit.PlatformFile -import io.github.vinceglb.filekit.dialogs.compose.rememberCameraPickerLauncher -import io.github.vinceglb.filekit.path actual object PhoneNumberUtil { actual fun isGlobalPhoneNumber(phoneNumber: String): Boolean { diff --git a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.android.kt b/feature/client/src/androidMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.android.kt index b4559608985..7e902bf1f20 100644 --- a/feature/client/src/androidMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.android.kt +++ b/feature/client/src/androidMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.android.kt @@ -49,4 +49,4 @@ actual fun rememberPlatformCameraLauncher( permissionState = permissionState, launcher = launcher, ) -} \ No newline at end of file +} diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt index 84fb4532d09..bd77aa402d1 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsScreen.kt @@ -83,7 +83,6 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment @@ -104,12 +103,10 @@ import com.mifos.core.designsystem.component.MifosSweetError import com.mifos.core.designsystem.icon.MifosIcons import com.mifos.core.ui.components.MifosUserImage import com.mifos.core.ui.util.DevicePreview -import com.mifos.feature.client.utils.PlatformCameraLauncher import com.mifos.feature.client.utils.rememberPlatformCameraLauncher import com.mifos.room.entities.accounts.loans.LoanAccountEntity import com.mifos.room.entities.accounts.savings.SavingAccountDepositTypeEntity import com.mifos.room.entities.accounts.savings.SavingsAccountEntity -import io.github.vinceglb.filekit.PlatformFile import io.github.vinceglb.filekit.dialogs.FileKitType import io.github.vinceglb.filekit.dialogs.compose.rememberFilePickerLauncher import org.jetbrains.compose.resources.getString @@ -158,11 +155,12 @@ internal fun ClientDetailsScreen( } } - val cameraLauncher = rememberPlatformCameraLauncher( onImageCapturedPath = { - file-> - showSelectImageDialog = false - clientDetailsViewModel.saveClientImage(clientId,file) - } + val cameraLauncher = rememberPlatformCameraLauncher( + onImageCapturedPath = { + file -> + showSelectImageDialog = false + clientDetailsViewModel.saveClientImage(clientId, file) + }, ) LaunchedEffect(key1 = true) { @@ -334,8 +332,8 @@ internal fun ClientDetailsScreen( loanAccountSelected = loanAccountSelected, savingsAccountSelected = savingsAccountSelected, onClick = { - showSelectImageDialog=true - } + showSelectImageDialog = true + }, ) } } @@ -346,7 +344,7 @@ internal fun ClientDetailsScreen( private fun MifosClientDetailsScreen( loanAccountSelected: (Int) -> Unit, padding: PaddingValues, - onClick:()->Unit, + onClick: () -> Unit, savingsAccountSelected: (Int, SavingAccountDepositTypeEntity) -> Unit, clientDetailsViewModel: ClientDetailsViewModel = koinViewModel(), ) { @@ -370,7 +368,7 @@ private fun MifosClientDetailsScreen( bitmap = profileImage.value, modifier = Modifier .size(100.dp) - .clickable(onClick=onClick), + .clickable(onClick = onClick), username = client?.displayName ?: "", ) } diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt index fa8a929b57b..7c8ac1031c2 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt @@ -95,7 +95,7 @@ class ClientDetailsViewModel( _clientDetailsUiState.value = ClientDetailsUiState.ShowClientImageDeletedSuccessfully - _profileImage.value=null + _profileImage.value = null _showLoading.value = false } catch (e: Exception) { _clientDetailsUiState.value = @@ -126,7 +126,7 @@ class ClientDetailsViewModel( } fun saveClientImage(clientId: Int, imageFile: PlatformFile?) { - if(imageFile==null)return + if (imageFile == null)return viewModelScope.launch { saveAutoClientImage(clientId, imageFile) } @@ -135,7 +135,7 @@ class ClientDetailsViewModel( suspend fun saveAutoClientImage(clientId: Int, imageFile: PlatformFile) { try { _showLoading.value = true - val outFile= compressImage(imageFile,clientId) + val outFile = compressImage(imageFile, clientId) uploadImage(clientId, outFile) } catch (e: Exception) { _showLoading.value = false diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt index 9673a50bfc9..b926bd79525 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.kt @@ -111,7 +111,7 @@ import com.mifos.core.designsystem.component.MifosOutlinedTextField import com.mifos.core.designsystem.component.MifosScaffold import com.mifos.core.designsystem.component.MifosSweetError import com.mifos.core.designsystem.component.MifosTextFieldDropdown -import com.mifos.feature.client.utils.PlatformCameraLauncher +import com.mifos.feature.client.utils.PhoneNumberUtil import com.mifos.feature.client.utils.rememberPlatformCameraLauncher import com.mifos.room.entities.client.ClientPayloadEntity import com.mifos.room.entities.noncore.DataTableEntity @@ -990,10 +990,6 @@ private fun isMiddleNameValid( } } -internal expect object PhoneNumberUtil { - fun isGlobalPhoneNumber(phoneNumber: String): Boolean -} - private class CreateNewClientScreenPreviewProvider : PreviewParameterProvider { override val values: Sequence diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt index c05c539b055..7bf5d11856d 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientViewModel.kt @@ -134,7 +134,7 @@ class CreateNewClientViewModel( viewModelScope.launch { try { - val compressedImage= compressImage(selectedImage.value!!,id) + val compressedImage = compressImage(selectedImage.value!!, id) val requestFile = createImageRequestBody(compressedImage) repository.uploadClientImage(id, requestFile) diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/CompressImage.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/CompressImage.kt index d78e00331e9..b2461480198 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/CompressImage.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/CompressImage.kt @@ -1,3 +1,12 @@ +/* + * Copyright 2025 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/android-client/blob/master/LICENSE.md + */ package com.mifos.feature.client.utils import io.github.vinceglb.filekit.FileKit @@ -8,14 +17,14 @@ import io.github.vinceglb.filekit.div import io.github.vinceglb.filekit.filesDir import io.github.vinceglb.filekit.write -suspend fun compressImage(imageFile: PlatformFile, clientId:Int):PlatformFile{ +suspend fun compressImage(imageFile: PlatformFile, clientId: Int): PlatformFile { val bytes = FileKit.compressImage( file = imageFile, imageFormat = ImageFormat.PNG, quality = 100, - maxHeight=150 + maxHeight = 150, ) val outFile = FileKit.filesDir / "client_image_$clientId.png" outFile.write(bytes) return outFile -} \ No newline at end of file +} diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/PhoneNumberUtil.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/PhoneNumberUtil.kt new file mode 100644 index 00000000000..7af24bbcd25 --- /dev/null +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/PhoneNumberUtil.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2025 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * See https://github.com/openMF/android-client/blob/master/LICENSE.md + */ +package com.mifos.feature.client.utils + +expect object PhoneNumberUtil { + fun isGlobalPhoneNumber(phoneNumber: String): Boolean +} diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.kt index b856363aa67..a6ea9454cf0 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.kt @@ -19,4 +19,4 @@ expect class PlatformCameraLauncher { @Composable expect fun rememberPlatformCameraLauncher( onImageCapturedPath: (PlatformFile?) -> Unit, -): PlatformCameraLauncher \ No newline at end of file +): PlatformCameraLauncher diff --git a/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.desktop.kt b/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/utils/PhoneNumberUtil.desktop.kt similarity index 74% rename from feature/client/src/desktopMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.desktop.kt rename to feature/client/src/desktopMain/kotlin/com/mifos/feature/client/utils/PhoneNumberUtil.desktop.kt index 45c3ea10bbe..de60bb6f643 100644 --- a/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.desktop.kt +++ b/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/utils/PhoneNumberUtil.desktop.kt @@ -7,11 +7,7 @@ * * See https://github.com/openMF/android-client/blob/master/LICENSE.md */ -package com.mifos.feature.client.createNewClient - -import androidx.compose.runtime.Composable -import com.mifos.feature.client.utils.PlatformCameraLauncher -import io.github.vinceglb.filekit.PlatformFile +package com.mifos.feature.client.utils actual object PhoneNumberUtil { actual fun isGlobalPhoneNumber(phoneNumber: String): Boolean { diff --git a/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.desktop.kt b/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.desktop.kt index 74c51885f42..9030ed48c43 100644 --- a/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.desktop.kt +++ b/feature/client/src/desktopMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.desktop.kt @@ -20,4 +20,4 @@ actual class PlatformCameraLauncher { @Composable actual fun rememberPlatformCameraLauncher(onImageCapturedPath: (PlatformFile?) -> Unit): PlatformCameraLauncher { TODO("Not yet implemented") -} \ No newline at end of file +} diff --git a/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.native.kt b/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/utils/PhoneNumberUtil.native.kt similarity index 74% rename from feature/client/src/nativeMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.native.kt rename to feature/client/src/nativeMain/kotlin/com/mifos/feature/client/utils/PhoneNumberUtil.native.kt index 45c3ea10bbe..de60bb6f643 100644 --- a/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/createNewClient/CreateNewClientScreen.native.kt +++ b/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/utils/PhoneNumberUtil.native.kt @@ -7,11 +7,7 @@ * * See https://github.com/openMF/android-client/blob/master/LICENSE.md */ -package com.mifos.feature.client.createNewClient - -import androidx.compose.runtime.Composable -import com.mifos.feature.client.utils.PlatformCameraLauncher -import io.github.vinceglb.filekit.PlatformFile +package com.mifos.feature.client.utils actual object PhoneNumberUtil { actual fun isGlobalPhoneNumber(phoneNumber: String): Boolean { diff --git a/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.native.kt b/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.native.kt index 74c51885f42..9030ed48c43 100644 --- a/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.native.kt +++ b/feature/client/src/nativeMain/kotlin/com/mifos/feature/client/utils/PlatformCameraLauncher.native.kt @@ -20,4 +20,4 @@ actual class PlatformCameraLauncher { @Composable actual fun rememberPlatformCameraLauncher(onImageCapturedPath: (PlatformFile?) -> Unit): PlatformCameraLauncher { TODO("Not yet implemented") -} \ No newline at end of file +} diff --git a/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/createNewGroup/CreateNewGroupScreen.kt b/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/createNewGroup/CreateNewGroupScreen.kt index c549e5256fe..af036c702c5 100644 --- a/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/createNewGroup/CreateNewGroupScreen.kt +++ b/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/createNewGroup/CreateNewGroupScreen.kt @@ -111,7 +111,7 @@ internal fun CreateNewGroupScreen( }, onGroupCreated = { onGroupCreated(it, userStatus) }, getResponse = { viewModel.getResponse() }, - onBackPressed=onBackPressed + onBackPressed = onBackPressed, ) } @@ -444,6 +444,6 @@ private fun PreviewCreateNewGroupScreen( onGroupCreated = { _ -> }, getResponse = { "" }, - onBackPressed = {} + onBackPressed = {}, ) } diff --git a/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/navigation/GroupNavGraph.kt b/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/navigation/GroupNavGraph.kt index 490b014a7ba..089819a2f94 100644 --- a/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/navigation/GroupNavGraph.kt +++ b/feature/groups/src/commonMain/kotlin/com/mifos/feature/groups/navigation/GroupNavGraph.kt @@ -128,7 +128,7 @@ fun NavGraphBuilder.addNewGroupRoute( composable(route = GroupScreen.CreateNewGroupScreen.route) { CreateNewGroupScreen( onGroupCreated = onGroupCreated, - onBackPressed=onBackPressed + onBackPressed = onBackPressed, ) } } From 2207be14e05a1d5f5766f762df927510fac81a44 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sat, 28 Jun 2025 22:57:57 +0530 Subject: [PATCH 12/13] updated --- .../repository/ClientDetailsRepository.kt | 2 +- .../ClientDetailsRepositoryImp.kt | 2 +- .../useCases/UploadClientImageUseCase.kt | 12 ++++++---- .../network/datamanager/DataManagerClient.kt | 2 +- .../clientDetails/ClientDetailsViewModel.kt | 22 ++++++++----------- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/core/data/src/commonMain/kotlin/com/mifos/core/data/repository/ClientDetailsRepository.kt b/core/data/src/commonMain/kotlin/com/mifos/core/data/repository/ClientDetailsRepository.kt index 162a7d42c04..0aaf26bd46b 100644 --- a/core/data/src/commonMain/kotlin/com/mifos/core/data/repository/ClientDetailsRepository.kt +++ b/core/data/src/commonMain/kotlin/com/mifos/core/data/repository/ClientDetailsRepository.kt @@ -28,5 +28,5 @@ interface ClientDetailsRepository { suspend fun getClient(clientId: Int): ClientEntity - suspend fun getImage(clientId: Int): Flow> + fun getImage(clientId: Int): Flow> } diff --git a/core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/ClientDetailsRepositoryImp.kt b/core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/ClientDetailsRepositoryImp.kt index c51558af3ff..8f2c9e399fd 100644 --- a/core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/ClientDetailsRepositoryImp.kt +++ b/core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/ClientDetailsRepositoryImp.kt @@ -40,7 +40,7 @@ class ClientDetailsRepositoryImp( return dataManagerClient.getClient(clientId) } - override suspend fun getImage(clientId: Int): Flow> { + override fun getImage(clientId: Int): Flow> { return dataManagerClient.getClientImage(clientId) } } diff --git a/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt b/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt index baf8b276330..57676259421 100644 --- a/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt +++ b/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt @@ -27,10 +27,14 @@ class UploadClientImageUseCase( private val repository: ClientDetailsRepository, ) { - operator fun invoke(id: Int, image: MultiPartFormDataContent): Flow> { - return flow { + operator fun invoke(id: Int, image: MultiPartFormDataContent): Flow> = flow { + emit(DataState.Loading) + + try { repository.uploadClientImage(id, image) - emit(getString(Res.string.core_domain_client_image_uploaded_successfully)) - }.asDataStateFlow() + emit(DataState.Success(getString(Res.string.core_domain_client_image_uploaded_successfully))) + } catch (e: Exception) { + emit(DataState.Error(e)) + } } } diff --git a/core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerClient.kt b/core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerClient.kt index 50f4fdd0933..871103bc638 100644 --- a/core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerClient.kt +++ b/core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerClient.kt @@ -210,7 +210,7 @@ class DataManagerClient( return mBaseApiManager.clientsApi.uploadClientImage(clientId, file) } - suspend fun getClientImage(clientId: Int): Flow> { + fun getClientImage(clientId: Int): Flow> { return mBaseApiManager.clientsApi.getClientImage(clientId) .asDataStateFlow() .map { diff --git a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt index 7c8ac1031c2..cf62052d703 100644 --- a/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt +++ b/feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientDetails/ClientDetailsViewModel.kt @@ -126,20 +126,16 @@ class ClientDetailsViewModel( } fun saveClientImage(clientId: Int, imageFile: PlatformFile?) { - if (imageFile == null)return + imageFile ?: return viewModelScope.launch { - saveAutoClientImage(clientId, imageFile) - } - } - - suspend fun saveAutoClientImage(clientId: Int, imageFile: PlatformFile) { - try { - _showLoading.value = true - val outFile = compressImage(imageFile, clientId) - uploadImage(clientId, outFile) - } catch (e: Exception) { - _showLoading.value = false - _clientDetailsUiState.value = ClientDetailsUiState.ShowError(e.message.toString()) + try { + _showLoading.value = true + val compressed = compressImage(imageFile, clientId) + uploadImage(clientId, compressed) + } catch (e: Exception) { + _showLoading.value = false + _clientDetailsUiState.value = ClientDetailsUiState.ShowError(e.message ?: "Unexpected error") + } } } From b22ba45db7ccebc4e3cef80bb47ac4955bd9f966 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sat, 28 Jun 2025 23:06:48 +0530 Subject: [PATCH 13/13] updated --- .../mifos/core/data/repositoryImp/ClientDetailsRepositoryImp.kt | 2 +- .../com/mifos/core/domain/useCases/UploadClientImageUseCase.kt | 1 - .../com/mifos/core/network/datamanager/DataManagerClient.kt | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/ClientDetailsRepositoryImp.kt b/core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/ClientDetailsRepositoryImp.kt index 8f2c9e399fd..da454c94b0d 100644 --- a/core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/ClientDetailsRepositoryImp.kt +++ b/core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/ClientDetailsRepositoryImp.kt @@ -40,7 +40,7 @@ class ClientDetailsRepositoryImp( return dataManagerClient.getClient(clientId) } - override fun getImage(clientId: Int): Flow> { + override fun getImage(clientId: Int): Flow> { return dataManagerClient.getClientImage(clientId) } } diff --git a/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt b/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt index 57676259421..85a636368d0 100644 --- a/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt +++ b/core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/UploadClientImageUseCase.kt @@ -10,7 +10,6 @@ package com.mifos.core.domain.useCases import com.mifos.core.common.utils.DataState -import com.mifos.core.common.utils.asDataStateFlow import com.mifos.core.data.repository.ClientDetailsRepository import core.domain.generated.resources.Res import core.domain.generated.resources.core_domain_client_image_uploaded_successfully diff --git a/core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerClient.kt b/core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerClient.kt index 871103bc638..d9f188dd769 100644 --- a/core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerClient.kt +++ b/core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerClient.kt @@ -210,7 +210,7 @@ class DataManagerClient( return mBaseApiManager.clientsApi.uploadClientImage(clientId, file) } - fun getClientImage(clientId: Int): Flow> { + fun getClientImage(clientId: Int): Flow> { return mBaseApiManager.clientsApi.getClientImage(clientId) .asDataStateFlow() .map {