Skip to content

Commit

Permalink
refactoring and visual bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
suyash01 committed Jun 12, 2024
1 parent 3727d76 commit 5d7f1de
Show file tree
Hide file tree
Showing 21 changed files with 237 additions and 181 deletions.
14 changes: 7 additions & 7 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ android {
applicationId = "com.suyash.creditmanager"
minSdk = 26
targetSdk = 34
versionCode = 16
versionName = "1.0.15"
versionCode = 17
versionName = "1.0.16"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down Expand Up @@ -66,15 +66,15 @@ dependencies {
val navVersion = "2.7.7"
val workVersion = "2.9.0"
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.2")
implementation("androidx.appcompat:appcompat:1.7.0")
implementation("androidx.activity:activity-compose:1.9.0")
implementation(platform("androidx.compose:compose-bom:2024.05.00"))
implementation(platform("androidx.compose:compose-bom:2024.06.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3:1.2.1")
implementation("androidx.compose.material:material-icons-extended:1.6.7")
implementation("androidx.compose.material:material-icons-extended:1.6.8")
implementation("com.google.dagger:hilt-android:$hiltVersion")
implementation("androidx.room:room-runtime:$roomVersion")
implementation("androidx.room:room-ktx:$roomVersion")
Expand All @@ -92,7 +92,7 @@ dependencies {
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation(platform("androidx.compose:compose-bom:2024.05.00"))
androidTestImplementation(platform("androidx.compose:compose-bom:2024.06.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
Expand Down
12 changes: 11 additions & 1 deletion app/src/main/java/com/suyash/creditmanager/domain/model/EMI.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import androidx.room.PrimaryKey
import androidx.room.TypeConverters
import com.google.gson.annotations.SerializedName
import java.time.LocalDate
import java.time.temporal.ChronoUnit
import kotlin.math.min

@Entity(
tableName = "emis"
Expand All @@ -28,4 +30,12 @@ data class EMI(
@SerializedName("id")
@PrimaryKey(autoGenerate = true)
var id: Int = 0
)
) {
fun emisPaid(): Int {
if (date.isAfter(LocalDate.now())) {
return 0
}
val emiPaid: Int = ChronoUnit.MONTHS.between(date, LocalDate.now()).toInt() + 1
return min(emiPaid, months)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class GetEMIs(private val repository: EMIRepository) {
is EMIOrder.Rate -> emis.sortedBy { it.rate }
is EMIOrder.Months -> emis.sortedBy { it.months }
is EMIOrder.Date -> emis.sortedBy { it.date }
is EMIOrder.EMIsPaid -> emis.sortedBy { it.emisPaid() }
}
}
is OrderType.Descending -> {
Expand All @@ -27,6 +28,7 @@ class GetEMIs(private val repository: EMIRepository) {
is EMIOrder.Rate -> emis.sortedByDescending { it.rate }
is EMIOrder.Months -> emis.sortedByDescending { it.months }
is EMIOrder.Date -> emis.sortedByDescending { it.date }
is EMIOrder.EMIsPaid -> emis.sortedByDescending { it.emisPaid() }
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ sealed class EMIOrder(val orderType: OrderType) {
class Rate(orderType: OrderType): EMIOrder(orderType)
class Months(orderType: OrderType): EMIOrder(orderType)
class Date(orderType: OrderType): EMIOrder(orderType)
class EMIsPaid(orderType: OrderType): EMIOrder(orderType)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.suyash.creditmanager.presentation

import android.Manifest
import android.annotation.SuppressLint
import android.content.pm.ActivityInfo
import android.os.Build
import android.os.Bundle
import androidx.activity.compose.setContent
Expand All @@ -16,9 +18,12 @@ import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@SuppressLint("SourceLockedOrientationActivity")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
ActivityCompat.requestPermissions(
this,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController
import com.suyash.creditmanager.domain.util.CardType
import com.suyash.creditmanager.presentation.util.CMDateMask
import com.suyash.creditmanager.presentation.commons.CMDateMask
import kotlinx.coroutines.flow.collectLatest
import java.util.Currency
import java.util.Locale

@Composable
@OptIn(ExperimentalMaterial3Api::class)
Expand Down Expand Up @@ -226,6 +228,16 @@ fun AddEditCCScreen(
onValueChange = { newText ->
viewModel.onEvent(AddEditCCEvent.EnteredLimit(newText))
},
prefix = {
Text(
text = Currency.getInstance(
Locale(
"",
viewModel.countryCode.value
)
).symbol
)
},
label = { Text("Limit") },
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Number,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package com.suyash.creditmanager.presentation.add_edit_cc
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.datastore.core.DataStore
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.suyash.creditmanager.data.settings.AppSettings
import com.suyash.creditmanager.domain.model.CreditCard
import com.suyash.creditmanager.domain.model.InvalidCreditCardException
import com.suyash.creditmanager.domain.use_case.CreditCardUseCases
Expand All @@ -19,8 +21,11 @@ import javax.inject.Inject
@HiltViewModel
class AddEditCCViewModel @Inject constructor(
private val creditCardUseCases: CreditCardUseCases,
private val dataStore: DataStore<AppSettings>,
savedStateHandle: SavedStateHandle
): ViewModel() {
) : ViewModel() {
private val _countryCode = mutableStateOf("")
val countryCode: State<String> = _countryCode

private val _last4Digits = mutableStateOf("")
val last4Digits: State<String> = _last4Digits
Expand Down Expand Up @@ -54,7 +59,7 @@ class AddEditCCViewModel @Inject constructor(

init {
savedStateHandle.get<Int>("ccId")?.let { ccId ->
if(ccId != -1) {
if (ccId != -1) {
viewModelScope.launch {
creditCardUseCases.getCreditCard(ccId)?.also { creditCard ->
_currentCCId.intValue = creditCard.id
Expand All @@ -64,67 +69,80 @@ class AddEditCCViewModel @Inject constructor(
_billDate.value = creditCard.billDate.toString()
_dueDate.value = creditCard.dueDate.toString()
_limit.value = creditCard.limit.toString()
_bankName.value = creditCard.bankName?:""
_bankName.value = creditCard.bankName ?: ""
_cardType.value = creditCard.cardType
}
}
}
}
viewModelScope.launch {
dataStore.data.collect {
_countryCode.value = it.countryCode
}
}
}

fun onEvent(event: AddEditCCEvent) {
when(event) {
when (event) {
is AddEditCCEvent.SelectedCardType -> {
_cardType.value = event.value
}

is AddEditCCEvent.EnteredLast4Digits -> {
if(event.value.isEmpty()) {
if (event.value.isEmpty()) {
_last4Digits.value = event.value
}
if(event.value.length <= 4 && event.value.toIntOrNull() != null && event.value.toInt() >= 0) {
if (event.value.length <= 4 && event.value.toIntOrNull() != null && event.value.toInt() >= 0) {
_last4Digits.value = event.value
}
}

is AddEditCCEvent.EnteredCardName -> {
_cardName.value = event.value
}

is AddEditCCEvent.EnteredExpiry -> {
if(event.value.isEmpty()) {
if (event.value.isEmpty()) {
_expiry.value = event.value
}
if(validateExpiry(event.value)) {
if (validateExpiry(event.value)) {
_expiry.value = event.value
}
}

is AddEditCCEvent.EnteredDueDate -> {
if(event.value.isEmpty()) {
if (event.value.isEmpty()) {
_dueDate.value = event.value
}
val value: Int? = event.value.toIntOrNull()
if(value != null && event.value.toInt() > 0 && event.value.toInt() < 31) {
if (value != null && event.value.toInt() > 0 && event.value.toInt() < 31) {
_dueDate.value = event.value
}
}

is AddEditCCEvent.EnteredBillDate -> {
if(event.value.isEmpty()) {
if (event.value.isEmpty()) {
_billDate.value = event.value
}
val value: Int? = event.value.toIntOrNull()
if(value != null && event.value.toInt() > 0 && value < 31) {
if (value != null && event.value.toInt() > 0 && value < 31) {
_billDate.value = event.value
}
}

is AddEditCCEvent.EnteredLimit -> {
if(event.value.isEmpty()) {
if (event.value.isEmpty()) {
_limit.value = event.value
}
if(event.value.toIntOrNull() != null && event.value.toInt() > 0) {
if (event.value.toIntOrNull() != null && event.value.toInt() > 0) {
_limit.value = event.value
}
}

is AddEditCCEvent.EnteredBankName -> {
_bankName.value = event.value
}

is AddEditCCEvent.UpsertCreditCard -> {
viewModelScope.launch {
try {
Expand All @@ -133,10 +151,10 @@ class AddEditCCViewModel @Inject constructor(
cardName = cardName.value,
last4Digits = last4Digits.value,
expiryDate = expiry.value,
billDate = billDate.value.toIntOrNull()?:0,
dueDate = dueDate.value.toIntOrNull()?:0,
billDate = billDate.value.toIntOrNull() ?: 0,
dueDate = dueDate.value.toIntOrNull() ?: 0,
cardType = cardType.value,
limit = limit.value.toIntOrNull()?:0,
limit = limit.value.toIntOrNull() ?: 0,
bankName = bankName.value,
id = currentCCId.value
)
Expand All @@ -151,6 +169,7 @@ class AddEditCCViewModel @Inject constructor(
}
}
}

is AddEditCCEvent.BackPressed -> {
viewModelScope.launch {
_eventFlow.emit(UiEvent.NavigateUp)
Expand All @@ -160,18 +179,18 @@ class AddEditCCViewModel @Inject constructor(
}

private fun validateExpiry(expiry: String): Boolean {
if(expiry.toIntOrNull() == null) return false
if (expiry.toIntOrNull() == null) return false
return when (expiry.length) {
1 -> expiry.toInt() < 2
2 -> expiry.toInt() in 1..12
3 -> expiry.toInt() < 130
4 -> expiry.toInt() in 101.. 1299
4 -> expiry.toInt() in 101..1299
else -> false
}
}

sealed class UiEvent {
data class ShowSnackbar(val message: String): UiEvent()
data object NavigateUp: UiEvent()
data class ShowSnackbar(val message: String) : UiEvent()
data object NavigateUp : UiEvent()
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.suyash.creditmanager.presentation.util
package com.suyash.creditmanager.presentation.commons

import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.input.OffsetMapping
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package com.suyash.creditmanager.presentation.util
package com.suyash.creditmanager.presentation.commons

import com.suyash.creditmanager.domain.util.DateFormat
import java.text.NumberFormat
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit
import java.util.Locale
import kotlin.math.min

class CMUtils {
companion object {
Expand All @@ -26,10 +24,5 @@ class CMUtils {
fun formatDate(dateTime: LocalDate, dateFormat: DateFormat): String {
return dateTime.format(DateTimeFormatter.ofPattern(dateFormat.format))
}

fun calculateEMIPaid(emiDate: LocalDate, months: Int): Int {
val emiPaid: Int = ChronoUnit.MONTHS.between(emiDate, LocalDate.now()).toInt() + 1
return min(emiPaid, months)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.suyash.creditmanager.presentation.util
package com.suyash.creditmanager.presentation.commons

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
Expand Down
Loading

0 comments on commit 5d7f1de

Please sign in to comment.