Skip to content

Commit

Permalink
refactor: migrated loan repayment schedule scree to compose
Browse files Browse the repository at this point in the history
  • Loading branch information
PratyushSingh07 committed Jun 3, 2024
1 parent 4fa0ae0 commit a45c07f
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 223 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,10 @@ import android.view.View
import android.view.ViewGroup
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.fragment.app.viewModels
import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler
import dagger.hilt.android.AndroidEntryPoint
import org.mifos.mobile.R
import org.mifos.mobile.models.accounts.loan.LoanWithAssociations
import org.mifos.mobile.models.accounts.loan.Periods
import org.mifos.mobile.models.accounts.loan.tableview.Cell
import org.mifos.mobile.models.accounts.loan.tableview.ColumnHeader
import org.mifos.mobile.models.accounts.loan.tableview.RowHeader
import org.mifos.mobile.ui.adapters.LoanRepaymentScheduleAdapter
import org.mifos.mobile.core.ui.theme.MifosMobileTheme
import org.mifos.mobile.ui.fragments.base.BaseFragment
import org.mifos.mobile.utils.Constants
import org.mifos.mobile.utils.ParcelableAndSerializableUtils.getCheckedParcelable
import javax.inject.Inject

/**
* Created by Rajan Maurya on 03/03/17.
Expand All @@ -28,7 +18,6 @@ import javax.inject.Inject
class LoanRepaymentScheduleFragment : BaseFragment() {

private var loanId: Long? = 0
private var loanWithAssociations: LoanWithAssociations? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (arguments != null) loanId = arguments?.getLong(Constants.LOAN_ID)
Expand All @@ -39,185 +28,16 @@ class LoanRepaymentScheduleFragment : BaseFragment() {
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
// _binding = FragmentLoanRepaymentScheduleBinding.inflate(inflater, container, false)
// sweetUIErrorHandler = SweetUIErrorHandler(context, binding.root)
// showUserInterface()
// if (savedInstanceState == null) {
// viewModel.loanLoanWithAssociations(loanId)
// }
// return binding.root
return ComposeView(requireContext()).apply {
setContent {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
LoanRepaymentScheduleScreen(navigateBack = { activity?.supportFragmentManager?.popBackStack() }, loanId = loanId ?: 1)
MifosMobileTheme {
LoanRepaymentScheduleScreen(navigateBack = { activity?.supportFragmentManager?.popBackStack() }, loanId = loanId ?: 1)
}
}
}
}

// override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// super.onViewCreated(view, savedInstanceState)
//
// viewLifecycleOwner.lifecycleScope.launch {
// repeatOnLifecycle(Lifecycle.State.STARTED) {
// viewModel.loanUiState.collect {
// when (it) {
// is LoanUiState.Loading -> showProgress()
// is LoanUiState.ShowError -> {
// hideProgress()
//// showError(getString(it.message))
// }
//
// is LoanUiState.ShowLoan -> {
// hideProgress()
// showLoanRepaymentSchedule(it.loanWithAssociations)
// }
//
// is LoanUiState.ShowEmpty -> {
// hideProgress()
//// showEmptyRepaymentsSchedule(loanWithAssociations)
// }
//
// else -> throw IllegalStateException("Unexpected state: $it")
// }
// }
// }
// }
//
//// binding.layoutError.btnTryAgain.setOnClickListener {
//// retryClicked()
//// }
// }

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putParcelable(Constants.LOAN_ACCOUNT, loanWithAssociations)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
if (savedInstanceState != null) {
showLoanRepaymentSchedule(
savedInstanceState.getCheckedParcelable(
LoanWithAssociations::class.java,
Constants.LOAN_ACCOUNT
)
)
}
}

/**
* Fetches [LoanWithAssociations] for a loan with `loanId`
*
* @param loanWithAssociations Contains details about Repayment Schedule
*/
fun showLoanRepaymentSchedule(loanWithAssociations: LoanWithAssociations?) {
/**
* Handled this logic in compose UI
*/
// this.loanWithAssociations = loanWithAssociations
// var currencyRepresentation =
// loanWithAssociations?.currency?.displaySymbol ?: loanWithAssociations?.currency?.code
// loanRepaymentScheduleAdapter
// ?.setCurrency(currencyRepresentation)
// setTableViewList(loanWithAssociations?.repaymentSchedule?.periods)
// binding.tvAccountNumber.text = loanWithAssociations?.accountNo
// binding.tvDisbursementDate.text =
// DateHelper.getDateAsString(loanWithAssociations?.timeline?.expectedDisbursementDate)
// binding.tvNumberOfPayments.text = loanWithAssociations?.numberOfRepayments.toString()
}

private fun setTableViewList(periods: List<Periods>?) {
/**
* Handled this logic in compose UI
*/
// val mColumnHeaderList: MutableList<ColumnHeader?> = ArrayList()
// val mRowHeaders: MutableList<RowHeader?> = ArrayList()
// val mCellList: MutableList<List<Cell?>> = ArrayList()
// mColumnHeaderList.add(ColumnHeader(getString(R.string.date)))
// mColumnHeaderList.add(ColumnHeader(getString(R.string.loan_balance)))
// mColumnHeaderList.add(ColumnHeader(getString(R.string.repayment)))
// if (periods != null) {
// for ((i, period) in periods.withIndex()) {
// val cells: MutableList<Cell> = ArrayList()
// cells.add(Cell(period))
// cells.add(Cell(period))
// cells.add(Cell(period))
// mCellList.add(cells)
// mRowHeaders.add(RowHeader(i + 1))
// }
// }
// loanRepaymentScheduleAdapter?.setAllItems(mColumnHeaderList, mRowHeaders, mCellList)
}

/**
* Shows an empty layout for a loan with `loanId` which has no Repayment Schedule
*
* @param loanWithAssociations Contains details about Repayment Schedule
*/
fun showEmptyRepaymentsSchedule(loanWithAssociations: LoanWithAssociations?) {
/**
* Handled this logic in compose UI
*/
// binding.tvAccountNumber.text = loanWithAssociations?.accountNo
// binding.tvDisbursementDate.text =
// DateHelper.getDateAsString(loanWithAssociations?.timeline?.expectedDisbursementDate)
// binding.tvNumberOfPayments.text = loanWithAssociations?.numberOfRepayments.toString()
// sweetUIErrorHandler?.showSweetEmptyUI(
// getString(R.string.repayment_schedule),
// R.drawable.ic_charges,
// binding.tvRepaymentSchedule,
// binding.layoutError.root,
// )
}

/**
* It is called whenever any error occurs while executing a request
*
* @param message Error message that tells the user about the problem.
*/
// fun showError(message: String?) {
// if (!Network.isConnected(activity)) {
// sweetUIErrorHandler?.showSweetNoInternetUI(
// binding.tvRepaymentSchedule,
// binding.layoutError.root,
// )
// } else {
// sweetUIErrorHandler?.showSweetErrorUI(
// message,
// binding.tvRepaymentSchedule,
// binding.layoutError.root,
// )
// Toast.makeText(activity, message, Toast.LENGTH_SHORT).show()
// }
// }
//
// fun retryClicked() {
// if (Network.isConnected(context)) {
// sweetUIErrorHandler?.hideSweetErrorLayoutUI(
// binding.tvRepaymentSchedule,
// binding.layoutError.root,
// )
// viewModel.loanLoanWithAssociations(loanId)
// } else {
// Toast.makeText(
// context,
// getString(R.string.internet_not_connected),
// Toast.LENGTH_SHORT,
// ).show()
// }
// }
//
// override fun onDestroyView() {
// super.onDestroyView()
// hideProgressBar()
// _binding = null
// }
//
// override fun onConfigurationChanged(newConfig: Configuration) {
// super.onConfigurationChanged(newConfig)
// showUserInterface()
// }

companion object {
fun newInstance(loanId: Long?): LoanRepaymentScheduleFragment {
val loanRepaymentScheduleFragment = LoanRepaymentScheduleFragment()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.mifos.mobile.ui.loan_repayment_schedule

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand Down Expand Up @@ -122,15 +123,15 @@ fun LoanRepaymentScheduleCard(loanWithAssociations: LoanWithAssociations) {
Column(
modifier = Modifier.padding(8.dp)
) {
TableRow(
LoanRepaymentScheduleCardItem(
label = stringResource(id = R.string.account_number),
value = loanWithAssociations.accountNo ?: "--"
)
TableRow(
LoanRepaymentScheduleCardItem(
label = stringResource(id = R.string.disbursement_date),
value = DateHelper.getDateAsString(loanWithAssociations.timeline?.expectedDisbursementDate)
)
TableRow(
LoanRepaymentScheduleCardItem(
label = stringResource(id = R.string.no_of_payments),
value = loanWithAssociations.numberOfRepayments.toString()
)
Expand All @@ -144,7 +145,7 @@ fun RepaymentScheduleTable(currency: String, periods: List<Periods>) {
LazyColumn(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
.padding(12.dp)
) {
item {
Row {
Expand Down Expand Up @@ -172,25 +173,28 @@ fun RepaymentScheduleTable(currency: String, periods: List<Periods>) {
} else {
EmptyDataView(icon = R.drawable.ic_charges, error = R.string.repayment_schedule)
}

}


@Composable
fun RowScope.TableCell(
text: String,
weight: Float
) {
val borderColor = if (isSystemInDarkTheme()) Color.Gray else Color.Black

Text(
text = text,
Modifier
.border(1.dp, Color.Black)
modifier = Modifier
.border(1.dp, borderColor)
.weight(weight)
.padding(8.dp)
.padding(4.dp),
textAlign = TextAlign.Center
)
}

@Composable
fun TableRow(label: String, value: String) {
fun LoanRepaymentScheduleCardItem(label: String, value: String) {
Row(
modifier = Modifier
.fillMaxWidth()
Expand All @@ -200,7 +204,7 @@ fun TableRow(label: String, value: String) {
Text(
text = label,
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.weight(1f)
modifier = Modifier.weight(1f),
)
Text(
text = value,
Expand All @@ -216,15 +220,10 @@ class LoanRepaymentSchedulePreviewProvider : PreviewParameterProvider<LoanUiStat
get() = sequenceOf(
LoanUiState.Loading,
LoanUiState.ShowError(R.string.repayment_schedule),
LoanUiState.ShowLoan(sampleLoanWithAssociations[0])
LoanUiState.ShowLoan(LoanWithAssociations())
)
}

val sampleLoanWithAssociations = List(20) {
LoanWithAssociations()
}


@Preview(showSystemUi = true, showBackground = true)
@Composable
private fun LoanRepaymentScheduleScreenPreview(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ fun MifosErrorComponent(
) {
when {
!isNetworkConnected -> NoInternetComponent(isRetryEnabled = isRetryEnabled) { onRetry() }
else -> EmptyDataComponent(isEmptyData = isEmptyData)
else -> EmptyDataComponent(
isEmptyData = isEmptyData,
isRetryEnabled = isRetryEnabled,
onRetry = onRetry
)
}
}

Expand Down Expand Up @@ -69,7 +73,7 @@ fun NoInternetComponent(

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

if(isRetryEnabled) {
if (isRetryEnabled) {
FilledTonalButton(onClick = { onRetry.invoke() }) {
Text(text = stringResource(id = R.string.retry))
}
Expand All @@ -80,30 +84,41 @@ fun NoInternetComponent(
@Composable
fun EmptyDataComponent(
modifier: Modifier = Modifier.fillMaxSize(),
isEmptyData: Boolean = false
isEmptyData: Boolean = false,
isRetryEnabled: Boolean = false,
onRetry: () -> Unit = {}
) {
Column(
modifier = modifier,
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Icon(
modifier = Modifier
.size(100.dp)
.padding(bottom = 12.dp),
imageVector = Icons.Filled.Info,
contentDescription = null,
tint = MaterialTheme.colorScheme.onSecondary
)
Column(
modifier = modifier,
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Icon(
modifier = Modifier
.size(100.dp)
.padding(bottom = 12.dp),
imageVector = Icons.Filled.Info,
contentDescription = null,
tint = MaterialTheme.colorScheme.onSecondary
)

Text(
modifier= Modifier.padding(horizontal = 20.dp),
text = if(isEmptyData) stringResource(id = R.string.no_data) else stringResource(id = R.string.something_went_wrong),
style = TextStyle(fontSize = 20.sp),
color = MaterialTheme.colorScheme.onSecondary,
textAlign = TextAlign.Center
)
Text(
modifier = Modifier.padding(horizontal = 20.dp),
text = if (isEmptyData) stringResource(id = R.string.no_data) else stringResource(id = R.string.something_went_wrong),
style = TextStyle(fontSize = 20.sp),
color = MaterialTheme.colorScheme.onSecondary,
textAlign = TextAlign.Center
)

if (isRetryEnabled) {
FilledTonalButton(
modifier = Modifier.padding(top = 8.dp),
onClick = { onRetry.invoke() }
) {
Text(text = stringResource(id = R.string.retry))
}
}
}
}


Expand Down

0 comments on commit a45c07f

Please sign in to comment.