Update API URL to myhoneydue.com, fix missing translations, and UI polish
- Update DEV API URLs from treytartt.com to api.myhoneydue.com - Add rounded corners to app icon in login, register, and onboarding screens - Add 9 missing English translations in Localizable.xcstrings - Fix property feature pills to use equal height for balanced layout - Remove duplicate honeyDue user scheme Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@@ -9,7 +9,7 @@ package com.tt.honeyDue.network
|
|||||||
*/
|
*/
|
||||||
object ApiConfig {
|
object ApiConfig {
|
||||||
// ⚠️ CHANGE THIS TO TOGGLE ENVIRONMENT ⚠️
|
// ⚠️ CHANGE THIS TO TOGGLE ENVIRONMENT ⚠️
|
||||||
val CURRENT_ENV = Environment.LOCAL
|
val CURRENT_ENV = Environment.DEV
|
||||||
|
|
||||||
enum class Environment {
|
enum class Environment {
|
||||||
LOCAL,
|
LOCAL,
|
||||||
@@ -22,7 +22,7 @@ object ApiConfig {
|
|||||||
fun getBaseUrl(): String {
|
fun getBaseUrl(): String {
|
||||||
return when (CURRENT_ENV) {
|
return when (CURRENT_ENV) {
|
||||||
Environment.LOCAL -> "http://${getLocalhostAddress()}:8000/api"
|
Environment.LOCAL -> "http://${getLocalhostAddress()}:8000/api"
|
||||||
Environment.DEV -> "https://honeyDue.treytartt.com/api"
|
Environment.DEV -> "https://api.myhoneydue.com/api"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ object ApiConfig {
|
|||||||
fun getMediaBaseUrl(): String {
|
fun getMediaBaseUrl(): String {
|
||||||
return when (CURRENT_ENV) {
|
return when (CURRENT_ENV) {
|
||||||
Environment.LOCAL -> "http://${getLocalhostAddress()}:8000"
|
Environment.LOCAL -> "http://${getLocalhostAddress()}:8000"
|
||||||
Environment.DEV -> "https://honeyDue.treytartt.com"
|
Environment.DEV -> "https://api.myhoneydue.com"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ object ApiConfig {
|
|||||||
fun getEnvironmentName(): String {
|
fun getEnvironmentName(): String {
|
||||||
return when (CURRENT_ENV) {
|
return when (CURRENT_ENV) {
|
||||||
Environment.LOCAL -> "Local (${getLocalhostAddress()}:8000)"
|
Environment.LOCAL -> "Local (${getLocalhostAddress()}:8000)"
|
||||||
Environment.DEV -> "Dev Server (honeyDue.treytartt.com)"
|
Environment.DEV -> "Dev Server (api.myhoneydue.com)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "icon.png",
|
"filename" : "HoneyDue-01-Standard@2x.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"platform" : "ios",
|
"platform" : "ios",
|
||||||
"size" : "1024x1024"
|
"size" : "1024x1024"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "icon.pdf",
|
"filename" : "HoneyDue-01-Standard@2x.png",
|
||||||
"idiom" : "universal"
|
"idiom" : "universal"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
BIN
iosApp/iosApp/Assets.xcassets/icon.imageset/HoneyDue-01-Standard@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
iosApp/iosApp/Assets.xcassets/icon.imageset/icon.pdf
vendored
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "house_outline.pdf",
|
"filename" : "outline.pdf",
|
||||||
"idiom" : "universal"
|
"idiom" : "universal"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
BIN
iosApp/iosApp/Assets.xcassets/outline.imageset/outline.pdf
vendored
Normal file
@@ -1,17 +1,17 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "house_outline 2.png",
|
"filename" : "outline_1x.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "house_outline 1.png",
|
"filename" : "outline_2x.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "house_outline.png",
|
"filename" : "outline_3x.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"scale" : "3x"
|
"scale" : "3x"
|
||||||
}
|
}
|
||||||
BIN
iosApp/iosApp/Assets.xcassets/tab_view.imageset/outline_1x.png
vendored
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
iosApp/iosApp/Assets.xcassets/tab_view.imageset/outline_2x.png
vendored
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
iosApp/iosApp/Assets.xcassets/tab_view.imageset/outline_3x.png
vendored
Normal file
|
After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
@@ -469,7 +469,7 @@ struct ContractorDetailView: View {
|
|||||||
if let residenceId = residenceId {
|
if let residenceId = residenceId {
|
||||||
DetailSection(title: L10n.Contractors.associatedPropertySection) {
|
DetailSection(title: L10n.Contractors.associatedPropertySection) {
|
||||||
HStack(spacing: AppSpacing.sm) {
|
HStack(spacing: AppSpacing.sm) {
|
||||||
Image("house_outline")
|
Image("outline")
|
||||||
.renderingMode(.template)
|
.renderingMode(.template)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ struct ContractorFormSheet: View {
|
|||||||
Section {
|
Section {
|
||||||
Button(action: { showingResidencePicker = true }) {
|
Button(action: { showingResidencePicker = true }) {
|
||||||
HStack {
|
HStack {
|
||||||
Image("house_outline")
|
Image("outline")
|
||||||
.renderingMode(.template)
|
.renderingMode(.template)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ struct FloatingLeaf: View {
|
|||||||
|
|
||||||
// Organic Stat Pills
|
// Organic Stat Pills
|
||||||
HStack(spacing: 12) {
|
HStack(spacing: 12) {
|
||||||
OrganicStatPill(icon: "house_outline", value: "3", label: "Properties", isSystemIcon: false)
|
OrganicStatPill(icon: "outline", value: "3", label: "Properties", isSystemIcon: false)
|
||||||
OrganicStatPill(icon: "checklist", value: "12", label: "Tasks", color: .orange)
|
OrganicStatPill(icon: "checklist", value: "12", label: "Tasks", color: .orange)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ struct LoginView: View {
|
|||||||
.resizable()
|
.resizable()
|
||||||
.scaledToFit()
|
.scaledToFit()
|
||||||
.frame(width: 80, height: 80)
|
.frame(width: 80, height: 80)
|
||||||
|
.clipShape(RoundedRectangle(cornerRadius: 18, style: .continuous))
|
||||||
}
|
}
|
||||||
|
|
||||||
VStack(spacing: 8) {
|
VStack(spacing: 8) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ struct MainTabView: View {
|
|||||||
}
|
}
|
||||||
.id(refreshID)
|
.id(refreshID)
|
||||||
.tabItem {
|
.tabItem {
|
||||||
Label("Residences", image: "tab_view_house")
|
Label("Residences", image: "tab_view")
|
||||||
}
|
}
|
||||||
.tag(Tab.residences)
|
.tag(Tab.residences)
|
||||||
.accessibilityIdentifier(AccessibilityIdentifiers.Navigation.residencesTab)
|
.accessibilityIdentifier(AccessibilityIdentifiers.Navigation.residencesTab)
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ struct OnboardingNameResidenceContent: View {
|
|||||||
.resizable()
|
.resizable()
|
||||||
.scaledToFit()
|
.scaledToFit()
|
||||||
.frame(width: 100, height: 100)
|
.frame(width: 100, height: 100)
|
||||||
|
.clipShape(RoundedRectangle(cornerRadius: 22, style: .continuous))
|
||||||
.naturalShadow(.pronounced)
|
.naturalShadow(.pronounced)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +146,7 @@ struct OnboardingNameResidenceContent: View {
|
|||||||
)
|
)
|
||||||
.frame(width: 40, height: 40)
|
.frame(width: 40, height: 40)
|
||||||
|
|
||||||
Image("house_outline")
|
Image("outline")
|
||||||
.renderingMode(.template)
|
.renderingMode(.template)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ struct OnboardingWelcomeView: View {
|
|||||||
.resizable()
|
.resizable()
|
||||||
.scaledToFit()
|
.scaledToFit()
|
||||||
.frame(width: 24, height: 24)
|
.frame(width: 24, height: 24)
|
||||||
|
.clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous))
|
||||||
Text("Start Fresh")
|
Text("Start Fresh")
|
||||||
.font(.system(size: 17, weight: .semibold))
|
.font(.system(size: 17, weight: .semibold))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ struct NotificationPreferencesView: View {
|
|||||||
.foregroundColor(Color.appTextSecondary)
|
.foregroundColor(Color.appTextSecondary)
|
||||||
}
|
}
|
||||||
} icon: {
|
} icon: {
|
||||||
Image("house_outline")
|
Image("outline")
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 22, height: 22)
|
.frame(width: 22, height: 22)
|
||||||
.foregroundColor(Color.appTextOnPrimary)
|
.foregroundColor(Color.appTextOnPrimary)
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ private struct OrganicEmptyResidencesView: View {
|
|||||||
.fill(Color.appPrimary.opacity(0.1))
|
.fill(Color.appPrimary.opacity(0.1))
|
||||||
.frame(width: 100, height: 100)
|
.frame(width: 100, height: 100)
|
||||||
|
|
||||||
Image("house_outline")
|
Image("outline")
|
||||||
.renderingMode(.template)
|
.renderingMode(.template)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ struct UpgradeFeatureView: View {
|
|||||||
PromoContentView(content: promoContent)
|
PromoContentView(content: promoContent)
|
||||||
} else {
|
} else {
|
||||||
VStack(alignment: .leading, spacing: 14) {
|
VStack(alignment: .leading, spacing: 14) {
|
||||||
OrganicUpgradeFeatureRow(icon: "house_outline", text: "Unlimited properties")
|
OrganicUpgradeFeatureRow(icon: "outline", text: "Unlimited properties")
|
||||||
OrganicUpgradeFeatureRow(icon: "checkmark.circle.fill", text: "Unlimited tasks")
|
OrganicUpgradeFeatureRow(icon: "checkmark.circle.fill", text: "Unlimited tasks")
|
||||||
OrganicUpgradeFeatureRow(icon: "person.2.fill", text: "Contractor management")
|
OrganicUpgradeFeatureRow(icon: "person.2.fill", text: "Contractor management")
|
||||||
OrganicUpgradeFeatureRow(icon: "doc.fill", text: "Document & warranty storage")
|
OrganicUpgradeFeatureRow(icon: "doc.fill", text: "Document & warranty storage")
|
||||||
@@ -251,8 +251,8 @@ private struct OrganicUpgradeFeatureRow: View {
|
|||||||
Circle()
|
Circle()
|
||||||
.fill(Color.appPrimary.opacity(0.1))
|
.fill(Color.appPrimary.opacity(0.1))
|
||||||
.frame(width: 36, height: 36)
|
.frame(width: 36, height: 36)
|
||||||
if icon == "house_outline" {
|
if icon == "outline" {
|
||||||
Image("house_outline")
|
Image("outline")
|
||||||
.renderingMode(.template)
|
.renderingMode(.template)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ struct UpgradePromptView: View {
|
|||||||
PromoContentView(content: promoContent)
|
PromoContentView(content: promoContent)
|
||||||
} else {
|
} else {
|
||||||
VStack(alignment: .leading, spacing: 14) {
|
VStack(alignment: .leading, spacing: 14) {
|
||||||
OrganicFeatureRow(icon: "house_outline", text: "Unlimited properties")
|
OrganicFeatureRow(icon: "outline", text: "Unlimited properties")
|
||||||
OrganicFeatureRow(icon: "checkmark.circle.fill", text: "Unlimited tasks")
|
OrganicFeatureRow(icon: "checkmark.circle.fill", text: "Unlimited tasks")
|
||||||
OrganicFeatureRow(icon: "person.2.fill", text: "Contractor management")
|
OrganicFeatureRow(icon: "person.2.fill", text: "Contractor management")
|
||||||
OrganicFeatureRow(icon: "doc.fill", text: "Document & warranty storage")
|
OrganicFeatureRow(icon: "doc.fill", text: "Document & warranty storage")
|
||||||
@@ -374,8 +374,8 @@ private struct OrganicFeatureRow: View {
|
|||||||
Circle()
|
Circle()
|
||||||
.fill(Color.appPrimary.opacity(0.1))
|
.fill(Color.appPrimary.opacity(0.1))
|
||||||
.frame(width: 36, height: 36)
|
.frame(width: 36, height: 36)
|
||||||
if icon == "house_outline" {
|
if icon == "outline" {
|
||||||
Image("house_outline")
|
Image("outline")
|
||||||
.renderingMode(.template)
|
.renderingMode(.template)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ struct LoginHeader: View {
|
|||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
.frame(width: 80, height: 80)
|
.frame(width: 80, height: 80)
|
||||||
.foregroundColor(Color.appPrimary)
|
.clipShape(RoundedRectangle(cornerRadius: 18, style: .continuous))
|
||||||
|
|
||||||
Text("honeyDue")
|
Text("honeyDue")
|
||||||
.font(.largeTitle)
|
.font(.largeTitle)
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ struct OverviewCard: View {
|
|||||||
// Stats Grid
|
// Stats Grid
|
||||||
HStack(spacing: AppSpacing.md) {
|
HStack(spacing: AppSpacing.md) {
|
||||||
StatView(
|
StatView(
|
||||||
icon: "house_outline",
|
icon: "outline",
|
||||||
value: "\(summary.totalResidences)",
|
value: "\(summary.totalResidences)",
|
||||||
label: "Properties",
|
label: "Properties",
|
||||||
color: Color.appPrimary
|
color: Color.appPrimary
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ struct StatView: View {
|
|||||||
/// Convenience initializer that accepts a plain string for backward compatibility.
|
/// Convenience initializer that accepts a plain string for backward compatibility.
|
||||||
/// Asset names are detected automatically; everything else is treated as an SF Symbol.
|
/// Asset names are detected automatically; everything else is treated as an SF Symbol.
|
||||||
init(icon: String, value: String, label: String, color: Color = Color.appPrimary) {
|
init(icon: String, value: String, label: String, color: Color = Color.appPrimary) {
|
||||||
if icon == "house_outline" {
|
if icon == "outline" {
|
||||||
self.icon = .asset(icon)
|
self.icon = .asset(icon)
|
||||||
} else {
|
} else {
|
||||||
self.icon = .system(icon)
|
self.icon = .system(icon)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ struct EmptyResidencesView: View {
|
|||||||
.fill(Color.appPrimary.opacity(0.08))
|
.fill(Color.appPrimary.opacity(0.08))
|
||||||
.frame(width: 120, height: 120)
|
.frame(width: 120, height: 120)
|
||||||
|
|
||||||
Image("house_outline")
|
Image("outline")
|
||||||
.renderingMode(.template)
|
.renderingMode(.template)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ private struct PropertyDetailIcon: View {
|
|||||||
.frame(width: 48, height: 48)
|
.frame(width: 48, height: 48)
|
||||||
|
|
||||||
// Icon
|
// Icon
|
||||||
Image("house_outline")
|
Image("outline")
|
||||||
.resizable()
|
.resizable()
|
||||||
.scaledToFit()
|
.scaledToFit()
|
||||||
.frame(width: 22, height: 22)
|
.frame(width: 22, height: 22)
|
||||||
@@ -244,7 +244,8 @@ private struct PropertyFeaturePill: View {
|
|||||||
.font(.system(size: 11, weight: .medium))
|
.font(.system(size: 11, weight: .medium))
|
||||||
.foregroundColor(Color.appTextSecondary)
|
.foregroundColor(Color.appTextSecondary)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity)
|
.frame(minWidth: 0, maxWidth: .infinity)
|
||||||
|
.frame(height: 48)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ private struct PropertyIconView: View {
|
|||||||
.frame(width: 56, height: 56)
|
.frame(width: 56, height: 56)
|
||||||
|
|
||||||
// House icon
|
// House icon
|
||||||
Image("house_outline")
|
Image("outline")
|
||||||
.resizable()
|
.resizable()
|
||||||
.scaledToFit()
|
.scaledToFit()
|
||||||
.frame(width: 48, height: 48)
|
.frame(width: 48, height: 48)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ struct SummaryCard: View {
|
|||||||
// Main Stats Row
|
// Main Stats Row
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
OrganicStatItem(
|
OrganicStatItem(
|
||||||
icon: "house_outline",
|
icon: "outline",
|
||||||
value: "\(summary.totalResidences)",
|
value: "\(summary.totalResidences)",
|
||||||
label: "Properties",
|
label: "Properties",
|
||||||
accentColor: Color.appPrimary
|
accentColor: Color.appPrimary
|
||||||
@@ -95,8 +95,8 @@ private struct OrganicStatItem: View {
|
|||||||
.fill(accentColor.opacity(0.12))
|
.fill(accentColor.opacity(0.12))
|
||||||
.frame(width: 40, height: 40)
|
.frame(width: 40, height: 40)
|
||||||
|
|
||||||
if icon == "house_outline" {
|
if icon == "outline" {
|
||||||
Image("house_outline")
|
Image("outline")
|
||||||
.renderingMode(.template)
|
.renderingMode(.template)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ struct SummaryStatView: View {
|
|||||||
.fill(Color.appPrimary.opacity(0.1))
|
.fill(Color.appPrimary.opacity(0.1))
|
||||||
.frame(width: 44, height: 44)
|
.frame(width: 44, height: 44)
|
||||||
|
|
||||||
if icon == "house_outline" {
|
if icon == "outline" {
|
||||||
Image("house_outline")
|
Image("outline")
|
||||||
.renderingMode(.template)
|
.renderingMode(.template)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
@@ -42,7 +42,7 @@ struct SummaryStatView: View {
|
|||||||
#Preview {
|
#Preview {
|
||||||
HStack(spacing: 20) {
|
HStack(spacing: 20) {
|
||||||
SummaryStatView(
|
SummaryStatView(
|
||||||
icon: "house_outline",
|
icon: "outline",
|
||||||
value: "3",
|
value: "3",
|
||||||
label: "Properties"
|
label: "Properties"
|
||||||
)
|
)
|
||||||
|
|||||||