Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions feature/activate/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
/*
* 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/android-client/blob/master/LICENSE.md
*/
plugins {
alias(libs.plugins.mifos.android.feature)
alias(libs.plugins.mifos.android.library.compose)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
/*
* 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/android-client/blob/master/LICENSE.md
*/
package com.mifos.feature.activate

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
Expand All @@ -21,4 +28,4 @@ class ExampleInstrumentedTest {
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.mifos.feature.activate.test", appContext.packageName)
}
}
}
9 changes: 9 additions & 0 deletions feature/activate/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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/android-client/blob/master/LICENSE.md
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

</manifest>
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
/*
* 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/android-client/blob/master/LICENSE.md
*/
@file:OptIn(ExperimentalMaterial3Api::class)

package com.mifos.feature.activate
Expand Down Expand Up @@ -51,11 +60,10 @@ import java.text.SimpleDateFormat
import java.util.Locale

@Composable
fun ActivateScreen(
onBackPressed: () -> Unit
internal fun ActivateScreen(
onBackPressed: () -> Unit,
viewModel: ActivateViewModel = hiltViewModel(),
) {

val viewModel: ActivateViewModel = hiltViewModel()
val state by viewModel.activateUiState.collectAsStateWithLifecycle()
val id by viewModel.id.collectAsStateWithLifecycle()
val activateType by viewModel.activateType.collectAsStateWithLifecycle()
Expand All @@ -71,48 +79,48 @@ fun ActivateScreen(
when (activateType) {
Constants.ACTIVATE_CLIENT -> viewModel.activateClient(
clientId = clientIdAsInt,
clientPayload = it
clientPayload = it,
)

Constants.ACTIVATE_CENTER -> viewModel.activateCenter(
centerId = clientIdAsInt,
centerPayload = it
centerPayload = it,
)

Constants.ACTIVATE_GROUP -> viewModel.activateGroup(
groupId = clientIdAsInt,
groupPayload = it
groupPayload = it,
)

else -> {}
}
},
onBackPressed = onBackPressed
onBackPressed = onBackPressed,
)
}

@Composable
fun ActivateScreen(
internal fun ActivateScreen(
state: ActivateUiState,
onActivate: (ActivatePayload) -> Unit,
onBackPressed: () -> Unit
onBackPressed: () -> Unit,
modifier: Modifier = Modifier,
) {

val snackbarHostState = remember { SnackbarHostState() }

MifosScaffold(
icon = MifosIcons.arrowBack,
title = stringResource(id = R.string.feature_activate),
onBackPressed = onBackPressed,
snackbarHostState = snackbarHostState
snackbarHostState = snackbarHostState,
) { paddingValues ->
Column(modifier = Modifier.padding(paddingValues)) {
Column(modifier = modifier.padding(paddingValues)) {
when (state) {
is ActivateUiState.ActivatedSuccessfully -> {
Toast.makeText(
LocalContext.current,
stringResource(id = state.message),
Toast.LENGTH_SHORT
Toast.LENGTH_SHORT,
).show()
onBackPressed()
}
Expand All @@ -128,102 +136,102 @@ fun ActivateScreen(
}

@Composable
fun ActivateContent(
onActivate: (ActivatePayload) -> Unit
private fun ActivateContent(
onActivate: (ActivatePayload) -> Unit,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier) {
var showDatePicker by rememberSaveable { mutableStateOf(false) }
var activateDate by rememberSaveable { mutableLongStateOf(System.currentTimeMillis()) }
val datePickerState = rememberDatePickerState(
initialSelectedDateMillis = activateDate,
selectableDates = object : SelectableDates {
override fun isSelectableDate(utcTimeMillis: Long): Boolean {
return utcTimeMillis >= System.currentTimeMillis()
}
},
)

var showDatePicker by rememberSaveable { mutableStateOf(false) }
var activateDate by rememberSaveable { mutableLongStateOf(System.currentTimeMillis()) }
val datePickerState = rememberDatePickerState(
initialSelectedDateMillis = activateDate,
selectableDates = object : SelectableDates {
override fun isSelectableDate(utcTimeMillis: Long): Boolean {
return utcTimeMillis >= System.currentTimeMillis()
if (showDatePicker) {
DatePickerDialog(
onDismissRequest = {
showDatePicker = false
},
confirmButton = {
TextButton(
onClick = {
showDatePicker = false
datePickerState.selectedDateMillis?.let {
activateDate = it
}
},
) { Text(stringResource(id = R.string.feature_activate_select)) }
},
dismissButton = {
TextButton(
onClick = {
showDatePicker = false
},
) { Text(stringResource(id = R.string.feature_activate_cancel)) }
},
) {
DatePicker(state = datePickerState)
}
}
)

if (showDatePicker) {
DatePickerDialog(
onDismissRequest = {
showDatePicker = false
},
confirmButton = {
TextButton(
onClick = {
showDatePicker = false
datePickerState.selectedDateMillis?.let {
activateDate = it
}
}
) { Text(stringResource(id = R.string.feature_activate_select)) }
MifosDatePickerTextField(
value = SimpleDateFormat("dd MMMM yyyy", Locale.getDefault()).format(
activateDate,
),
label = R.string.feature_activate_activation_date,
openDatePicker = {
showDatePicker = true
},
dismissButton = {
TextButton(
onClick = {
showDatePicker = false
}
) { Text(stringResource(id = R.string.feature_activate_cancel)) }
}
)
{
DatePicker(state = datePickerState)
}
}

MifosDatePickerTextField(
value = SimpleDateFormat("dd MMMM yyyy", Locale.getDefault()).format(
activateDate
),
label = R.string.feature_activate_activation_date,
openDatePicker = {
showDatePicker = true
}
)
Spacer(modifier = Modifier.height(16.dp))

Spacer(modifier = Modifier.height(16.dp))

Button(
onClick = {
onActivate(
ActivatePayload(
activationDate = activateDate.toString()
Button(
onClick = {
onActivate(
ActivatePayload(
activationDate = activateDate.toString(),
),
)
)
},
modifier = Modifier
.fillMaxWidth()
.heightIn(44.dp)
.padding(start = 16.dp, end = 16.dp),
contentPadding = PaddingValues(),
colors = ButtonDefaults.buttonColors(
containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary
)
) {
Text(text = stringResource(id = R.string.feature_activate), fontSize = 16.sp)
},
modifier = Modifier
.fillMaxWidth()
.heightIn(44.dp)
.padding(start = 16.dp, end = 16.dp),
contentPadding = PaddingValues(),
colors = ButtonDefaults.buttonColors(
containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary,
),
) {
Text(text = stringResource(id = R.string.feature_activate), fontSize = 16.sp)
}
}
}


class ActivateUiStateProvider : PreviewParameterProvider<ActivateUiState> {
private class ActivateUiStateProvider : PreviewParameterProvider<ActivateUiState> {

override val values: Sequence<ActivateUiState>
get() = sequenceOf(
ActivateUiState.Loading,
ActivateUiState.Error(R.string.feature_activate_failed_to_activate_client),
ActivateUiState.ActivatedSuccessfully(R.string.feature_activate_client),
ActivateUiState.Initial
ActivateUiState.Initial,
)
}

@Preview(showBackground = true)
@Composable
private fun ActivateScreenPreview(
@PreviewParameter(ActivateUiStateProvider::class) state: ActivateUiState
@PreviewParameter(ActivateUiStateProvider::class) state: ActivateUiState,
) {
ActivateScreen(
state = state,
onActivate = {},
onBackPressed = {}
onBackPressed = {},
)
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
/*
* 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/android-client/blob/master/LICENSE.md
*/
package com.mifos.feature.activate

/**
Expand Down
Loading
Loading