Fix build failures from rebrand: restore pbxproj exceptions, fix Kotlin casing, move missed source dirs
- Restore 6 missing PBXFileSystemSynchronizedBuildFileExceptionSet entries and exceptions arrays on 5 root groups (lost during sed rename) - Rename extension WidgetIconView.swift to avoid stringsdata collision (original had different names: MyCribIconView vs CaseraIconView) - Rename CaseraExtension.entitlements → HoneyDueExtension.entitlements - Fix Kotlin object casing: honeyDueShareCodec → HoneyDueShareCodec, honeyDuePackageType → HoneyDuePackageType - Move missed Kotlin source dirs (jsMain, webMain, androidMain/com/casera) to com/tt/honeyDue - Rename remaining Casera widget files to HoneyDue - Rename CaseraTests.swift → HoneyDueTests.swift All 4 projects (Go API, iOS, Android, Web) now compile clean. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -35,8 +35,8 @@ import com.tt.honeyDue.network.APILayer
|
||||
import com.tt.honeyDue.sharing.ContractorSharingManager
|
||||
import com.tt.honeyDue.data.DataManager
|
||||
import com.tt.honeyDue.data.PersistenceManager
|
||||
import com.tt.honeyDue.models.honeyDuePackageType
|
||||
import com.tt.honeyDue.models.detecthoneyDuePackageType
|
||||
import com.tt.honeyDue.models.HoneyDuePackageType
|
||||
import com.tt.honeyDue.models.detectHoneyDuePackageType
|
||||
import com.tt.honeyDue.analytics.PostHogAnalytics
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -273,11 +273,11 @@ class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
|
||||
val jsonString = inputStream.bufferedReader().use { it.readText() }
|
||||
inputStream.close()
|
||||
|
||||
val packageType = detecthoneyDuePackageType(jsonString)
|
||||
val packageType = detectHoneyDuePackageType(jsonString)
|
||||
Log.d("MainActivity", "Detected package type: $packageType")
|
||||
|
||||
when (packageType) {
|
||||
honeyDuePackageType.RESIDENCE -> {
|
||||
HoneyDuePackageType.RESIDENCE -> {
|
||||
Log.d("MainActivity", "Routing to residence import")
|
||||
pendingResidenceImportUri = uri
|
||||
}
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.tt.honeyDue.ui.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tt.honeyDue.models.TaskSummary
|
||||
import com.tt.honeyDue.models.TaskColumnCategory
|
||||
|
||||
/**
|
||||
* Displays a task summary with dynamic categories from the backend.
|
||||
*
|
||||
* The backend provides icons, colors, and counts for each category,
|
||||
* allowing the UI to be built entirely from API data.
|
||||
*
|
||||
* @param taskSummary The task summary data from the API
|
||||
* @param modifier Optional modifier for the card
|
||||
* @param visibleCategories Optional list of category names to show (default: show all)
|
||||
*/
|
||||
@Composable
|
||||
fun TaskSummaryCard(
|
||||
taskSummary: TaskSummary,
|
||||
modifier: Modifier = Modifier,
|
||||
visibleCategories: List<String>? = null
|
||||
) {
|
||||
Card(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "Tasks",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
// Filter categories if visibleCategories is provided
|
||||
val categories = if (visibleCategories != null) {
|
||||
taskSummary.categories.filter { it.name in visibleCategories }
|
||||
} else {
|
||||
taskSummary.categories
|
||||
}
|
||||
|
||||
// Display each category
|
||||
categories.forEach { category ->
|
||||
TaskCategoryItem(category = category)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a single task category with icon, name, and count
|
||||
*/
|
||||
@Composable
|
||||
private fun TaskCategoryItem(
|
||||
category: TaskColumnCategory,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.background(
|
||||
color = parseHexColor(category.color).copy(alpha = 0.1f),
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
)
|
||||
.padding(12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
// Icon placeholder (using colored circle for now, can be replaced with actual icons)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(32.dp)
|
||||
.background(
|
||||
color = parseHexColor(category.color),
|
||||
shape = RoundedCornerShape(16.dp)
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = category.displayName.first().toString(),
|
||||
color = Color.White,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
|
||||
// Category name
|
||||
Text(
|
||||
text = category.displayName,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
|
||||
// Count badge
|
||||
Surface(
|
||||
color = parseHexColor(category.color),
|
||||
shape = RoundedCornerShape(12.dp)
|
||||
) {
|
||||
Text(
|
||||
text = category.count.toString(),
|
||||
color = Color.White,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
fontWeight = FontWeight.Bold,
|
||||
modifier = Modifier.padding(horizontal = 12.dp, vertical = 4.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse hex color string to Compose Color
|
||||
*/
|
||||
private fun parseHexColor(hex: String): Color {
|
||||
return try {
|
||||
Color(android.graphics.Color.parseColor(hex))
|
||||
} catch (e: Exception) {
|
||||
Color.Gray // Fallback color
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.core.content.FileProvider
|
||||
import com.tt.honeyDue.data.DataManager
|
||||
import com.tt.honeyDue.models.honeyDueShareCodec
|
||||
import com.tt.honeyDue.models.HoneyDueShareCodec
|
||||
import com.tt.honeyDue.models.Contractor
|
||||
import com.tt.honeyDue.network.APILayer
|
||||
import com.tt.honeyDue.network.ApiResult
|
||||
@@ -29,8 +29,8 @@ object ContractorSharingManager {
|
||||
fun createShareIntent(context: Context, contractor: Contractor): Intent? {
|
||||
return try {
|
||||
val currentUsername = DataManager.currentUser.value?.username ?: "Unknown"
|
||||
val jsonString = honeyDueShareCodec.encodeContractorPackage(contractor, currentUsername)
|
||||
val fileName = honeyDueShareCodec.safeShareFileName(contractor.name)
|
||||
val jsonString = HoneyDueShareCodec.encodeContractorPackage(contractor, currentUsername)
|
||||
val fileName = HoneyDueShareCodec.safeShareFileName(contractor.name)
|
||||
|
||||
// Create shared directory
|
||||
val shareDir = File(context.cacheDir, "shared")
|
||||
@@ -79,7 +79,7 @@ object ContractorSharingManager {
|
||||
val jsonString = inputStream.bufferedReader().use { it.readText() }
|
||||
inputStream.close()
|
||||
|
||||
val createRequest = honeyDueShareCodec.createContractorImportRequestOrNull(
|
||||
val createRequest = HoneyDueShareCodec.createContractorImportRequestOrNull(
|
||||
jsonContent = jsonString,
|
||||
availableSpecialties = DataManager.contractorSpecialties.value
|
||||
) ?: return@withContext ApiResult.Error("Invalid contractor share package")
|
||||
|
||||
@@ -5,7 +5,7 @@ import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.core.content.FileProvider
|
||||
import com.tt.honeyDue.data.DataManager
|
||||
import com.tt.honeyDue.models.honeyDueShareCodec
|
||||
import com.tt.honeyDue.models.HoneyDueShareCodec
|
||||
import com.tt.honeyDue.models.JoinResidenceResponse
|
||||
import com.tt.honeyDue.models.Residence
|
||||
import com.tt.honeyDue.network.APILayer
|
||||
@@ -38,8 +38,8 @@ object ResidenceSharingManager {
|
||||
when (result) {
|
||||
is ApiResult.Success -> {
|
||||
val sharedResidence = result.data
|
||||
val jsonString = honeyDueShareCodec.encodeSharedResidence(sharedResidence)
|
||||
val fileName = honeyDueShareCodec.safeShareFileName(residence.name)
|
||||
val jsonString = HoneyDueShareCodec.encodeSharedResidence(sharedResidence)
|
||||
val fileName = HoneyDueShareCodec.safeShareFileName(residence.name)
|
||||
|
||||
// Create shared directory
|
||||
val shareDir = File(context.cacheDir, "shared")
|
||||
@@ -95,7 +95,7 @@ object ResidenceSharingManager {
|
||||
val jsonString = inputStream.bufferedReader().use { it.readText() }
|
||||
inputStream.close()
|
||||
|
||||
val shareCode = honeyDueShareCodec.extractResidenceShareCodeOrNull(jsonString)
|
||||
val shareCode = HoneyDueShareCodec.extractResidenceShareCodeOrNull(jsonString)
|
||||
?: return@withContext ApiResult.Error("Invalid residence share package")
|
||||
|
||||
// Call API with share code
|
||||
|
||||
Reference in New Issue
Block a user