Add honeycomb completion heatmap and dev API environment

- Add HoneycombSummaryView component with colored hexagon grid
- Display completion summary on residence detail screen
- Add CompletionSummary model to KMP shared layer
- Add DEV/PROD environment split in ApiConfig
- Fix ResidenceResponse initializers for completionSummary parameter

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-03-12 00:05:11 -05:00
parent b8360a2e86
commit 7689027bdd
9 changed files with 280 additions and 11 deletions

View File

@@ -52,6 +52,7 @@ data class ResidenceResponse(
@SerialName("is_primary") val isPrimary: Boolean = false,
@SerialName("is_active") val isActive: Boolean = true,
@SerialName("overdue_count") val overdueCount: Int = 0,
@SerialName("completion_summary") val completionSummary: CompletionSummary? = null,
@SerialName("created_at") val createdAt: String,
@SerialName("updated_at") val updatedAt: String
) {
@@ -261,6 +262,38 @@ data class RemoveUserResponse(
val message: String
)
/**
* Completion summary for honeycomb grid display.
* Returned by the residence detail endpoint.
*/
@Serializable
data class CompletionSummary(
@SerialName("total_all_time") val totalAllTime: Int = 0,
@SerialName("total_last_12_months") val totalLast12Months: Int = 0,
val months: List<MonthlyCompletionSummary> = emptyList()
)
/**
* Monthly completion breakdown by kanban column.
*/
@Serializable
data class MonthlyCompletionSummary(
val month: String, // "2025-04" format
val completions: List<ColumnCompletionCount> = emptyList(),
val total: Int = 0,
val overflow: Int = 0
)
/**
* Count of completions from a specific kanban column with its color.
*/
@Serializable
data class ColumnCompletionCount(
val column: String,
val color: String,
val count: Int
)
// Type aliases for backwards compatibility with existing code
typealias Residence = ResidenceResponse
typealias ResidenceShareCode = ShareCodeResponse

View File

@@ -3,9 +3,10 @@ package com.tt.honeyDue.network
/**
* API Environment Configuration
*
* To switch between localhost and dev server, simply change the CURRENT_ENV value:
* To switch environments, simply change the CURRENT_ENV value:
* - Environment.LOCAL for local development
* - Environment.DEV for remote dev server
* - Environment.DEV for remote dev/staging server
* - Environment.PROD for production server
*/
object ApiConfig {
// ⚠️ CHANGE THIS TO TOGGLE ENVIRONMENT ⚠️
@@ -13,7 +14,8 @@ object ApiConfig {
enum class Environment {
LOCAL,
DEV
DEV,
PROD
}
/**
@@ -22,7 +24,8 @@ object ApiConfig {
fun getBaseUrl(): String {
return when (CURRENT_ENV) {
Environment.LOCAL -> "http://${getLocalhostAddress()}:8000/api"
Environment.DEV -> "https://api.myhoneydue.com/api"
Environment.DEV -> "https://devapi.myhoneydue.com/api"
Environment.PROD -> "https://api.myhoneydue.com/api"
}
}
@@ -32,7 +35,8 @@ object ApiConfig {
fun getMediaBaseUrl(): String {
return when (CURRENT_ENV) {
Environment.LOCAL -> "http://${getLocalhostAddress()}:8000"
Environment.DEV -> "https://api.myhoneydue.com"
Environment.DEV -> "https://devapi.myhoneydue.com"
Environment.PROD -> "https://api.myhoneydue.com"
}
}
@@ -42,7 +46,8 @@ object ApiConfig {
fun getEnvironmentName(): String {
return when (CURRENT_ENV) {
Environment.LOCAL -> "Local (${getLocalhostAddress()}:8000)"
Environment.DEV -> "Dev Server (api.myhoneydue.com)"
Environment.DEV -> "Dev Server (devapi.myhoneydue.com)"
Environment.PROD -> "Production (api.myhoneydue.com)"
}
}