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 @@ -35,7 +35,7 @@ import com.resolum.intiva.features.paymentmethodsandcategories.data.local.entiti
CategoryEntity::class,
FinancialAccountEntity::class
],
version = 4,
version = 5,
exportSchema = false
)
@TypeConverters(RoomConverters::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import com.resolum.intiva.features.finances.presentation.transactions.Transactio
import com.resolum.intiva.features.finances.presentation.transactions.TransactionDetailScreen
import com.resolum.intiva.features.finances.presentation.transactions.TransactionsScreen
import com.resolum.intiva.features.paymentmethodsandcategories.presentation.category.ManageCategoriesScreen
import com.resolum.intiva.features.paymentmethodsandcategories.presentation.financialaccount.AccountDetailScreen
import com.resolum.intiva.features.paymentmethodsandcategories.presentation.financialaccount.CreateFinancialAccountScreen
import com.resolum.intiva.features.paymentmethodsandcategories.presentation.financialaccount.FinancialAccountScreen
import com.resolum.intiva.features.paymentmethodsandcategories.presentation.financialaccount.EditFinancialAccountScreen
import com.resolum.intiva.features.savings.presentation.SavingsGoalCreateScreen
import com.resolum.intiva.features.savings.presentation.SavingsGoalDetailScreen
import com.resolum.intiva.features.savings.presentation.SavingsGoalEditScreen
Expand All @@ -36,7 +38,8 @@ import com.resolum.intiva.features.profiles.presentation.EditProfileScreen
import com.resolum.intiva.features.profiles.presentation.ConfiguracionScreen
import com.resolum.intiva.features.profiles.presentation.PrivacidadSeguridadScreen
import com.resolum.intiva.features.profiles.presentation.CentroAyudaScreen
import com.resolum.intiva.features.profiles.presentation.NotificacionesScreen
import com.resolum.intiva.features.communications.presentation.notifications.NotificationSettingsScreen
import com.resolum.intiva.features.communications.presentation.notifications.InAppNotificationsScreen
import com.resolum.intiva.features.profiles.presentation.AparienciaScreen
import com.resolum.intiva.features.household.presentation.family.FamilyScreen
import com.resolum.intiva.features.household.presentation.invite.InviteMemberScreen
Expand Down Expand Up @@ -170,6 +173,9 @@ fun MainShell(
onNavigateToAppearance = {
shellNavController.navigate(NavRoutes.APPEARANCE)
},
onNavigateToLinkedAccounts = {
shellNavController.navigate(NavRoutes.FINANCIAL_ACCOUNTS)
},
onNavigateBack = {
shellNavController.popBackStack()
}
Expand All @@ -189,7 +195,13 @@ fun MainShell(
}

composable(NavRoutes.NOTIFICATIONS) {
NotificacionesScreen(
NotificationSettingsScreen(
onNavigateBack = { shellNavController.popBackStack() }
)
}

composable(NavRoutes.IN_APP_NOTIFICATIONS) {
InAppNotificationsScreen(
onNavigateBack = { shellNavController.popBackStack() }
)
}
Expand All @@ -211,6 +223,9 @@ fun MainShell(
FinancialAccountScreen(
onAddAccountClick = {
shellNavController.navigate(NavRoutes.CREATE_FINANCIAL_ACCOUNT)
},
onAccountClick = { accountId ->
shellNavController.navigate(NavRoutes.financialAccountDetail(accountId))
}
)
}
Expand All @@ -222,6 +237,22 @@ fun MainShell(
)
}

composable(NavRoutes.FINANCIAL_ACCOUNT_DETAIL) {
AccountDetailScreen(
onBackClick = { shellNavController.popBackStack() },
onEditClick = { accountId ->
shellNavController.navigate(NavRoutes.editFinancialAccount(accountId))
}
)
}

composable(NavRoutes.EDIT_FINANCIAL_ACCOUNT) {
EditFinancialAccountScreen(
onAccountUpdated = { shellNavController.popBackStack() },
onBackClick = { shellNavController.popBackStack() }
)
}

/**
* Savings Goals feature navigation.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ object NavRoutes {
const val PRIVACY = "privacy"
const val HELP = "help"
const val NOTIFICATIONS = "notifications"
const val IN_APP_NOTIFICATIONS = "in_app_notifications"
const val APPEARANCE = "appearance"

const val NEW_INCOME = "transactions/new_income"
Expand All @@ -37,6 +38,11 @@ object NavRoutes {

const val FINANCIAL_ACCOUNTS = "financial_accounts"
const val CREATE_FINANCIAL_ACCOUNT = "create_financial_account"
const val FINANCIAL_ACCOUNT_DETAIL = "financial_account_detail/{accountId}"
const val EDIT_FINANCIAL_ACCOUNT = "edit_financial_account/{accountId}"

fun financialAccountDetail(accountId: Long) = "financial_account_detail/$accountId"
fun editFinancialAccount(accountId: Long) = "edit_financial_account/$accountId"

val BOTTOM_NAV_ROUTES = setOf(HOME, TRANSACTIONS, SAVINGS_GOALS, FAMILY, PROFILE)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.resolum.intiva.features.communications.data.remote.models

import com.google.gson.annotations.SerializedName

data class InAppNotificationDto(
@SerializedName("id") val id: Long,
@SerializedName("recipientUserId") val recipientUserId: Long,
@SerializedName("type") val type: String,
@SerializedName("source") val source: String,
@SerializedName("sourceId") val sourceId: Long,
@SerializedName("title") val title: String,
@SerializedName("message") val message: String,
@SerializedName("status") val status: String,
@SerializedName("createdAt") val createdAt: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.resolum.intiva.features.communications.data.remote.models

import com.google.gson.annotations.SerializedName

data class InAppNotificationResponseDto(
@SerializedName("message") val message: String,
@SerializedName("data") val data: List<InAppNotificationDto>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.resolum.intiva.features.communications.data.remote.services

import com.resolum.intiva.features.communications.data.remote.models.InAppNotificationResponseDto
import retrofit2.http.GET
import retrofit2.http.Query

interface InAppNotificationService {

@GET("notifications")
suspend fun getNotifications(
@Query("userId") userId: Long
): InAppNotificationResponseDto
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.resolum.intiva.features.communications.data.repositories

import com.resolum.intiva.core.data.repository.BaseRepository
import com.resolum.intiva.core.network.model.NetworkResult
import com.resolum.intiva.features.communications.data.remote.models.InAppNotificationDto
import com.resolum.intiva.features.communications.data.remote.services.InAppNotificationService
import com.resolum.intiva.features.communications.domain.models.InAppNotification
import com.resolum.intiva.features.communications.domain.models.InAppNotificationStatus
import com.resolum.intiva.features.communications.domain.repositories.InAppNotificationRepository
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import javax.inject.Inject

class InAppNotificationRepositoryImpl @Inject constructor(
private val service: InAppNotificationService
) : BaseRepository(), InAppNotificationRepository {

override suspend fun getNotifications(userId: Long): NetworkResult<List<InAppNotification>> = safeCall {
val response = service.getNotifications(userId)
response.data.map { it.toDomain() }
}

private fun InAppNotificationDto.toDomain(): InAppNotification {
return InAppNotification(
id = id,
recipientUserId = recipientUserId,
type = type,
source = source,
sourceId = sourceId,
title = title,
message = message,
status = when (status.uppercase()) {
"READ" -> InAppNotificationStatus.READ
else -> InAppNotificationStatus.UNREAD
},
createdAt = try {
LocalDateTime.parse(createdAt, DateTimeFormatter.ISO_DATE_TIME)
} catch (_: Exception) {
LocalDateTime.now()
}
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.resolum.intiva.features.communications.di

import com.resolum.intiva.features.communications.data.remote.services.InAppNotificationService
import com.resolum.intiva.features.communications.data.repositories.InAppNotificationRepositoryImpl
import com.resolum.intiva.features.communications.domain.repositories.InAppNotificationRepository
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import retrofit2.Retrofit
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object InAppNotificationModule {

@Provides
@Singleton
fun provideInAppNotificationService(retrofit: Retrofit): InAppNotificationService =
retrofit.create(InAppNotificationService::class.java)

@Provides
@Singleton
fun provideInAppNotificationRepository(
impl: InAppNotificationRepositoryImpl
): InAppNotificationRepository = impl
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.resolum.intiva.features.communications.domain.models

import java.time.LocalDateTime

data class InAppNotification(
val id: Long,
val recipientUserId: Long,
val type: String,
val source: String,
val sourceId: Long,
val title: String,
val message: String,
val status: InAppNotificationStatus,
val createdAt: LocalDateTime
)

enum class InAppNotificationStatus {
READ,
UNREAD
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.resolum.intiva.features.communications.domain.repositories

import com.resolum.intiva.core.network.model.NetworkResult
import com.resolum.intiva.features.communications.domain.models.InAppNotification

interface InAppNotificationRepository {
suspend fun getNotifications(userId: Long): NetworkResult<List<InAppNotification>>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.resolum.intiva.features.communications.domain.usecase

import com.resolum.intiva.core.network.model.NetworkResult
import com.resolum.intiva.features.communications.domain.models.InAppNotification
import com.resolum.intiva.features.communications.domain.repositories.InAppNotificationRepository
import javax.inject.Inject

class GetNotificationsUseCase @Inject constructor(
private val repository: InAppNotificationRepository
) {
suspend operator fun invoke(userId: Long): NetworkResult<List<InAppNotification>> {
return repository.getNotifications(userId)
}
}
Loading