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
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.spendoo.categories.domain.entity.scheduledPayment.CreateScheduledPaym
import kotlinx.serialization.Serializable
import com.spendoo.categories.domain.entity.scheduledPayment.PaymentFrequency
import com.spendoo.categories.domain.entity.scheduledPayment.ReminderUnit
import com.spendoo.shared.domain.utils.toLocalDateTime
import com.spendoo.shared.domain.utils.toUtcInstant

@Serializable
Expand All @@ -23,7 +22,7 @@ fun CreateScheduledPayment.toDto(): CreateScheduledPaymentDto {
title = this.title,
amount = this.amount,
categoryId = this.categoryId,
startDate = this.startDate.toLocalDateTime().toUtcInstant().toString(),
startDate = this.startDate.toUtcInstant().toString(),
frequency = if (this.frequency == PaymentFrequency.CUSTOM) this.customFrequencyDays ?: 0 else this.frequency.toDays(),
reminderPeriod = this.reminderPeriod,
reminderUnit = this.reminderUnit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fun ScheduledPaymentDto.toDomain(): ScheduledPayment {
amount = this.amount,
categoryId = this.categoryId,
categoryIcon = CategoryIcon.fromStringOrDefault(this.categoryIcon),
startDate = this.startDate?.toLocalDateTimeOrDefault()?.date ?: today,
startDate = this.startDate?.toLocalDateTimeOrDefault() ?: now,
nextDueDate = this.nextDueDate?.toLocalDateTimeOrDefault() ?: now,
nextReminderDate = this.nextReminderDate?.toLocalDateTimeOrDefault()?.date ?: today,
frequency = domainFrequency,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.spendoo.categories.domain.entity.scheduledPayment

import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime

data class CreateScheduledPayment(
val title: String,
val amount: Double,
val categoryId: String,
val startDate: LocalDate,
val startDate: LocalDateTime,
val frequency: PaymentFrequency,
val customFrequencyDays: Int? = null,
val reminderPeriod: Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ data class ScheduledPayment(
val amount: Double,
val categoryId: String,
val categoryIcon: CategoryIcon,
val startDate: LocalDate,
val startDate: LocalDateTime,
val nextDueDate: LocalDateTime,
val nextReminderDate: LocalDate,
val frequency: PaymentFrequency,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import org.jetbrains.compose.resources.stringResource
import spendoo.designsystem.generated.resources.enter_custom_days
import com.spendoo.designsystem.components.button.AppButtonState
import com.spendoo.designsystem.components.dialog.DatePicker
import com.spendoo.designsystem.components.dialog.TimePicker
import com.spendoo.designsystem.components.dropdownMenu.DropdownMenu
import com.spendoo.designsystem.components.dropdownMenu.DropdownMenuItem
import com.spendoo.designsystem.components.icon.Icon
Expand All @@ -55,6 +56,8 @@ import spendoo.designsystem.generated.resources.enter_title
import spendoo.designsystem.generated.resources.frequency
import spendoo.designsystem.generated.resources.ic_arrow_down
import spendoo.designsystem.generated.resources.ic_date
import spendoo.designsystem.generated.resources.ic_clock_red
import spendoo.designsystem.generated.resources.time_label
import spendoo.designsystem.generated.resources.reminder_period
import spendoo.designsystem.generated.resources.save_payment

Expand Down Expand Up @@ -170,33 +173,64 @@ private fun AddScheduledPaymentContent(
trailingIconColor = Theme.colorScheme.text.link
)

CustomTextField(
value = state.startDate.format(),
onValueChange = { },
hint = Res.string.enter_start_date.asString(),
enabled = false,
Row(
modifier = Modifier
.fillMaxWidth()
.clickableNoRipple {
.padding(bottom = 16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
CustomTextField(
value = state.startDate.date.format(),
onValueChange = { },
hint = Res.string.enter_start_date.asString(),
enabled = false,
modifier = Modifier
.weight(1f)
.clickableNoRipple {
focusManager.clearFocus()
interactionListener.onShowDatePicker(true)
},
onTrailingIconClick = {
focusManager.clearFocus()
interactionListener.onShowDatePicker(true)
}
.padding(bottom = 16.dp),
onTrailingIconClick = {
focusManager.clearFocus()
interactionListener.onShowDatePicker(true)
},
trailingIcon = Res.drawable.ic_date.painter(),
trailingIconColor = Theme.colorScheme.text.label
)
},
trailingIcon = Res.drawable.ic_date.painter(),
trailingIconColor = Theme.colorScheme.text.label
)
CustomTextField(
value = state.startDate.time.format(),
onValueChange = { },
hint = stringResource(Res.string.time_label),
enabled = false,
modifier = Modifier
.weight(1f)
.clickableNoRipple {
focusManager.clearFocus()
interactionListener.onShowTimePicker(true)
},
onTrailingIconClick = {
focusManager.clearFocus()
interactionListener.onShowTimePicker(true)
},
trailingIcon = Res.drawable.ic_clock_red.painter(),
trailingIconColor = Theme.colorScheme.text.label
)
}

DatePicker(
showDialog = state.showDatePicker,
selectedDate = state.startDate,
selectedDate = state.startDate.date,
onDateSelected = interactionListener::onStartDateChanged,
onDismiss = { interactionListener.onShowDatePicker(false) }
)

TimePicker(
showDialog = state.showTimePicker,
selectedTime = state.startDate.time,
onTimeSelected = interactionListener::onStartTimeChanged,
onDismiss = { interactionListener.onShowTimePicker(false) }
)

Text(
text = Res.string.frequency.asString(),
style = Theme.typography.label.medium.small,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ interface AddScheduledPaymentInteractionListener {
fun onCategorySelected(category: CategoryItemUiState)
fun onStartDateChanged(date: LocalDate)
fun onShowDatePicker(show: Boolean)
fun onShowTimePicker(show: Boolean)
fun onStartTimeChanged(time: kotlinx.datetime.LocalTime)
fun onFrequencyChanged(frequency: PaymentFrequency)
fun onCustomFrequencyDaysChanged(days: String)
fun onReminderPeriodValueChanged(value: String)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package com.spendoo.categories.presentation.screen.addScheduledPaymentBottomShee
import com.spendoo.shared.domain.entity.CategoryIcon
import com.spendoo.categories.domain.entity.scheduledPayment.PaymentFrequency
import com.spendoo.categories.domain.entity.scheduledPayment.ReminderUnit
import com.spendoo.shared.domain.utils.getToday
import com.spendoo.shared.domain.utils.getNow
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.LocalTime
import kotlinx.datetime.LocalDate
import spendoo.designsystem.generated.resources.Res
import spendoo.designsystem.generated.resources.daily
Expand Down Expand Up @@ -31,8 +33,9 @@ data class AddScheduledPaymentUiState(
val categoryIcon: CategoryIcon = CategoryIcon.DEFAULT,
val categoryName: String = "",
val isCategorySelectionSheetVisible: Boolean = false,
val startDate: LocalDate = getToday(),
val startDate: LocalDateTime = getNow(),
val showDatePicker: Boolean = false,
val showTimePicker: Boolean = false,
val frequency: PaymentFrequency = PaymentFrequency.MONTHLY,
val customFrequencyDays: String = "",
val customFrequencyDaysError: StringResource? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import com.spendoo.designsystem.navigation.BaseViewModel
import com.spendoo.designsystem.utils.UiText
import com.spendoo.shared.domain.utils.toCleanDoubleOrNull
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalTime
import kotlinx.datetime.LocalDateTime
import spendoo.designsystem.generated.resources.Res
import spendoo.designsystem.generated.resources.an_error_occurred
import spendoo.designsystem.generated.resources.custom_frequency_must_be_greater_than_zero
Expand Down Expand Up @@ -58,13 +60,21 @@ class AddScheduledPaymentViewModel(
}

override fun onStartDateChanged(date: LocalDate) {
updateState { copy(startDate = date, showDatePicker = false) }
updateState { copy(startDate = LocalDateTime(date, startDate.time), showDatePicker = false) }
}

override fun onShowDatePicker(show: Boolean) {
updateState { copy(showDatePicker = show) }
}

override fun onShowTimePicker(show: Boolean) {
updateState { copy(showTimePicker = show) }
}

override fun onStartTimeChanged(time: LocalTime) {
updateState { copy(startDate = LocalDateTime(startDate.date, time), showTimePicker = false) }
}

override fun onFrequencyChanged(frequency: PaymentFrequency) {
updateState {
val customDays =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
Expand All @@ -23,6 +25,7 @@ import com.spendoo.categories.presentation.screen.addTransactionBottomSheet.comp
import com.spendoo.categories.presentation.screen.addTransactionBottomSheet.components.IncomeEntriesSection
import com.spendoo.categories.presentation.screen.categorySelectionSheet.CategorySelectionSheet
import com.spendoo.designsystem.components.dialog.DatePicker
import com.spendoo.designsystem.components.dialog.TimePicker
import com.spendoo.designsystem.components.general.AppSegmentedControl
import com.spendoo.designsystem.components.sheet.BottomSheet
import com.spendoo.designsystem.components.sheet.BottomSheetTemplate
Expand All @@ -36,14 +39,17 @@ import com.spendoo.designsystem.utils.extentions.painter
import com.spendoo.shared.domain.entity.CategoryIcon
import io.github.vinceglb.filekit.PlatformFile
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalTime
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import spendoo.designsystem.generated.resources.Res
import spendoo.designsystem.generated.resources.add
import spendoo.designsystem.generated.resources.add_transaction
import spendoo.designsystem.generated.resources.cancel
import spendoo.designsystem.generated.resources.enter_your_date
import spendoo.designsystem.generated.resources.ic_clock_red
import spendoo.designsystem.generated.resources.ic_date
import spendoo.designsystem.generated.resources.time_label
import spendoo.designsystem.generated.resources.write_a_note_optional

@Composable
Expand Down Expand Up @@ -77,6 +83,13 @@ fun AddTransactionBottomSheet(
onDateSelected = viewModel::onDateSelected,
onDismiss = viewModel::onDatePickerDismissed
)

TimePicker(
showDialog = state.showTimePicker,
selectedTime = state.time,
onTimeSelected = viewModel::onTimeSelected,
onDismiss = viewModel::onTimePickerDismissed
)
}

@Composable
Expand Down Expand Up @@ -124,26 +137,50 @@ private fun AddTransactionBottomSheetContent(
enter = fadeIn() + expandVertically(),
exit = fadeOut() + shrinkVertically()
) {
CustomTextField(
value = state.date.format(),
onValueChange = { },
hint = stringResource(Res.string.enter_your_date),
enabled = false,
Row(
modifier = Modifier
.fillMaxWidth()
.clickableNoRipple {
focusManager.clearFocus()
interactionListener.onDatePickerRequested()
}
.padding(bottom = 8.dp)
.padding(horizontal = 16.dp),
onTrailingIconClick = {
focusManager.clearFocus()
interactionListener.onDatePickerRequested()
},
trailingIcon = Res.drawable.ic_date.painter(),
trailingIconColor = Theme.colorScheme.text.label
)
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
CustomTextField(
value = state.date.format(),
onValueChange = { },
hint = stringResource(Res.string.enter_your_date),
enabled = false,
modifier = Modifier
.weight(1f)
.clickableNoRipple {
focusManager.clearFocus()
interactionListener.onDatePickerRequested()
},
onTrailingIconClick = {
focusManager.clearFocus()
interactionListener.onDatePickerRequested()
},
trailingIcon = Res.drawable.ic_date.painter(),
trailingIconColor = Theme.colorScheme.text.label
)
CustomTextField(
value = state.time.format(),
onValueChange = { },
hint = stringResource(Res.string.time_label),
enabled = false,
modifier = Modifier
.weight(1f)
.clickableNoRipple {
focusManager.clearFocus()
interactionListener.onTimePickerRequested()
},
onTrailingIconClick = {
focusManager.clearFocus()
interactionListener.onTimePickerRequested()
},
trailingIcon = Res.drawable.ic_clock_red.painter(),
trailingIconColor = Theme.colorScheme.text.label
)
}
}

AnimatedVisibility(
Expand All @@ -168,7 +205,7 @@ private fun AddTransactionBottomSheetContent(
}

item {
Spacer(modifier = Modifier.padding(bottom = 60.dp))
Spacer(modifier = Modifier.padding(bottom = 16.dp))
}
}

Expand Down Expand Up @@ -199,6 +236,9 @@ val previewInteractionListener = object : AddTransactionInteractionListener {
override fun onSavingAmountChanged(amount: String) {}
override fun onDatePickerRequested() {}
override fun onDatePickerDismissed() {}
override fun onTimeSelected(time: LocalTime) {}
override fun onTimePickerRequested() {}
override fun onTimePickerDismissed() {}
override fun onNoteChanged(note: String) {}
override fun onDateSelected(date: LocalDate) {}
override fun submit() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ interface AddTransactionInteractionListener {
fun onDateSelected(date: LocalDate)
fun onDatePickerRequested()
fun onDatePickerDismissed()
fun onTimeSelected(time: kotlinx.datetime.LocalTime)
fun onTimePickerRequested()
fun onTimePickerDismissed()
fun onSavingChecked(checked: Boolean)

// Expense Entry Actions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package com.spendoo.categories.presentation.screen.addTransactionBottomSheet
import com.spendoo.categories.domain.entity.category.Category
import com.spendoo.shared.domain.entity.CategoryIcon
import com.spendoo.shared.domain.utils.getToday
import com.spendoo.shared.domain.utils.getNow
import com.spendoo.designsystem.utils.UiText
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalTime
import org.jetbrains.compose.resources.StringResource
import spendoo.designsystem.generated.resources.Res
import spendoo.designsystem.generated.resources.expenses
Expand Down Expand Up @@ -51,9 +53,11 @@ data class AddTransactionUiState(
val incomeAmount: Double? = null,
val incomeNote: String = "",
val date: LocalDate = getToday(),
val time: LocalTime = getNow().time,
val isSavingChecked: Boolean = false,
val savingAmount: Double? = null,
val showDatePicker: Boolean = false,
val showTimePicker: Boolean = false,
val isSubmitting: Boolean = false,
val isProcessingMedia: Boolean = false,
val showCategorySheet: Boolean = false,
Expand Down
Loading
Loading