Skip to content

Commit

Permalink
Merge branch 'master' into collection_sheet_details
Browse files Browse the repository at this point in the history
  • Loading branch information
Aditya-gupta99 authored Jul 13, 2024
2 parents 7e09ec3 + 426301c commit 3818e01
Show file tree
Hide file tree
Showing 21 changed files with 1,553 additions and 515 deletions.
5 changes: 5 additions & 0 deletions core/data/src/main/java/com/mifos/core/data/di/DataModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.mifos.core.data.repository.ClientIdentifiersRepository
import com.mifos.core.data.repository.CreateNewCenterRepository
import com.mifos.core.data.repository.DocumentListRepository
import com.mifos.core.data.repository.GroupDetailsRepository
import com.mifos.core.data.repository.GroupListRepository
import com.mifos.core.data.repository.GroupsListRepository
import com.mifos.core.data.repository.IndividualCollectionSheetDetailsRepository
import com.mifos.core.data.repository.LoanAccountRepository
Expand All @@ -26,6 +27,7 @@ import com.mifos.core.data.repository_imp.ClientIdentifiersRepositoryImp
import com.mifos.core.data.repository_imp.CreateNewCenterRepositoryImp
import com.mifos.core.data.repository_imp.DocumentListRepositoryImp
import com.mifos.core.data.repository_imp.GroupDetailsRepositoryImp
import com.mifos.core.data.repository_imp.GroupListRepositoryImp
import com.mifos.core.data.repository_imp.GroupsListRepositoryImpl
import com.mifos.core.data.repository_imp.IndividualCollectionSheetDetailsRepositoryImp
import com.mifos.core.data.repository_imp.LoanAccountRepositoryImp
Expand Down Expand Up @@ -91,4 +93,7 @@ abstract class DataModule {

@Binds
internal abstract fun bindIndividualCollectionSheetDetailsRepositoryImp(impl: IndividualCollectionSheetDetailsRepositoryImp): IndividualCollectionSheetDetailsRepository

@Binds
internal abstract fun bindGroupListRepository(impl: GroupListRepositoryImp): GroupListRepository
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.mifos.mifosxdroid.online.grouplist
package com.mifos.core.data.repository

import com.mifos.core.objects.group.CenterWithAssociations
import com.mifos.core.objects.group.GroupWithAssociations
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.mifos.mifosxdroid.online.grouplist
package com.mifos.core.data.repository_imp

import com.mifos.core.data.repository.GroupListRepository
import com.mifos.core.network.DataManager
import com.mifos.core.objects.group.CenterWithAssociations
import com.mifos.core.objects.group.GroupWithAssociations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fun MifosScaffold(
Text(
text = it,
style = TextStyle(
fontSize = 24.sp,
fontSize = 22.sp,
fontWeight = FontWeight.Medium,
fontStyle = FontStyle.Normal
),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.mifos.core.domain.use_cases

import com.mifos.core.common.utils.Resource
import com.mifos.core.data.repository.GroupListRepository
import com.mifos.core.objects.group.CenterWithAssociations
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import rx.Subscriber
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import javax.inject.Inject

class GetGroupsByCenterUseCase @Inject constructor(private val repository: GroupListRepository) {

suspend operator fun invoke(id: Int): Flow<Resource<CenterWithAssociations>> = callbackFlow {
try {
trySend(Resource.Loading())
repository.getGroupsByCenter(id)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(object : Subscriber<CenterWithAssociations>() {
override fun onCompleted() {
}

override fun onError(e: Throwable) {
trySend(Resource.Error(e.message.toString()))
}

override fun onNext(centerWithAssociations: CenterWithAssociations) {
trySend(Resource.Success(centerWithAssociations))
}
})

awaitClose { channel.close() }
} catch (exception: Exception) {
send(Resource.Error(exception.message.toString()))
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.mifos.core.domain.use_cases

import com.mifos.core.common.utils.Resource
import com.mifos.core.data.repository.GroupListRepository
import com.mifos.core.objects.group.GroupWithAssociations
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import rx.Subscriber
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import javax.inject.Inject

class GetGroupsUseCase @Inject constructor(private val repository: GroupListRepository) {

suspend operator fun invoke(groupId: Int): Flow<Resource<GroupWithAssociations>> =
callbackFlow {
try {
trySend(Resource.Loading())
repository.getGroups(groupId)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(object : Subscriber<GroupWithAssociations>() {
override fun onCompleted() {}

override fun onError(exception: Throwable) {
trySend(Resource.Error(exception.message.toString()))
}

override fun onNext(groupWithAssociations: GroupWithAssociations) {
trySend(Resource.Success(groupWithAssociations))
}
})

awaitClose { channel.close() }
} catch (exception: Exception) {
trySend(Resource.Error(exception.message.toString()))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
package com.mifos.feature.center.center_group_list

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Arrangement
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.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.mifos.core.designsystem.component.MifosCircularProgress
import com.mifos.core.designsystem.component.MifosScaffold
import com.mifos.core.designsystem.component.MifosSweetError
import com.mifos.core.designsystem.icon.MifosIcons
import com.mifos.core.objects.client.Client
import com.mifos.core.objects.client.Status
import com.mifos.core.objects.group.CenterWithAssociations
import com.mifos.core.objects.group.Group
import com.mifos.core.ui.components.MifosEmptyUi
import com.mifos.feature.center.R

@Composable
fun GroupListScreen(
centerId: Int,
onBackPressed: () -> Unit,
loadClientsOfGroup: (List<Client>) -> Unit
) {

val viewModel: GroupListViewModel = hiltViewModel()
val state by viewModel.groupListUiState.collectAsStateWithLifecycle()
val groupAssociationState by viewModel.groupAssociationState.collectAsStateWithLifecycle()
var groupClicked by remember { mutableStateOf(false) }

LaunchedEffect(key1 = groupAssociationState) {
groupAssociationState?.let {
if (groupClicked) {
loadClientsOfGroup(it.clientMembers)
}
}
}

LaunchedEffect(key1 = Unit) {
viewModel.loadGroupByCenter(centerId)
}

GroupListScreen(
state = state,
onBackPressed = onBackPressed,
onGroupClick = {
groupClicked = true
viewModel.loadGroups(it)
},
onRetry = {
viewModel.loadGroupByCenter(centerId)
}
)
}

@Composable
fun GroupListScreen(
state: GroupListUiState,
onBackPressed: () -> Unit,
onRetry: () -> Unit,
onGroupClick: (Int) -> Unit
) {
val snackbarHostState = remember { SnackbarHostState() }

MifosScaffold(
icon = MifosIcons.arrowBack,
title = stringResource(id = R.string.feature_center_groups),
onBackPressed = onBackPressed,
snackbarHostState = snackbarHostState
) { paddingValues ->
Column(modifier = Modifier.padding(paddingValues)) {
when (state) {
is GroupListUiState.Error -> MifosSweetError(message = stringResource(id = state.message)) {
onRetry()
}

is GroupListUiState.Loading -> MifosCircularProgress()

is GroupListUiState.GroupList -> {
if (state.centerWithAssociations.groupMembers.isEmpty()) {
MifosEmptyUi(
text = stringResource(id = R.string.feature_center_no_group_list_to_show),
icon = MifosIcons.fileTask
)
} else {
GroupListContent(
centerWithAssociations = state.centerWithAssociations,
onGroupClick = onGroupClick
)
}
}
}
}
}
}


@Composable
fun GroupListContent(
centerWithAssociations: CenterWithAssociations,
onGroupClick: (Int) -> Unit
) {
LazyColumn {
items(centerWithAssociations.groupMembers) { group ->
GroupItem(group = group, onGroupClick = onGroupClick)
}
}
}


@Composable
fun GroupItem(
group: Group,
onGroupClick: (Int) -> Unit
) {
Card(
modifier = Modifier
.fillMaxWidth(),
shape = RoundedCornerShape(0.dp),
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp),
colors = CardDefaults.cardColors(
containerColor = Color.White
),
onClick = { group.id?.let { onGroupClick(it) } }
) {
Column(modifier = Modifier.padding(8.dp)) {
Row(
modifier = Modifier
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(
modifier = Modifier
.padding(8.dp),
text = group.name.toString(),
style = MaterialTheme.typography.bodyMedium
)
Text(
modifier = Modifier.padding(8.dp),
text = group.officeName.toString(),
style = MaterialTheme.typography.bodyMedium,
)
}
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
modifier = Modifier.padding(8.dp),
style = MaterialTheme.typography.bodySmall,
text = if (group.status?.value?.let { Status.isActive(it) } == true) {
stringResource(id = R.string.feature_center_active)
} else {
stringResource(id = R.string.feature_center_inactive)
}
)
Canvas(modifier = Modifier.size(16.dp)) {
if (group.status?.value?.let { Status.isActive(it) } == true) {
drawRect(Color.Green)
} else {
drawRect(Color.Red)
}
}
}
}
}
HorizontalDivider()
}

class GroupListUiStateProvider : PreviewParameterProvider<GroupListUiState> {

override val values: Sequence<GroupListUiState>
get() = sequenceOf(
GroupListUiState.Loading,
GroupListUiState.Error(R.string.feature_center_failed_to_load_group_list),
GroupListUiState.GroupList(sampleCenterWithAssociations)
)
}

@Preview(showBackground = true)
@Composable
private fun GroupListScreenPreview(
@PreviewParameter(GroupListUiStateProvider::class) state: GroupListUiState
) {
GroupListScreen(
state = state,
onBackPressed = {},
onGroupClick = {},
onRetry = {}
)
}

val sampleCenterWithAssociations = CenterWithAssociations()
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.mifos.feature.center.center_group_list

import com.mifos.core.objects.group.CenterWithAssociations

/**
* Created by Aditya Gupta on 06/08/23.
*/
sealed class GroupListUiState {

data object Loading : GroupListUiState()

data class Error(val message: Int) : GroupListUiState()

data class GroupList(val centerWithAssociations: CenterWithAssociations) : GroupListUiState()
}
Loading

0 comments on commit 3818e01

Please sign in to comment.