diff --git a/.github/workflows/master_dev_ci.yml b/.github/workflows/master_dev_ci.yml index 247bbc0d2..27bb7a38d 100644 --- a/.github/workflows/master_dev_ci.yml +++ b/.github/workflows/master_dev_ci.yml @@ -54,7 +54,7 @@ jobs: fi - name: Upload Detekt Reports - if: ${{ matrix.check }} == 'detekt' && steps.run_check.outcome == 'success' + if: ${{ matrix.check == 'detekt' && steps.run_check.outcome == 'success' }} uses: actions/upload-artifact@v4 with: name: detekt-reports @@ -79,7 +79,6 @@ jobs: - name: Prevent updating Dependency Guard baselines if this is a fork id: checkfork_dependencyguard - continue-on-error: true if: steps.dependencyguard_verify.outcome == 'failure' && github.event.pull_request.head.repo.full_name != github.repository run: | echo "::error::Dependency Guard failed, please update baselines with: ./gradlew dependencyGuardBaseline" && exit 1 @@ -99,7 +98,6 @@ jobs: disable_globbing: true commit_message: "🤖 Updates baselines for Dependency Guard" - tests_and_lint: needs: setup runs-on: ubuntu-latest @@ -111,7 +109,7 @@ jobs: java-version: 17 - name: Run tests run: | - ./gradlew testDemoDebug lintProdRelease + ./gradlew testDemoDebug :lint:test :mifospay:lintProdRelease :lint:lint - name: Upload reports if: always() uses: actions/upload-artifact@v4 @@ -122,7 +120,7 @@ jobs: **/build/test-results/test*UnitTest/**.xml build: - needs: [ checks, tests_and_lint ] + needs: [ checks, dependency_guard, tests_and_lint ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/README.md b/README.md index 250fd6b08..4256cfbfa 100644 --- a/README.md +++ b/README.md @@ -98,20 +98,23 @@ Before you begin, you should have already downloaded the Android Studio SDK and 4. **Perform a Gradle Check** -All your pull requests must pass the CI build only then, it will be allowed to merge. Sometimes, when the build doesn't pass you can use these commands in your local terminal and check for the errors,
+All your pull requests must pass the CI build only then, it will be allowed to merge. +Sometimes, when the build doesn't pass you can use these commands in your local terminal and check for the errors,
-For Mac OS, you can use the following commands: +**We've commited to use Material3 design in our project. And added lint check for not to use any M2 libraries in our project.
** +**And when adding new library, please make sure to follow the naming convention and place in sequential order(A->Z).** -* `./gradlew check` quality checks on your project’s code using Checkstyle and generates reports from these checks.
-* `./gradlew spotlessApply` an check and apply formatting to any plain-text file.
-* `./gradlew build` provides a command line to execute build script.
+In MacOS, Windows or Linux, you should run the following commands before opening a PR, and make sure to pass all the commands: +* `./gradlew check -p build-logic` this checks build-logic configured properly.
+* `./gradlew spotlessApply --no-configuration-cache` an check and apply formatting to any file.
+* `./gradlew dependencyGuardBaseline` to generate dependency-guard baseline.
+* `./gradlew detekt` to check detekt error.
+* `./gradlew testDemoDebug :lint:test :mifospay:lintProdRelease :lint:lint` to check lint and test error.
+* `./gradlew build` to build the project.
+* `./gradlew updateProdReleaseBadging` to update the badging for the project.
-For Windows, you can use the following commands: - -* `gradlew check` quality checks on your project’s code using Checkstyle and generates reports from these checks.
-* `gradlew spotlessApply` an check and apply formatting to any plain-text file.
-* `gradlew build` provides a command line to execute build script.
+*Or Run the `ci-prebuild.sh` or `ci-prebuild.bat` script to run all the above commands in one go.* ### **Committing Your Changes** diff --git a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt index 867913659..6ef667136 100644 --- a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt @@ -4,6 +4,7 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.kotlin import org.mifospay.libs class AndroidFeatureConventionPlugin : Plugin { @@ -24,16 +25,25 @@ class AndroidFeatureConventionPlugin : Plugin { dependencies { add("implementation", project(":core:ui")) add("implementation", project(":core:designsystem")) - add("implementation", project(":shared")) - add("implementation", project(":desktop")) - add("implementation", libs.findLibrary("androidx.material.navigation").get()) + add("implementation", project(":libs:material3-navigation")) + + add("implementation", libs.findLibrary("kotlinx.collections.immutable").get()) add("implementation", libs.findLibrary("androidx.hilt.navigation.compose").get()) add("implementation", libs.findLibrary("androidx.lifecycle.runtimeCompose").get()) add("implementation", libs.findLibrary("androidx.lifecycle.viewModelCompose").get()) add("implementation", libs.findLibrary("androidx.tracing.ktx").get()) add("androidTestImplementation", libs.findLibrary("androidx.lifecycle.runtimeTesting").get()) + + add("testImplementation", kotlin("test")) + add("testImplementation", libs.findLibrary("hilt.android.testing").get()) + + add("debugImplementation", libs.findLibrary("androidx.compose.ui.test.manifest").get()) + add("androidTestImplementation", libs.findLibrary("androidx.navigation.testing").get()) + add("androidTestImplementation", libs.findLibrary("androidx.compose.ui.test").get()) + add("androidTestImplementation", libs.findLibrary("hilt.android.testing").get()) + add("androidTestImplementation", libs.findLibrary("androidx.lifecycle.runtimeTesting").get()) } } } diff --git a/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt index 54246d61e..4614a16ab 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt @@ -4,6 +4,7 @@ import com.android.build.api.dsl.Lint import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.configure +import java.io.File class AndroidLintConventionPlugin : Plugin { override fun apply(target: Project) { @@ -27,4 +28,10 @@ class AndroidLintConventionPlugin : Plugin { private fun Lint.configure() { xmlReport = true checkDependencies = true + abortOnError = false + // Disable this rule until we ship the libraries to some maven. + disable += "ResourceName" + baseline = File("lint-baseline.xml") + explainIssues = true + htmlReport = true } diff --git a/ci-prebuild.bat b/ci-prebuild.bat index f83e81a37..dc7e9d6bc 100644 --- a/ci-prebuild.bat +++ b/ci-prebuild.bat @@ -13,8 +13,7 @@ call :run_gradle_task "check -p build-logic" call :run_gradle_task "spotlessApply --no-configuration-cache" call :run_gradle_task "dependencyGuardBaseline" call :run_gradle_task "detekt" -call :run_gradle_task "testDemoDebug" -call :run_gradle_task "lintProdRelease" +call :run_gradle_task "testDemoDebug :lint:test :mifospay:lintProdRelease :lint:lint" call :run_gradle_task "build" call :run_gradle_task "updateProdReleaseBadging" diff --git a/ci-prebuild.sh b/ci-prebuild.sh index 603398e0b..3e02d3d01 100644 --- a/ci-prebuild.sh +++ b/ci-prebuild.sh @@ -8,23 +8,52 @@ fi echo "Starting all checks and tests..." +failed_tasks=() +successful_tasks=() + run_gradle_task() { echo "Running: $1" "./gradlew" $1 if [ $? -ne 0 ]; then - echo "Error: Task $1 failed" - exit 1 + echo "Warning: Task $1 failed" + failed_tasks+=("$1") + else + echo "Task $1 completed successfully" + successful_tasks+=("$1") fi } -run_gradle_task "check -p build-logic" -run_gradle_task "spotlessApply --no-configuration-cache" -run_gradle_task "dependencyGuardBaseline" -run_gradle_task "detekt" -run_gradle_task "testDemoDebug" -run_gradle_task "lintProdRelease" -run_gradle_task "build" -run_gradle_task "updateProdReleaseBadging" - -echo "All checks and tests completed successfully." -exit 0 \ No newline at end of file +tasks=( + "check -p build-logic" + "spotlessApply --no-configuration-cache" + "dependencyGuardBaseline" + "detekt" + "testDemoDebug :lint:test :lint:lint :mifospay:lintProdRelease" + "build" + "updateProdReleaseBadging" +) + +for task in "${tasks[@]}"; do + run_gradle_task "$task" +done + +echo "All tasks have finished." + +echo "Successful tasks:" +for task in "${successful_tasks[@]}"; do + echo "- $task" +done + +if [ ${#failed_tasks[@]} -eq 0 ]; then + echo "All checks and tests completed successfully." +else + echo "Failed tasks:" + for task in "${failed_tasks[@]}"; do + echo "- $task" + done + echo "Please review the output above for more details on the failures." +fi + +echo "Total tasks: ${#tasks[@]}" +echo "Successful tasks: ${#successful_tasks[@]}" +echo "Failed tasks: ${#failed_tasks[@]}" \ No newline at end of file diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts index c6654fb72..5e84d21ee 100644 --- a/core/common/build.gradle.kts +++ b/core/common/build.gradle.kts @@ -16,11 +16,4 @@ android { namespace = "org.mifospay.common" } -dependencies { - implementation(libs.androidx.core.ktx) - implementation(libs.androidx.appcompat) - implementation(libs.material) - testImplementation(libs.junit) - androidTestImplementation(libs.androidx.test.ext.junit) - androidTestImplementation(libs.espresso.core) -} +dependencies {} diff --git a/core/common/src/main/kotlin/org/mifospay/common/Utils.kt b/core/common/src/main/kotlin/org/mifospay/common/Utils.kt index 5e95d0e62..5b18a303d 100644 --- a/core/common/src/main/kotlin/org/mifospay/common/Utils.kt +++ b/core/common/src/main/kotlin/org/mifospay/common/Utils.kt @@ -9,31 +9,17 @@ */ package org.mifospay.common -import android.app.Activity -import android.content.Context -import android.content.res.Resources -import android.view.inputmethod.InputMethodManager import java.text.NumberFormat import java.util.Currency object Utils { @JvmStatic - fun hideSoftKeyboard(activity: Activity) { - val view = activity.currentFocus - val inputMethodManager = - activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - inputMethodManager.hideSoftInputFromWindow(view?.windowToken, 0) - } - - @JvmStatic - fun Int.dp2px() = (this * Resources.getSystem().displayMetrics.density + 0.5f).toInt() - - @JvmStatic - fun String.isBlank() = this.isEmpty() || indices.all { this[it].isWhitespace() } - - @JvmStatic - fun getFormattedAccountBalance(balance: Double?, currencyCode: String?, maximumFractionDigits: Int? = 0): String { + fun getFormattedAccountBalance( + balance: Double?, + currencyCode: String?, + maximumFractionDigits: Int? = 0, + ): String { val accountBalanceFormatter = NumberFormat.getCurrencyInstance() accountBalanceFormatter.maximumFractionDigits = maximumFractionDigits ?: 0 accountBalanceFormatter.currency = Currency.getInstance(currencyCode) diff --git a/core/designsystem/build.gradle.kts b/core/designsystem/build.gradle.kts index 3a66ea76e..f08a5aea8 100644 --- a/core/designsystem/build.gradle.kts +++ b/core/designsystem/build.gradle.kts @@ -20,8 +20,11 @@ android { } dependencies { + lintPublish(projects.lint) + implementation(projects.core.model) + api(libs.androidx.compose.ui) api(libs.androidx.compose.foundation) api(libs.androidx.compose.foundation.layout) api(libs.androidx.compose.material.iconsExtended) diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/Button.kt b/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/Button.kt index 023de3031..2c1d566ad 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/Button.kt +++ b/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/Button.kt @@ -18,7 +18,9 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.sizeIn import androidx.compose.material3.Button +import androidx.compose.material3.ButtonColors import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.ButtonElevation import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton @@ -27,6 +29,7 @@ import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.dp import org.mifospay.core.designsystem.icon.MifosIcons import org.mifospay.core.designsystem.theme.MifosTheme @@ -61,6 +64,29 @@ fun MifosButton( ) } +@Composable +fun MifosButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + shape: Shape = ButtonDefaults.shape, + contentPadding: PaddingValues = ButtonDefaults.ContentPadding, + elevation: ButtonElevation? = ButtonDefaults.buttonElevation(), + colors: ButtonColors = ButtonDefaults.buttonColors(), + content: @Composable RowScope.() -> Unit = {}, +) { + Button( + onClick = onClick, + modifier = modifier, + enabled = enabled, + colors = colors, + shape = shape, + elevation = elevation, + contentPadding = contentPadding, + content = content, + ) +} + /** * Mifos Wallet filled button with text and icon content slots. * @@ -114,6 +140,9 @@ fun MifosOutlinedButton( onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, + shape: Shape = ButtonDefaults.outlinedShape, + border: BorderStroke? = ButtonDefaults.outlinedButtonBorder, + colors: ButtonColors = ButtonDefaults.outlinedButtonColors(), contentPadding: PaddingValues = ButtonDefaults.ContentPadding, content: @Composable RowScope.() -> Unit = {}, ) { @@ -121,19 +150,9 @@ fun MifosOutlinedButton( onClick = onClick, modifier = modifier, enabled = enabled, - colors = ButtonDefaults.outlinedButtonColors( - contentColor = MaterialTheme.colorScheme.onBackground, - ), - border = BorderStroke( - width = MifosButtonDefaults.OutlinedButtonBorderWidth, - color = if (enabled) { - MaterialTheme.colorScheme.outline - } else { - MaterialTheme.colorScheme.onSurface.copy( - alpha = MifosButtonDefaults.DISABLED_OUTLINED_BUTTON_BORDER_ALPHA, - ) - }, - ), + shape = shape, + colors = colors, + border = border, contentPadding = contentPadding, content = content, ) diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/MifosTab.kt b/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/MifosTab.kt new file mode 100644 index 000000000..0aac6d9e6 --- /dev/null +++ b/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/component/MifosTab.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2024 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/mobile-wallet/blob/master/LICENSE.md + */ +package org.mifospay.core.designsystem.component + +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Tab +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color + +@Composable +fun MifosTab( + text: String, + selected: Boolean, + onClick: () -> Unit, + modifier: Modifier = Modifier, + selectedContentColor: Color = MaterialTheme.colorScheme.onSurface, + unselectedContentColor: Color = Color.LightGray, +) { + Tab( + text = { + Text( + text = text, + color = MaterialTheme.colorScheme.onSurface, + ) + }, + selected = selected, + modifier = modifier, + selectedContentColor = selectedContentColor, + unselectedContentColor = unselectedContentColor, + onClick = onClick, + ) +} diff --git a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/icon/MifosIcons.kt b/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/icon/MifosIcons.kt index 7912bd160..3caf851dc 100644 --- a/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/icon/MifosIcons.kt +++ b/core/designsystem/src/main/kotlin/org/mifospay/core/designsystem/icon/MifosIcons.kt @@ -12,8 +12,12 @@ package org.mifospay.core.designsystem.icon import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.outlined.ArrowBack +import androidx.compose.material.icons.filled.ArrowDropDown import androidx.compose.material.icons.filled.ArrowOutward import androidx.compose.material.icons.filled.Camera +import androidx.compose.material.icons.filled.Check +import androidx.compose.material.icons.filled.ChevronRight +import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.ContentCopy import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Edit @@ -22,8 +26,11 @@ import androidx.compose.material.icons.filled.FlashOn import androidx.compose.material.icons.filled.Info import androidx.compose.material.icons.filled.Photo import androidx.compose.material.icons.filled.PhotoLibrary +import androidx.compose.material.icons.filled.QrCode import androidx.compose.material.icons.filled.QrCode2 import androidx.compose.material.icons.filled.Share +import androidx.compose.material.icons.filled.Visibility +import androidx.compose.material.icons.filled.VisibilityOff import androidx.compose.material.icons.outlined.AccountCircle import androidx.compose.material.icons.outlined.Cancel import androidx.compose.material.icons.outlined.Home @@ -46,6 +53,13 @@ import androidx.compose.ui.graphics.vector.ImageVector * Mifos icons. Material icons are [ImageVector]s, custom icons are drawable resource IDs. */ object MifosIcons { + val ChevronRight: ImageVector = Icons.Filled.ChevronRight + val QrCode: ImageVector = Icons.Filled.QrCode + val Close: ImageVector = Icons.Filled.Close + val VisibilityOff: ImageVector = Icons.Filled.VisibilityOff + val Visibility: ImageVector = Icons.Filled.Visibility + val Check: ImageVector = Icons.Default.Check + val ArrowDropDown: ImageVector = Icons.Default.ArrowDropDown val Home = Icons.Outlined.Home val HomeBoarder = Icons.Rounded.Home val Payment = Icons.Rounded.SwapHoriz diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index a05cdd580..74cbb02cc 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -26,8 +26,12 @@ dependencies { api(libs.androidx.metrics) api(projects.core.analytics) + implementation(libs.androidx.compose.runtime) implementation(libs.accompanist.pager) implementation(libs.androidx.browser) implementation(libs.coil.kt) implementation(libs.coil.kt.compose) + + testImplementation(libs.androidx.compose.ui.test) + androidTestImplementation(libs.bundles.androidx.compose.ui.test) } \ No newline at end of file diff --git a/core/ui/src/main/kotlin/org/mifospay/core/ui/DevicePreviews.kt b/core/ui/src/main/kotlin/org/mifospay/core/ui/DevicePreviews.kt index 95699ccc4..6e15874c9 100644 --- a/core/ui/src/main/kotlin/org/mifospay/core/ui/DevicePreviews.kt +++ b/core/ui/src/main/kotlin/org/mifospay/core/ui/DevicePreviews.kt @@ -15,8 +15,8 @@ import androidx.compose.ui.tooling.preview.Preview * Multipreview annotation that represents various device sizes. Add this annotation to a composable * to render various devices. */ -@Preview(name = "phone", device = "spec:shape=Normal,width=360,height=640,unit=dp,dpi=480") -@Preview(name = "landscape", device = "spec:shape=Normal,width=640,height=360,unit=dp,dpi=480") -@Preview(name = "foldable", device = "spec:shape=Normal,width=673,height=841,unit=dp,dpi=480") -@Preview(name = "tablet", device = "spec:shape=Normal,width=1280,height=800,unit=dp,dpi=480") +@Preview(name = "phone", device = "spec:width=360dp,height=640dp,dpi=480") +@Preview(name = "landscape", device = "spec:width=640dp,height=360dp,dpi=480") +@Preview(name = "foldable", device = "spec:width=673dp,height=841dp,dpi=480") +@Preview(name = "tablet", device = "spec:width=1280dp,height=800dp,dpi=480") annotation class DevicePreviews diff --git a/core/ui/src/main/kotlin/org/mifospay/core/ui/EmptyContentScreen.kt b/core/ui/src/main/kotlin/org/mifospay/core/ui/EmptyContentScreen.kt index 8c6b5ed34..1441d645c 100644 --- a/core/ui/src/main/kotlin/org/mifospay/core/ui/EmptyContentScreen.kt +++ b/core/ui/src/main/kotlin/org/mifospay/core/ui/EmptyContentScreen.kt @@ -18,8 +18,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Search import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -35,6 +33,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import org.mifospay.core.designsystem.icon.MifosIcons import org.mifospay.core.designsystem.theme.MifosTheme @Composable @@ -115,7 +114,7 @@ fun EmptyContentScreen( subTitle: String, modifier: Modifier = Modifier, iconTint: Color = MaterialTheme.colorScheme.surfaceTint, - iconImageVector: ImageVector = Icons.Rounded.Search, + iconImageVector: ImageVector = MifosIcons.Search, ) { EmptyContentScreen( title = title, @@ -155,7 +154,7 @@ fun EmptyContentScreenImageVectorPreview() { subTitle = "Please check you connection or try again", modifier = Modifier, iconTint = MaterialTheme.colorScheme.primary, - iconImageVector = Icons.Rounded.Search, + iconImageVector = MifosIcons.Search, ) } } diff --git a/core/ui/src/main/kotlin/org/mifospay/core/ui/FaqItemScreen.kt b/core/ui/src/main/kotlin/org/mifospay/core/ui/FaqItemScreen.kt index af565f2d6..aa6792e43 100644 --- a/core/ui/src/main/kotlin/org/mifospay/core/ui/FaqItemScreen.kt +++ b/core/ui/src/main/kotlin/org/mifospay/core/ui/FaqItemScreen.kt @@ -19,8 +19,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowDropDown import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme @@ -35,6 +33,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.scale import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import org.mifospay.core.designsystem.icon.MifosIcons @Composable fun FaqItemScreen( @@ -67,7 +66,7 @@ fun FaqItemScreen( ) Icon( - imageVector = Icons.Default.ArrowDropDown, + imageVector = MifosIcons.ArrowDropDown, contentDescription = "drop down", tint = MaterialTheme.colorScheme.onSurface, modifier = Modifier diff --git a/core/ui/src/main/kotlin/org/mifospay/core/ui/HeadingTitile.kt b/core/ui/src/main/kotlin/org/mifospay/core/ui/HeadingTitile.kt index c558064fa..891347c2e 100644 --- a/core/ui/src/main/kotlin/org/mifospay/core/ui/HeadingTitile.kt +++ b/core/ui/src/main/kotlin/org/mifospay/core/ui/HeadingTitile.kt @@ -13,8 +13,6 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Check import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme @@ -29,6 +27,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import org.mifospay.core.designsystem.icon.MifosIcons import org.mifospay.core.designsystem.theme.MifosTheme @Composable @@ -57,7 +56,7 @@ fun VerifyStepHeader( ) { if (isVerified) { Icon( - imageVector = Icons.Default.Check, + imageVector = MifosIcons.Check, contentDescription = null, tint = if (isVerified) MaterialTheme.colorScheme.onSurface else Color.Gray, modifier = Modifier.size(24.dp), diff --git a/core/ui/src/main/kotlin/org/mifospay/core/ui/ScrollableTabRow.kt b/core/ui/src/main/kotlin/org/mifospay/core/ui/ScrollableTabRow.kt index f5394a96a..b806e14fb 100644 --- a/core/ui/src/main/kotlin/org/mifospay/core/ui/ScrollableTabRow.kt +++ b/core/ui/src/main/kotlin/org/mifospay/core/ui/ScrollableTabRow.kt @@ -11,8 +11,6 @@ package org.mifospay.core.ui import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ScrollableTabRow -import androidx.compose.material3.Tab -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier @@ -22,6 +20,7 @@ import androidx.compose.ui.unit.dp import com.google.accompanist.pager.HorizontalPager import com.google.accompanist.pager.PagerState import kotlinx.coroutines.launch +import org.mifospay.core.designsystem.component.MifosTab import org.mifospay.core.ui.utility.TabContent @Suppress("MultipleEmitters") @@ -44,13 +43,8 @@ fun MifosScrollableTabRow( edgePadding = edgePadding, ) { tabContents.forEachIndexed { index, currentTab -> - Tab( - text = { - Text( - text = currentTab.tabName, - color = MaterialTheme.colorScheme.onSurface, - ) - }, + MifosTab( + text = currentTab.tabName, selected = pagerState.currentPage == index, selectedContentColor = selectedContentColor, unselectedContentColor = unselectedContentColor, diff --git a/core/ui/src/main/kotlin/org/mifospay/core/ui/utility/AddBtnChip.kt b/core/ui/src/main/kotlin/org/mifospay/core/ui/utility/AddBtnChip.kt index 1d6b33189..8d094a6ca 100644 --- a/core/ui/src/main/kotlin/org/mifospay/core/ui/utility/AddBtnChip.kt +++ b/core/ui/src/main/kotlin/org/mifospay/core/ui/utility/AddBtnChip.kt @@ -11,8 +11,6 @@ package org.mifospay.core.ui.utility import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Add import androidx.compose.material3.AssistChip import androidx.compose.material3.AssistChipDefaults import androidx.compose.material3.Icon @@ -23,6 +21,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import org.mifospay.core.designsystem.icon.MifosIcons @Composable fun AddCardChip( @@ -46,7 +45,7 @@ fun AddCardChip( }, leadingIcon = { Icon( - imageVector = Icons.Filled.Add, + imageVector = MifosIcons.Add, contentDescription = stringResource(btnText), modifier = Modifier.size(16.dp), tint = MaterialTheme.colorScheme.onPrimary, diff --git a/feature/accounts/build.gradle.kts b/feature/accounts/build.gradle.kts index 37039201b..75d75c8b1 100644 --- a/feature/accounts/build.gradle.kts +++ b/feature/accounts/build.gradle.kts @@ -18,7 +18,6 @@ android { dependencies { implementation(projects.core.data) - // TODO:: this should be removed - implementation(libs.compose.material) -// implementation(projects.feature.upiSetup) + + implementation(projects.libs.pullrefresh) } \ No newline at end of file diff --git a/feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/AccountsScreen.kt b/feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/AccountsScreen.kt index 01a0209b3..45fa9d047 100644 --- a/feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/AccountsScreen.kt +++ b/feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/AccountsScreen.kt @@ -17,12 +17,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Info -import androidx.compose.material.pullrefresh.PullRefreshIndicator -import androidx.compose.material.pullrefresh.pullRefresh -import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -36,8 +30,12 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.mifos.library.pullrefresh.PullRefreshIndicator +import com.mifos.library.pullrefresh.pullRefresh +import com.mifos.library.pullrefresh.rememberPullRefreshState import com.mifospay.core.model.domain.BankAccountDetails import org.mifospay.core.designsystem.component.MfLoadingWheel +import org.mifospay.core.designsystem.icon.MifosIcons import org.mifospay.core.ui.EmptyContentScreen import org.mifospay.core.ui.utility.AddCardChip @@ -70,7 +68,6 @@ fun AccountsScreen( ) } -@OptIn(ExperimentalMaterialApi::class) @Composable private fun AccountScreen( accountsUiState: AccountsUiState, @@ -97,7 +94,7 @@ private fun AccountScreen( subTitle = stringResource(id = R.string.feature_accounts_unexpected_error_subtitle), modifier = Modifier, iconTint = MaterialTheme.colorScheme.onSurface, - iconImageVector = Icons.Rounded.Info, + iconImageVector = MifosIcons.Info, ) } diff --git a/feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/details/BankAccountDetailScreen.kt b/feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/details/BankAccountDetailScreen.kt index 56589e89e..4e99dae28 100644 --- a/feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/details/BankAccountDetailScreen.kt +++ b/feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/details/BankAccountDetailScreen.kt @@ -17,9 +17,6 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ChevronRight -import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme @@ -31,7 +28,9 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.mifospay.core.model.domain.BankAccountDetails +import org.mifospay.core.designsystem.component.MifosButton import org.mifospay.core.designsystem.component.MifosTopBar +import org.mifospay.core.designsystem.icon.MifosIcons import org.mifospay.feature.bank.accounts.R @Composable @@ -194,7 +193,7 @@ private fun BankAccountDetailButton( hasTrailingIcon: Boolean = false, ) { if (isUpiEnabled) { - Button( + MifosButton( onClick = { onClick.invoke() }, colors = ButtonDefaults.buttonColors(MaterialTheme.colorScheme.primary), modifier = modifier @@ -213,7 +212,7 @@ private fun BankAccountDetailButton( ) if (hasTrailingIcon) { Icon( - imageVector = Icons.Filled.ChevronRight, + imageVector = MifosIcons.ChevronRight, contentDescription = null, tint = MaterialTheme.colorScheme.onPrimary, ) diff --git a/feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/link/LinkBankAccountScreen.kt b/feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/link/LinkBankAccountScreen.kt index 1c81b3c13..ec319bc8c 100644 --- a/feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/link/LinkBankAccountScreen.kt +++ b/feature/accounts/src/main/kotlin/org/mifospay/feature/bank/accounts/link/LinkBankAccountScreen.kt @@ -28,8 +28,6 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Search import androidx.compose.material3.CardDefaults import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider @@ -183,7 +181,7 @@ private fun BankListScreenContent( .fillMaxWidth() .padding(horizontal = 16.dp), trailingIcon = { - Icon(imageVector = Icons.Filled.Search, contentDescription = null) + Icon(imageVector = MifosIcons.Search, contentDescription = null) }, ) diff --git a/feature/auth/build.gradle.kts b/feature/auth/build.gradle.kts index 06ede5166..31e838893 100644 --- a/feature/auth/build.gradle.kts +++ b/feature/auth/build.gradle.kts @@ -22,9 +22,7 @@ android { dependencies { implementation(projects.core.data) - implementation(libs.compose.country.code.picker) - // TODO:: this should be removed - implementation(libs.compose.material) + implementation(projects.libs.countryCodePicker) // Credentials Manager implementation(libs.androidx.credentials) diff --git a/feature/auth/src/main/kotlin/org/mifospay/feature/auth/login/LoginScreen.kt b/feature/auth/src/main/kotlin/org/mifospay/feature/auth/login/LoginScreen.kt index 03ae92473..361691104 100644 --- a/feature/auth/src/main/kotlin/org/mifospay/feature/auth/login/LoginScreen.kt +++ b/feature/auth/src/main/kotlin/org/mifospay/feature/auth/login/LoginScreen.kt @@ -23,11 +23,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Visibility -import androidx.compose.material.icons.filled.VisibilityOff -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme @@ -51,7 +46,9 @@ import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.mifospay.core.designsystem.component.MfOverlayLoadingWheel +import org.mifospay.core.designsystem.component.MifosButton import org.mifospay.core.designsystem.component.MifosOutlinedTextField +import org.mifospay.core.designsystem.icon.MifosIcons import org.mifospay.core.designsystem.theme.MifosTheme import org.mifospay.core.designsystem.theme.grey import org.mifospay.core.designsystem.theme.styleNormal18sp @@ -161,20 +158,19 @@ private fun LoginScreenContent( }, trailingIcon = { val image = if (passwordVisibility) { - Icons.Filled.Visibility + MifosIcons.Visibility } else { - Icons.Filled.VisibilityOff + MifosIcons.VisibilityOff } IconButton(onClick = { passwordVisibility = !passwordVisibility }) { Icon(imageVector = image, null) } }, ) - Button( + MifosButton( modifier = Modifier .fillMaxWidth() .padding(top = 16.dp), - colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary), enabled = userName.text.isNotEmpty() && password.text.isNotEmpty(), onClick = { login.invoke(userName.text, password.text) diff --git a/feature/auth/src/main/kotlin/org/mifospay/feature/auth/mobileVerify/MobileVerificationScreen.kt b/feature/auth/src/main/kotlin/org/mifospay/feature/auth/mobileVerify/MobileVerificationScreen.kt index b867b7e55..ef304a4e9 100644 --- a/feature/auth/src/main/kotlin/org/mifospay/feature/auth/mobileVerify/MobileVerificationScreen.kt +++ b/feature/auth/src/main/kotlin/org/mifospay/feature/auth/mobileVerify/MobileVerificationScreen.kt @@ -22,10 +22,8 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.material.TextFieldDefaults -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -43,8 +41,9 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.togitech.ccp.component.TogiCountryCodePicker +import com.mifos.library.countrycodepicker.CountryCodePicker import org.mifospay.common.Constants +import org.mifospay.core.designsystem.component.MifosButton import org.mifospay.core.designsystem.component.MifosLoadingWheel import org.mifospay.core.designsystem.component.MifosOutlinedTextField import org.mifospay.core.designsystem.theme.MifosTheme @@ -167,11 +166,11 @@ private fun MobileVerificationScreen( } } - Button( + MifosButton( modifier = Modifier .fillMaxWidth() .padding(horizontal = 32.dp, vertical = 16.dp), - colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary), + color = MaterialTheme.colorScheme.primary, enabled = if (uiState == MobileVerificationUiState.VerifyPhone) { isNumberValid } else { @@ -204,10 +203,10 @@ private fun EnterPhoneScreen( modifier: Modifier = Modifier, ) { val keyboardController = LocalSoftwareKeyboardController.current - TogiCountryCodePicker( + CountryCodePicker( modifier = modifier, shape = RoundedCornerShape(8.dp), - colors = TextFieldDefaults.outlinedTextFieldColors( + colors = OutlinedTextFieldDefaults.colors( focusedBorderColor = MaterialTheme.colorScheme.primary, ), onValueChange = { (code, phone), isValid -> diff --git a/feature/auth/src/main/kotlin/org/mifospay/feature/auth/signup/SignupScreen.kt b/feature/auth/src/main/kotlin/org/mifospay/feature/auth/signup/SignupScreen.kt index 76bc47ae9..1306520e9 100644 --- a/feature/auth/src/main/kotlin/org/mifospay/feature/auth/signup/SignupScreen.kt +++ b/feature/auth/src/main/kotlin/org/mifospay/feature/auth/signup/SignupScreen.kt @@ -21,8 +21,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api @@ -53,6 +51,7 @@ import org.mifospay.core.data.util.Constants.MIFOS_MERCHANT_SAVINGS_PRODUCT_ID import org.mifospay.core.designsystem.component.MfOutlinedTextField import org.mifospay.core.designsystem.component.MfOverlayLoadingWheel import org.mifospay.core.designsystem.component.MfPasswordTextField +import org.mifospay.core.designsystem.component.MifosButton import org.mifospay.core.designsystem.theme.styleMedium16sp import org.mifospay.feature.auth.R import org.mifospay.feature.auth.utils.ValidateUtil.isValidEmail @@ -333,12 +332,11 @@ private fun SignupScreenContent( selectedState = it } HorizontalDivider(thickness = 24.dp, color = Color.White) - Button( - modifier = - Modifier + MifosButton( + modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp), - colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.primary), + color = MaterialTheme.colorScheme.primary, enabled = true, onClick = { validateAllFields() diff --git a/feature/auth/src/main/kotlin/org/mifospay/feature/auth/socialSignup/SocialSignupMethodScreen.kt b/feature/auth/src/main/kotlin/org/mifospay/feature/auth/socialSignup/SocialSignupMethodScreen.kt index eb2c76431..7337b5bfa 100644 --- a/feature/auth/src/main/kotlin/org/mifospay/feature/auth/socialSignup/SocialSignupMethodScreen.kt +++ b/feature/auth/src/main/kotlin/org/mifospay/feature/auth/socialSignup/SocialSignupMethodScreen.kt @@ -32,7 +32,6 @@ import androidx.compose.material3.CheckboxDefaults import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -63,6 +62,8 @@ import org.mifospay.common.Constants import org.mifospay.core.data.util.Constants.MIFOS_CONSUMER_SAVINGS_PRODUCT_ID import org.mifospay.core.data.util.Constants.MIFOS_MERCHANT_SAVINGS_PRODUCT_ID import org.mifospay.core.designsystem.component.MifosBottomSheet +import org.mifospay.core.designsystem.component.MifosOutlinedButton +import org.mifospay.core.designsystem.theme.MifosTheme import org.mifospay.feature.auth.R const val TAG = "Social Login" @@ -215,14 +216,16 @@ private fun SignupMethodContentScreen( modifier = Modifier.padding(top = 16.dp), text = stringResource(id = R.string.feature_auth_create_an_account), ) - OutlinedButton( + MifosOutlinedButton( modifier = Modifier.padding(top = 48.dp), onClick = { onSignUpAsMerchant.invoke(checkedGoogleAccountState) }, border = BorderStroke(1.dp, Color.LightGray), shape = RoundedCornerShape(4.dp), - colors = ButtonDefaults.outlinedButtonColors(contentColor = MaterialTheme.colorScheme.primary), + colors = ButtonDefaults.outlinedButtonColors( + contentColor = MaterialTheme.colorScheme.primary, + ), ) { Text( text = stringResource(id = R.string.feature_auth_sign_up_as_merchant).uppercase(), @@ -254,14 +257,16 @@ private fun SignupMethodContentScreen( thickness = 1.dp, ) } - OutlinedButton( + MifosOutlinedButton( modifier = Modifier.padding(top = 24.dp), onClick = { onSignupAsCustomer.invoke(checkedGoogleAccountState) }, border = BorderStroke(1.dp, Color.LightGray), shape = RoundedCornerShape(4.dp), - colors = ButtonDefaults.outlinedButtonColors(contentColor = MaterialTheme.colorScheme.primary), + colors = ButtonDefaults.outlinedButtonColors( + contentColor = MaterialTheme.colorScheme.primary, + ), ) { Text( text = stringResource(id = R.string.feature_auth_sign_up_as_customer).uppercase(), @@ -322,7 +327,11 @@ private fun GoogleIdTokenCredential?.signUpWithMifos( @Preview @Composable private fun SignupMethodContentScreenPreview() { - MaterialTheme { - SignupMethodContentScreen(true, {}, {}) + MifosTheme { + SignupMethodContentScreen( + showProgress = true, + onSignUpAsMerchant = {}, + onSignupAsCustomer = {}, + ) } } diff --git a/feature/history/src/main/kotlin/org/mifospay/feature/history/HistoryScreen.kt b/feature/history/src/main/kotlin/org/mifospay/feature/history/HistoryScreen.kt index 5bb170539..328b6bbb7 100644 --- a/feature/history/src/main/kotlin/org/mifospay/feature/history/HistoryScreen.kt +++ b/feature/history/src/main/kotlin/org/mifospay/feature/history/HistoryScreen.kt @@ -21,10 +21,6 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Info -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -47,7 +43,9 @@ import com.mifospay.core.model.domain.Transaction import com.mifospay.core.model.domain.TransactionType import com.mifospay.core.model.entity.accounts.savings.TransferDetail import org.mifospay.core.designsystem.component.MifosBottomSheet +import org.mifospay.core.designsystem.component.MifosButton import org.mifospay.core.designsystem.component.MifosLoadingWheel +import org.mifospay.core.designsystem.icon.MifosIcons import org.mifospay.core.designsystem.theme.lightGrey import org.mifospay.core.ui.EmptyContentScreen import org.mifospay.core.ui.TransactionItemScreen @@ -89,7 +87,7 @@ private fun HistoryScreen( subTitle = stringResource(id = R.string.feature_history_empty_no_transaction_history_title), modifier = Modifier, iconTint = MaterialTheme.colorScheme.primary, - iconImageVector = Icons.Rounded.Info, + iconImageVector = MifosIcons.Info, ) } @@ -99,7 +97,7 @@ private fun HistoryScreen( subTitle = stringResource(id = R.string.feature_history_unexpected_error_subtitle), modifier = Modifier, iconTint = MaterialTheme.colorScheme.primary, - iconImageVector = Icons.Rounded.Info, + iconImageVector = MifosIcons.Info, ) } @@ -183,13 +181,13 @@ private fun Chip( ) { val context = LocalContext.current val backgroundColor = if (selected) MaterialTheme.colorScheme.primary else lightGrey - Button( + MifosButton( modifier = modifier, onClick = { onClick() Toast.makeText(context, label, Toast.LENGTH_SHORT).show() }, - colors = ButtonDefaults.buttonColors(backgroundColor), + color = backgroundColor, ) { Text( modifier = Modifier.padding(top = 4.dp, bottom = 4.dp, start = 16.dp, end = 16.dp), diff --git a/feature/history/src/main/kotlin/org/mifospay/feature/specific/transactions/SpecificTransactionsScreen.kt b/feature/history/src/main/kotlin/org/mifospay/feature/specific/transactions/SpecificTransactionsScreen.kt index 47e325ebb..907853c89 100644 --- a/feature/history/src/main/kotlin/org/mifospay/feature/specific/transactions/SpecificTransactionsScreen.kt +++ b/feature/history/src/main/kotlin/org/mifospay/feature/specific/transactions/SpecificTransactionsScreen.kt @@ -20,15 +20,13 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Info import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -42,7 +40,6 @@ import com.mifospay.core.model.domain.Transaction import com.mifospay.core.model.domain.TransactionType import com.mifospay.core.model.domain.client.Client import com.mifospay.core.model.entity.accounts.savings.SavingAccount -import org.mifospay.common.Utils.toArrayList import org.mifospay.core.designsystem.component.MfLoadingWheel import org.mifospay.core.designsystem.component.MifosScaffold import org.mifospay.core.designsystem.icon.MifosIcons @@ -56,22 +53,15 @@ import org.mifospay.feature.history.R @Composable internal fun SpecificTransactionsScreen( - accountNumber: String, - transactions: List, backPress: () -> Unit, transactionItemClicked: (String) -> Unit, modifier: Modifier = Modifier, viewModel: SpecificTransactionsViewModel = hiltViewModel(), ) { - val uiState = viewModel.uiState.collectAsStateWithLifecycle() - - LaunchedEffect(key1 = Unit) { - viewModel.setArguments(transactions.toArrayList(), accountNumber) - viewModel.getSpecificTransactions() - } + val uiState by viewModel.uiState.collectAsStateWithLifecycle() SpecificTransactionsScreen( - uiState = uiState.value, + uiState = uiState, backPress = backPress, transactionItemClicked = transactionItemClicked, modifier = modifier, @@ -115,7 +105,7 @@ internal fun SpecificTransactionsScreen( subTitle = stringResource(id = R.string.feature_history_no_transactions_found), modifier = Modifier, iconTint = MaterialTheme.colorScheme.onSurface, - iconImageVector = Icons.Rounded.Info, + iconImageVector = MifosIcons.Info, ) } else { SpecificTransactionsContent( diff --git a/feature/history/src/main/kotlin/org/mifospay/feature/specific/transactions/SpecificTransactionsViewModel.kt b/feature/history/src/main/kotlin/org/mifospay/feature/specific/transactions/SpecificTransactionsViewModel.kt index c1bf93fa4..03276dc37 100644 --- a/feature/history/src/main/kotlin/org/mifospay/feature/specific/transactions/SpecificTransactionsViewModel.kt +++ b/feature/history/src/main/kotlin/org/mifospay/feature/specific/transactions/SpecificTransactionsViewModel.kt @@ -9,38 +9,44 @@ */ package org.mifospay.feature.specific.transactions +import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import com.mifospay.core.model.domain.Transaction import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import org.mifospay.core.data.base.TaskLooper import org.mifospay.core.data.base.UseCase import org.mifospay.core.data.base.UseCaseFactory import org.mifospay.core.data.domain.usecase.account.FetchAccountTransfer import org.mifospay.core.data.util.Constants +import org.mifospay.feature.specific.transactions.SpecificTransactionsUiState.Loading +import org.mifospay.feature.specific.transactions.navigation.ACCOUNT_NUMBER_ARG +import org.mifospay.feature.specific.transactions.navigation.TRANSACTIONS_ARG import javax.inject.Inject @HiltViewModel class SpecificTransactionsViewModel @Inject constructor( private val mUseCaseFactory: UseCaseFactory, private var mTaskLooper: TaskLooper? = null, + savedStateHandle: SavedStateHandle, ) : ViewModel() { - private val _uiState: MutableStateFlow = - MutableStateFlow(SpecificTransactionsUiState.Loading) - val uiState get() = _uiState + private val _uiState: MutableStateFlow = MutableStateFlow(Loading) + val uiState = _uiState.asStateFlow() - private val _transactions: MutableStateFlow> = - MutableStateFlow(ArrayList()) - private val transactions get() = _transactions - - private val _accountNumber: MutableStateFlow = MutableStateFlow("") - private val accountNumber get() = _accountNumber - - fun getSpecificTransactions(): ArrayList { - val transactions = transactions.value - val accountNumber = accountNumber.value + init { + savedStateHandle.get(ACCOUNT_NUMBER_ARG)?.let { accountNumber -> + savedStateHandle.get>(TRANSACTIONS_ARG)?.let { transactions -> + getSpecificTransactions(accountNumber, transactions) + } + } + } + private fun getSpecificTransactions( + accountNumber: String, + transactions: ArrayList, + ): ArrayList { val specificTransactions = ArrayList() if (transactions.size > 0) { for (i in transactions.indices) { @@ -56,44 +62,41 @@ class SpecificTransactionsViewModel @Inject constructor( ), ) } - mTaskLooper!!.listen(object : TaskLooper.Listener { - override fun onTaskSuccess( - taskData: TaskLooper.TaskData, - response: R, - ) { - when (taskData.taskName) { - org.mifospay.common.Constants.TRANSFER_DETAILS -> { - val responseValue = response as FetchAccountTransfer.ResponseValue - val index = taskData.taskId - transactions[index].transferDetail = responseValue.transferDetail + mTaskLooper!!.listen( + object : TaskLooper.Listener { + override fun onTaskSuccess( + taskData: TaskLooper.TaskData, + response: R, + ) { + when (taskData.taskName) { + org.mifospay.common.Constants.TRANSFER_DETAILS -> { + val responseValue = response as FetchAccountTransfer.ResponseValue + val index = taskData.taskId + transactions[index].transferDetail = responseValue.transferDetail + } } } - } - override fun onComplete() { - for (transaction in transactions) { - if ( - transaction.transferDetail.fromAccount.accountNo == accountNumber || - transaction.transferDetail.toAccount.accountNo == accountNumber - ) { - specificTransactions.add(transaction) + override fun onComplete() { + for (transaction in transactions) { + if ( + transaction.transferDetail.fromAccount.accountNo == accountNumber || + transaction.transferDetail.toAccount.accountNo == accountNumber + ) { + specificTransactions.add(transaction) + } } + _uiState.value = SpecificTransactionsUiState.Success(specificTransactions) } - _uiState.value = SpecificTransactionsUiState.Success(specificTransactions) - } - override fun onFailure(message: String?) { - _uiState.value = SpecificTransactionsUiState.Error - } - }) + override fun onFailure(message: String?) { + _uiState.value = SpecificTransactionsUiState.Error + } + }, + ) } return specificTransactions } - - fun setArguments(transactions: ArrayList, accountNumber: String) { - _accountNumber.value = accountNumber - _transactions.value = transactions - } } sealed class SpecificTransactionsUiState { diff --git a/feature/history/src/main/kotlin/org/mifospay/feature/specific/transactions/navigation/SpecificTransactionsNavigation.kt b/feature/history/src/main/kotlin/org/mifospay/feature/specific/transactions/navigation/SpecificTransactionsNavigation.kt index 5abdc8e96..ceac2608f 100644 --- a/feature/history/src/main/kotlin/org/mifospay/feature/specific/transactions/navigation/SpecificTransactionsNavigation.kt +++ b/feature/history/src/main/kotlin/org/mifospay/feature/specific/transactions/navigation/SpecificTransactionsNavigation.kt @@ -17,30 +17,28 @@ import androidx.navigation.NavType import androidx.navigation.compose.composable import androidx.navigation.navArgument import com.mifospay.core.model.domain.Transaction -import org.mifospay.common.Constants import org.mifospay.feature.specific.transactions.SpecificTransactionsScreen -const val SPECIFIC_TRANSACTIONS_ROUTE = "specific_transactions_route" +const val SPECIFIC_TRANSACTIONS_BASE_ROUTE = "specific_transactions_route" +const val ACCOUNT_NUMBER_ARG = "accountNumber" +const val TRANSACTIONS_ARG = "transactions" + +const val SPECIFIC_TRANSACTIONS_ROUTE = SPECIFIC_TRANSACTIONS_BASE_ROUTE + + "?${ACCOUNT_NUMBER_ARG}={$ACCOUNT_NUMBER_ARG}" + + "&${TRANSACTIONS_ARG}={$TRANSACTIONS_ARG}" fun NavGraphBuilder.specificTransactionsScreen( onBackClick: () -> Unit, onTransactionItemClicked: (String) -> Unit, ) { composable( - route = "$SPECIFIC_TRANSACTIONS_ROUTE?${Constants.ACCOUNT_NUMBER}={accountNumber}&${Constants.TRANSACTIONS}={transactions}", + route = SPECIFIC_TRANSACTIONS_ROUTE, arguments = listOf( - navArgument(Constants.ACCOUNT_NUMBER) { type = NavType.StringType }, - navArgument(Constants.TRANSACTIONS) { type = NavType.StringType }, + navArgument(ACCOUNT_NUMBER_ARG) { type = NavType.StringType }, + navArgument(ACCOUNT_NUMBER_ARG) { type = NavType.StringType }, ), - ) { backStackEntry -> - val accountNumber = backStackEntry.arguments?.getString(Constants.ACCOUNT_NUMBER) ?: "" - val transactions = - backStackEntry.arguments?.getParcelableArrayList(Constants.TRANSACTIONS) - ?: arrayListOf() - + ) { SpecificTransactionsScreen( - accountNumber = accountNumber, - transactions = transactions.toList(), backPress = onBackClick, transactionItemClicked = onTransactionItemClicked, ) @@ -51,5 +49,5 @@ fun NavController.navigateToSpecificTransactions( accountNumber: String, transactions: ArrayList, ) { - this.navigate("$SPECIFIC_TRANSACTIONS_ROUTE?${Constants.ACCOUNT_NUMBER}=$accountNumber&${Constants.TRANSACTIONS}=$transactions") + this.navigate("$SPECIFIC_TRANSACTIONS_BASE_ROUTE?${ACCOUNT_NUMBER_ARG}=$accountNumber&${TRANSACTIONS_ARG}=$transactions") } diff --git a/feature/kyc/build.gradle.kts b/feature/kyc/build.gradle.kts index ef4ccfccd..c57fe120b 100644 --- a/feature/kyc/build.gradle.kts +++ b/feature/kyc/build.gradle.kts @@ -18,10 +18,13 @@ android { dependencies { implementation(projects.core.data) - implementation(libs.compose.material) + + implementation(projects.libs.countryCodePicker) + implementation(projects.libs.pullrefresh) + implementation(libs.sheets.compose.dialogs.core) implementation(libs.sheets.compose.dialogs.calender) - implementation(libs.compose.country.code.picker) + // TODO:: this should be removed implementation(libs.squareup.okhttp) } \ No newline at end of file diff --git a/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCDescriptionScreen.kt b/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCDescriptionScreen.kt index 35d032c17..da040068b 100644 --- a/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCDescriptionScreen.kt +++ b/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCDescriptionScreen.kt @@ -22,14 +22,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Check -import androidx.compose.material.icons.rounded.Info -import androidx.compose.material.pullrefresh.PullRefreshIndicator -import androidx.compose.material.pullrefresh.pullRefresh -import androidx.compose.material.pullrefresh.rememberPullRefreshState -import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme @@ -51,8 +43,13 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.mifos.library.pullrefresh.PullRefreshIndicator +import com.mifos.library.pullrefresh.pullRefresh +import com.mifos.library.pullrefresh.rememberPullRefreshState import com.mifospay.core.model.entity.kyc.KYCLevel1Details +import org.mifospay.core.designsystem.component.MifosButton import org.mifospay.core.designsystem.component.MifosOverlayLoadingWheel +import org.mifospay.core.designsystem.icon.MifosIcons import org.mifospay.core.ui.EmptyContentScreen import org.mifospay.kyc.R @@ -87,7 +84,6 @@ fun KYCScreen( ) } -@OptIn(ExperimentalMaterialApi::class) @Composable private fun KYCDescriptionScreen( kUiState: KYCDescriptionUiState, @@ -114,7 +110,7 @@ private fun KYCDescriptionScreen( subTitle = stringResource(id = R.string.feature_kyc_unexpected_error_subtitle), modifier = Modifier, iconTint = MaterialTheme.colorScheme.primary, - iconImageVector = Icons.Rounded.Info, + iconImageVector = MifosIcons.Info, ) } @@ -224,7 +220,7 @@ private fun ButtonComponent( onButtonClicked: () -> Unit, modifier: Modifier = Modifier, ) { - Button( + MifosButton( modifier = modifier .width(130.dp) .heightIn(38.dp) @@ -269,7 +265,7 @@ private fun IconComponent( .height(23.dp), ) { Icon( - Icons.Filled.Check, + imageVector = MifosIcons.Check, contentDescription = stringResource(R.string.feature_kyc_check), modifier = Modifier .size(20.dp), diff --git a/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel1Screen.kt b/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel1Screen.kt index 301cc6f90..501f40cec 100644 --- a/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel1Screen.kt +++ b/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel1Screen.kt @@ -20,10 +20,9 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.material.TextFieldDefaults -import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -46,8 +45,9 @@ import com.maxkeppeler.sheets.calendar.CalendarDialog import com.maxkeppeler.sheets.calendar.models.CalendarConfig import com.maxkeppeler.sheets.calendar.models.CalendarSelection import com.maxkeppeler.sheets.calendar.models.CalendarStyle -import com.togitech.ccp.component.TogiCountryCodePicker +import com.mifos.library.countrycodepicker.CountryCodePicker import org.mifospay.core.designsystem.component.MfOverlayLoadingWheel +import org.mifospay.core.designsystem.component.MifosButton import org.mifospay.core.designsystem.component.MifosOutlinedTextField import org.mifospay.core.designsystem.theme.MifosTheme import org.mifospay.kyc.R @@ -187,10 +187,10 @@ private fun Kyc1Form( .padding(vertical = 7.dp), ) { val keyboardController = LocalSoftwareKeyboardController.current - TogiCountryCodePicker( + CountryCodePicker( modifier = Modifier, shape = RoundedCornerShape(3.dp), - colors = TextFieldDefaults.outlinedTextFieldColors( + colors = OutlinedTextFieldDefaults.colors( focusedBorderColor = MaterialTheme.colorScheme.primary, ), onValueChange = { (code, phone), isValid -> @@ -236,7 +236,7 @@ private fun Kyc1Form( ) } - Button( + MifosButton( onClick = { submitData(kycDetails) }, diff --git a/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel2Screen.kt b/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel2Screen.kt index 610dcef1e..42363e4ee 100644 --- a/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel2Screen.kt +++ b/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel2Screen.kt @@ -26,7 +26,6 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Button import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarDuration @@ -46,7 +45,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -55,9 +53,11 @@ import androidx.core.content.ContextCompat import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.compose.collectAsStateWithLifecycle import kotlinx.coroutines.launch import org.mifospay.core.designsystem.component.MfOverlayLoadingWheel +import org.mifospay.core.designsystem.component.MifosButton import org.mifospay.core.designsystem.component.MifosOutlinedTextField import org.mifospay.core.designsystem.theme.MifosTheme import org.mifospay.kyc.R @@ -269,7 +269,7 @@ private fun Kyc2Form( ) Row { - Button( + MifosButton( onClick = { if (storagePermissionGranted) { docLauncher.launch(arrayOf("application/pdf", "image/*")) @@ -294,7 +294,7 @@ private fun Kyc2Form( } } - Button( + MifosButton( modifier = Modifier.align(Alignment.CenterHorizontally), onClick = { result?.let { uri -> diff --git a/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel3Screen.kt b/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel3Screen.kt index f8bcece6c..929282dcd 100644 --- a/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel3Screen.kt +++ b/feature/kyc/src/main/kotlin/org/mifospay/feature/kyc/KYCLevel3Screen.kt @@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -29,6 +28,7 @@ import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.mifospay.core.designsystem.component.MfOverlayLoadingWheel +import org.mifospay.core.designsystem.component.MifosButton import org.mifospay.core.designsystem.component.MifosOutlinedTextField import org.mifospay.core.designsystem.theme.MifosTheme import org.mifospay.kyc.R @@ -91,7 +91,7 @@ private fun Kyc3Form( .padding(vertical = 8.dp), ) - Button( + MifosButton( onClick = {}, modifier = Modifier .align(Alignment.CenterHorizontally) diff --git a/feature/kyc/src/main/res/layout/feature_kyc_fragment_kyc.xml b/feature/kyc/src/main/res/layout/feature_kyc_fragment_kyc.xml deleted file mode 100644 index 1044e2af1..000000000 --- a/feature/kyc/src/main/res/layout/feature_kyc_fragment_kyc.xml +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - - - - - -