diff --git a/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json index c68da6c..3cad146 100644 --- a/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "icon.png", + "filename" : "logo_primary.png", "idiom" : "universal", "platform" : "ios", "size" : "1024x1024" diff --git a/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/icon.png b/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/icon.png deleted file mode 100644 index b1e6f70..0000000 Binary files a/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/icon.png and /dev/null differ diff --git a/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/logo_primary.png b/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/logo_primary.png new file mode 100644 index 0000000..8c0231e Binary files /dev/null and b/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/logo_primary.png differ diff --git a/iosApp/iosApp/Assets.xcassets/Colors/Contents.json b/iosApp/iosApp/Assets.xcassets/Colors/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/Colors/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosApp/iosApp/Assets.xcassets/Colors/Semantic/Accent.colorset/Contents.json b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/Accent.colorset/Contents.json new file mode 100644 index 0000000..45336ad --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/Accent.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.031", + "green" : "0.784", + "red" : "0.941" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.031", + "green" : "0.784", + "red" : "0.941" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosApp/iosApp/Assets.xcassets/Colors/Semantic/BackgroundPrimary.colorset/Contents.json b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/BackgroundPrimary.colorset/Contents.json new file mode 100644 index 0000000..fdf29e9 --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/BackgroundPrimary.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.816", + "green" : "0.945", + "red" : "1.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.161", + "green" : "0.098", + "red" : "0.039" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosApp/iosApp/Assets.xcassets/Colors/Semantic/BackgroundSecondary.colorset/Contents.json b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/BackgroundSecondary.colorset/Contents.json new file mode 100644 index 0000000..b651e01 --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/BackgroundSecondary.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "1.000", + "red" : "1.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.247", + "green" : "0.184", + "red" : "0.102" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosApp/iosApp/Assets.xcassets/Colors/Semantic/Contents.json b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosApp/iosApp/Assets.xcassets/Colors/Semantic/Error.colorset/Contents.json b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/Error.colorset/Contents.json new file mode 100644 index 0000000..e3e5c20 --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/Error.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.102", + "green" : "0.110", + "red" : "0.867" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.267", + "green" : "0.267", + "red" : "1.000" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosApp/iosApp/Assets.xcassets/Colors/Semantic/Primary.colorset/Contents.json b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/Primary.colorset/Contents.json new file mode 100644 index 0000000..4a4b75b --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/Primary.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.765", + "green" : "0.627", + "red" : "0.027" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.765", + "green" : "0.627", + "red" : "0.027" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosApp/iosApp/Assets.xcassets/Colors/Semantic/Secondary.colorset/Contents.json b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/Secondary.colorset/Contents.json new file mode 100644 index 0000000..9d669ec --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/Secondary.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.533", + "green" : "0.404", + "red" : "0.031" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.745", + "green" : "0.624", + "red" : "0.039" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosApp/iosApp/Assets.xcassets/Colors/Semantic/TextOnPrimary.colorset/Contents.json b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/TextOnPrimary.colorset/Contents.json new file mode 100644 index 0000000..22c4bb0 --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/TextOnPrimary.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "1.000", + "red" : "1.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "1.000", + "red" : "1.000" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosApp/iosApp/Assets.xcassets/Colors/Semantic/TextPrimary.colorset/Contents.json b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/TextPrimary.colorset/Contents.json new file mode 100644 index 0000000..8988063 --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/TextPrimary.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.533", + "green" : "0.404", + "red" : "0.031" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.816", + "green" : "0.945", + "red" : "1.000" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosApp/iosApp/Assets.xcassets/Colors/Semantic/TextSecondary.colorset/Contents.json b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/TextSecondary.colorset/Contents.json new file mode 100644 index 0000000..4c2605b --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/Colors/Semantic/TextSecondary.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.600", + "blue" : "0.533", + "green" : "0.404", + "red" : "0.031" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.700", + "blue" : "0.816", + "green" : "0.945", + "red" : "1.000" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosApp/iosApp/Components/TaskSummaryCard.swift b/iosApp/iosApp/Components/TaskSummaryCard.swift index 1e53cf3..720d959 100644 --- a/iosApp/iosApp/Components/TaskSummaryCard.swift +++ b/iosApp/iosApp/Components/TaskSummaryCard.swift @@ -26,13 +26,14 @@ struct TaskSummaryCard: View { Text("Tasks") .font(.headline) .fontWeight(.bold) + .foregroundColor(Color.appTextPrimary) ForEach(filteredCategories, id: \.name) { category in TaskCategoryRow(category: category) } } .padding(16) - .background(Color(.systemBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(12) .shadow(color: Color.black.opacity(0.1), radius: 4, x: 0, y: 2) } @@ -55,14 +56,14 @@ struct TaskCategoryRow: View { .frame(width: 32, height: 32) Image(systemName: category.icons.ios) - .foregroundColor(.white) + .foregroundColor(Color.appTextOnPrimary) .font(.system(size: 14, weight: .semibold)) } // Category name Text(category.displayName) .font(.body) - .foregroundColor(.primary) + .foregroundColor(Color.appTextPrimary) Spacer() @@ -70,7 +71,7 @@ struct TaskCategoryRow: View { Text("\(category.count)") .font(.subheadline) .fontWeight(.bold) - .foregroundColor(.white) + .foregroundColor(Color.appTextOnPrimary) .padding(.horizontal, 12) .padding(.vertical, 4) .background(categoryColor) diff --git a/iosApp/iosApp/Contractor/ContractorCard.swift b/iosApp/iosApp/Contractor/ContractorCard.swift index c9e3db5..0f13ac2 100644 --- a/iosApp/iosApp/Contractor/ContractorCard.swift +++ b/iosApp/iosApp/Contractor/ContractorCard.swift @@ -10,12 +10,12 @@ struct ContractorCard: View { // Avatar ZStack { Circle() - .fill(.blue.opacity(0.1)) + .fill(Color.appPrimary.opacity(0.1)) .frame(width: 56, height: 56) Image(systemName: "person.fill") .font(.title2) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) } // Content @@ -24,13 +24,13 @@ struct ContractorCard: View { HStack(spacing: AppSpacing.xxs) { Text(contractor.name) .font(.title3.weight(.semibold)) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) .lineLimit(1) if contractor.isFavorite { Image(systemName: "star.fill") .font(.caption) - .foregroundColor(.orange) + .foregroundColor(Color.appAccent) } } @@ -38,7 +38,7 @@ struct ContractorCard: View { if let company = contractor.company { Text(company) .font(.body) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) .lineLimit(1) } @@ -48,21 +48,21 @@ struct ContractorCard: View { if let specialty = contractor.specialty { Label(specialty, systemImage: "wrench.and.screwdriver") .font(.caption.weight(.medium)) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } // Rating if let rating = contractor.averageRating, rating.doubleValue > 0 { Label(String(format: "%.1f", rating.doubleValue), systemImage: "star.fill") .font(.caption.weight(.medium)) - .foregroundColor(.orange) + .foregroundColor(Color.appAccent) } // Task count if contractor.taskCount > 0 { Label("\(contractor.taskCount) tasks", systemImage: "checkmark.circle") .font(.caption.weight(.medium)) - .foregroundColor(.green) + .foregroundColor(Color.appPrimary) } } } @@ -73,17 +73,17 @@ struct ContractorCard: View { Button(action: onToggleFavorite) { Image(systemName: contractor.isFavorite ? "star.fill" : "star") .font(.title3) - .foregroundColor(contractor.isFavorite ? .orange : Color(.tertiaryLabel)) + .foregroundColor(contractor.isFavorite ? Color.appAccent : Color.appTextSecondary.opacity(0.7)) } .buttonStyle(PlainButtonStyle()) // Chevron Image(systemName: "chevron.right") .font(.caption) - .foregroundColor(Color(.tertiaryLabel)) + .foregroundColor(Color.appTextSecondary.opacity(0.7)) } .padding(AppSpacing.md) - .background(Color(.secondarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.lg) .shadow(color: AppShadow.sm.color, radius: AppShadow.sm.radius, x: AppShadow.sm.x, y: AppShadow.sm.y) } diff --git a/iosApp/iosApp/Contractor/ContractorDetailView.swift b/iosApp/iosApp/Contractor/ContractorDetailView.swift index ccd1b7b..10b2fe7 100644 --- a/iosApp/iosApp/Contractor/ContractorDetailView.swift +++ b/iosApp/iosApp/Contractor/ContractorDetailView.swift @@ -12,7 +12,7 @@ struct ContractorDetailView: View { var body: some View { ZStack { - Color(.systemGroupedBackground).ignoresSafeArea() + Color.appBackgroundPrimary.ignoresSafeArea() if viewModel.isLoading { ProgressView() @@ -29,24 +29,24 @@ struct ContractorDetailView: View { // Avatar ZStack { Circle() - .fill(.blue.opacity(0.1)) + .fill(Color.appPrimary.opacity(0.1)) .frame(width: 80, height: 80) Image(systemName: "person.fill") .font(.system(size: 40)) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) } // Name Text(contractor.name) .font(.title3.weight(.semibold)) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) // Company if let company = contractor.company { Text(company) .font(.title3.weight(.semibold)) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } // Specialty Badge @@ -59,8 +59,8 @@ struct ContractorDetailView: View { } .padding(.horizontal, AppSpacing.sm) .padding(.vertical, AppSpacing.xxs) - .background(.blue.opacity(0.1)) - .foregroundColor(.blue) + .background(Color.appPrimary.opacity(0.1)) + .foregroundColor(Color.appPrimary) .cornerRadius(AppRadius.full) } @@ -69,43 +69,43 @@ struct ContractorDetailView: View { HStack(spacing: AppSpacing.xxs) { ForEach(0..<5) { index in Image(systemName: index < Int(rating.doubleValue) ? "star.fill" : "star") - .foregroundColor(.orange) + .foregroundColor(Color.appAccent) .font(.caption) } Text(String(format: "%.1f", rating.doubleValue)) .font(.title3.weight(.semibold)) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) } if contractor.taskCount > 0 { Text("\(contractor.taskCount) completed tasks") .font(.callout) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } } } .padding(AppSpacing.lg) .frame(maxWidth: .infinity) - .background(Color(.secondarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.lg) .shadow(color: AppShadow.sm.color, radius: AppShadow.sm.radius, x: AppShadow.sm.x, y: AppShadow.sm.y) // Contact Information DetailSection(title: "Contact Information") { if let phone = contractor.phone { - DetailRow(icon: "phone", label: "Phone", value: phone, iconColor: .blue) + DetailRow(icon: "phone", label: "Phone", value: phone, iconColor: Color.appPrimary) } if let email = contractor.email { - DetailRow(icon: "envelope", label: "Email", value: email, iconColor: .purple) + DetailRow(icon: "envelope", label: "Email", value: email, iconColor: Color.appPrimary) } if let secondaryPhone = contractor.secondaryPhone { - DetailRow(icon: "phone", label: "Secondary Phone", value: secondaryPhone, iconColor: .green) + DetailRow(icon: "phone", label: "Secondary Phone", value: secondaryPhone, iconColor: Color.appAccent) } if let website = contractor.website { - DetailRow(icon: "globe", label: "Website", value: website, iconColor: .orange) + DetailRow(icon: "globe", label: "Website", value: website, iconColor: Color.appAccent) } } @@ -113,7 +113,7 @@ struct ContractorDetailView: View { if contractor.licenseNumber != nil { DetailSection(title: "Business Details") { if let licenseNumber = contractor.licenseNumber { - DetailRow(icon: "doc.badge", label: "License Number", value: licenseNumber, iconColor: .blue) + DetailRow(icon: "doc.badge", label: "License Number", value: licenseNumber, iconColor: Color.appPrimary) } } } @@ -132,7 +132,7 @@ struct ContractorDetailView: View { icon: "mappin.circle", label: "Location", value: addressComponents.joined(separator: "\n"), - iconColor: .red + iconColor: Color.appError ) } } @@ -143,7 +143,7 @@ struct ContractorDetailView: View { DetailSection(title: "Notes") { Text(notes) .font(.body) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) .frame(maxWidth: .infinity, alignment: .leading) .padding(AppSpacing.md) } @@ -153,11 +153,11 @@ struct ContractorDetailView: View { DetailSection(title: "Task History") { HStack { Image(systemName: "checkmark.circle") - .foregroundColor(.green) + .foregroundColor(Color.appAccent) Spacer() Text("\(contractor.taskCount) completed tasks") .font(.body) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } .padding(AppSpacing.md) } @@ -191,7 +191,7 @@ struct ContractorDetailView: View { } } label: { Image(systemName: "ellipsis.circle") - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) } } } @@ -243,13 +243,13 @@ struct DetailSection: View { VStack(alignment: .leading, spacing: AppSpacing.sm) { Text(title) .font(.headline) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) .padding(.horizontal, AppSpacing.md) VStack(spacing: 0) { content() } - .background(Color(.secondarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.lg) .shadow(color: AppShadow.sm.color, radius: AppShadow.sm.radius, x: AppShadow.sm.x, y: AppShadow.sm.y) } @@ -272,11 +272,11 @@ struct DetailRow: View { VStack(alignment: .leading, spacing: AppSpacing.xxs) { Text(label) .font(.caption.weight(.medium)) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) Text(value) .font(.body) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) } Spacer() diff --git a/iosApp/iosApp/Contractor/ContractorFormSheet.swift b/iosApp/iosApp/Contractor/ContractorFormSheet.swift index 9577424..a1c21de 100644 --- a/iosApp/iosApp/Contractor/ContractorFormSheet.swift +++ b/iosApp/iosApp/Contractor/ContractorFormSheet.swift @@ -52,7 +52,7 @@ struct ContractorFormSheet: View { Section { HStack { Image(systemName: "person") - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) .frame(width: 24) TextField("Name", text: $name) .focused($focusedField, equals: .name) @@ -60,7 +60,7 @@ struct ContractorFormSheet: View { HStack { Image(systemName: "building.2") - .foregroundColor(.purple) + .foregroundColor(Color.appPrimary) .frame(width: 24) TextField("Company", text: $company) .focused($focusedField, equals: .company) @@ -70,14 +70,15 @@ struct ContractorFormSheet: View { } footer: { Text("Required: Name") .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } + .listRowBackground(Color.appBackgroundSecondary) // Contact Information Section { HStack { Image(systemName: "phone.fill") - .foregroundColor(.green) + .foregroundColor(Color.appPrimary) .frame(width: 24) TextField("Phone", text: $phone) .keyboardType(.phonePad) @@ -86,7 +87,7 @@ struct ContractorFormSheet: View { HStack { Image(systemName: "envelope.fill") - .foregroundColor(.orange) + .foregroundColor(Color.appAccent) .frame(width: 24) TextField("Email", text: $email) .keyboardType(.emailAddress) @@ -97,7 +98,7 @@ struct ContractorFormSheet: View { HStack { Image(systemName: "phone.badge.plus") - .foregroundColor(.green) + .foregroundColor(Color.appPrimary) .frame(width: 24) TextField("Secondary Phone", text: $secondaryPhone) .keyboardType(.phonePad) @@ -106,28 +107,29 @@ struct ContractorFormSheet: View { } header: { Text("Contact Information") } footer: { - + } + .listRowBackground(Color.appBackgroundSecondary) // Business Details Section { Button(action: { showingSpecialtyPicker = true }) { HStack { Image(systemName: "wrench.and.screwdriver") - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) .frame(width: 24) Text(specialty.isEmpty ? "Specialty" : specialty) - .foregroundColor(specialty.isEmpty ? Color(.placeholderText) : Color(.label)) + .foregroundColor(specialty.isEmpty ? Color.appTextSecondary.opacity(0.5) : Color.appTextPrimary) Spacer() Image(systemName: "chevron.down") .font(.caption) - .foregroundColor(Color(.tertiaryLabel)) + .foregroundColor(Color.appTextSecondary.opacity(0.7)) } } HStack { Image(systemName: "doc.badge") - .foregroundColor(.purple) + .foregroundColor(Color.appPrimary) .frame(width: 24) TextField("License Number", text: $licenseNumber) .focused($focusedField, equals: .licenseNumber) @@ -135,7 +137,7 @@ struct ContractorFormSheet: View { HStack { Image(systemName: "globe") - .foregroundColor(.blue) + .foregroundColor(Color.appAccent) .frame(width: 24) TextField("Website", text: $website) .keyboardType(.URL) @@ -146,12 +148,13 @@ struct ContractorFormSheet: View { } header: { Text("Business Details") } + .listRowBackground(Color.appBackgroundSecondary) // Address Section { HStack { Image(systemName: "location.fill") - .foregroundColor(.red) + .foregroundColor(Color.appError) .frame(width: 24) TextField("Street Address", text: $address) .focused($focusedField, equals: .address) @@ -159,7 +162,7 @@ struct ContractorFormSheet: View { HStack { Image(systemName: "building.2.crop.circle") - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) .frame(width: 24) TextField("City", text: $city) .focused($focusedField, equals: .city) @@ -168,7 +171,7 @@ struct ContractorFormSheet: View { HStack(spacing: AppSpacing.sm) { HStack { Image(systemName: "map") - .foregroundColor(.green) + .foregroundColor(Color.appAccent) .frame(width: 24) TextField("State", text: $state) .focused($focusedField, equals: .state) @@ -185,12 +188,13 @@ struct ContractorFormSheet: View { } header: { Text("Address") } + .listRowBackground(Color.appBackgroundSecondary) // Notes Section { HStack(alignment: .top) { Image(systemName: "note.text") - .foregroundColor(.orange) + .foregroundColor(Color.appAccent) .frame(width: 24) .padding(.top, 8) @@ -204,29 +208,35 @@ struct ContractorFormSheet: View { Text("Private notes about this contractor") .font(.caption) } + .listRowBackground(Color.appBackgroundSecondary) // Favorite Section { Toggle(isOn: $isFavorite) { Label("Mark as Favorite", systemImage: "star.fill") - .foregroundColor(isFavorite ? .orange : Color(.label)) + .foregroundColor(isFavorite ? Color.appAccent : Color.appTextPrimary) } - .tint(.orange) + .tint(Color.appAccent) } + .listRowBackground(Color.appBackgroundSecondary) // Error Message if let error = viewModel.errorMessage { Section { HStack { Image(systemName: "exclamationmark.triangle.fill") - .foregroundColor(.red) + .foregroundColor(Color.appError) Text(error) .font(.callout) - .foregroundColor(.red) + .foregroundColor(Color.appError) } } + .listRowBackground(Color.appBackgroundSecondary) } } + .listStyle(.plain) + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationTitle(contractor == nil ? "Add Contractor" : "Edit Contractor") .navigationBarTitleDisplayMode(.inline) .toolbar { @@ -258,16 +268,18 @@ struct ContractorFormSheet: View { }) { HStack { Text(spec) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) Spacer() if specialty == spec { Image(systemName: "checkmark") - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) } } } } } + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationTitle("Select Specialty") .navigationBarTitleDisplayMode(.inline) .toolbar { diff --git a/iosApp/iosApp/Contractor/ContractorsListView.swift b/iosApp/iosApp/Contractor/ContractorsListView.swift index aa2bf95..a9827f7 100644 --- a/iosApp/iosApp/Contractor/ContractorsListView.swift +++ b/iosApp/iosApp/Contractor/ContractorsListView.swift @@ -26,7 +26,7 @@ struct ContractorsListView: View { var body: some View { ZStack { - Color(.systemGroupedBackground).ignoresSafeArea() + Color.appBackgroundPrimary.ignoresSafeArea() VStack(spacing: 0) { // Search Bar @@ -115,7 +115,7 @@ struct ContractorsListView: View { loadContractors() }) { Image(systemName: showFavoritesOnly ? "star.fill" : "star") - .foregroundColor(showFavoritesOnly ? .orange : Color(.secondaryLabel)) + .foregroundColor(showFavoritesOnly ? Color.appAccent : Color.appTextSecondary) } // Specialty Filter @@ -139,14 +139,14 @@ struct ContractorsListView: View { } } label: { Image(systemName: "line.3.horizontal.decrease.circle") - .foregroundColor(selectedSpecialty != nil ? .blue : Color(.secondaryLabel)) + .foregroundColor(selectedSpecialty != nil ? Color.appPrimary : Color.appTextSecondary) } // Add Button Button(action: { showingAddSheet = true }) { Image(systemName: "plus.circle.fill") .font(.title2) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) } .accessibilityIdentifier(AccessibilityIdentifiers.Contractor.addButton) } @@ -206,7 +206,7 @@ struct SearchBar: View { var body: some View { HStack(spacing: AppSpacing.sm) { Image(systemName: "magnifyingglass") - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) TextField(placeholder, text: $text) .font(.body) @@ -214,12 +214,12 @@ struct SearchBar: View { if !text.isEmpty { Button(action: { text = "" }) { Image(systemName: "xmark.circle.fill") - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } } } .padding(AppSpacing.sm) - .background(Color(.secondarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.md) .shadow(color: AppShadow.sm.color, radius: AppShadow.sm.radius, x: AppShadow.sm.x, y: AppShadow.sm.y) } @@ -247,8 +247,8 @@ struct FilterChip: View { } .padding(.horizontal, AppSpacing.sm) .padding(.vertical, AppSpacing.xxs) - .background(.blue.opacity(0.1)) - .foregroundColor(.blue) + .background(Color.appPrimary.opacity(0.1)) + .foregroundColor(Color.appPrimary) .cornerRadius(AppRadius.full) } } @@ -261,16 +261,16 @@ struct EmptyContractorsView: View { VStack(spacing: AppSpacing.md) { Image(systemName: "person.badge.plus") .font(.system(size: 64)) - .foregroundColor(Color(.tertiaryLabel)) + .foregroundColor(Color.appTextSecondary.opacity(0.7)) Text(hasFilters ? "No contractors found" : "No contractors yet") .font(.title3.weight(.semibold)) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) if !hasFilters { Text("Add your first contractor to get started") .font(.callout) - .foregroundColor(Color(.tertiaryLabel)) + .foregroundColor(Color.appTextSecondary.opacity(0.7)) } } .padding(AppSpacing.xl) diff --git a/iosApp/iosApp/Design/DesignSystem.swift b/iosApp/iosApp/Design/DesignSystem.swift index f60ea54..2ee9ea6 100644 --- a/iosApp/iosApp/Design/DesignSystem.swift +++ b/iosApp/iosApp/Design/DesignSystem.swift @@ -3,6 +3,49 @@ import SwiftUI // MARK: - Design System // Modern, sleek design system for MyCrib with Light and Dark mode support +// MARK: - Colors + +extension Color { + // MARK: - Semantic Colors (Use These in UI) + static let appPrimary = Color("Primary") + static let appSecondary = Color("Secondary") + static let appAccent = Color("Accent") + static let appBackgroundPrimary = Color("BackgroundPrimary") + static let appBackgroundSecondary = Color("BackgroundSecondary") + static let appError = Color("Error") + static let appTextPrimary = Color("TextPrimary") + static let appTextSecondary = Color("TextSecondary") + static let appTextOnPrimary = Color("TextOnPrimary") + + // MARK: - Hex Support + init?(hex: String) { + let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) + var int: UInt64 = 0 + Scanner(string: hex).scanHexInt64(&int) + let a, r, g, b: UInt64 + switch hex.count { + case 3: // RGB (12-bit) + (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) + case 6: // RGB (24-bit) + (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) + case 8: // ARGB (32-bit) + (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) + default: + return nil + } + + self.init( + .sRGB, + red: Double(r) / 255, + green: Double(g) / 255, + blue: Double(b) / 255, + opacity: Double(a) / 255 + ) + } +} + +// MARK: - Spacing + struct AppSpacing { static let xxs: CGFloat = 4 static let xs: CGFloat = 8 @@ -53,7 +96,7 @@ struct CardStyle: ViewModifier { func body(content: Content) -> some View { content - .background(Color(.secondarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.lg) .shadow(color: shadow.color, radius: shadow.radius, x: shadow.x, y: shadow.y) } @@ -65,11 +108,11 @@ struct PrimaryButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { configuration.label .font(.headline) - .foregroundColor(.white) + .foregroundColor(.appTextOnPrimary) .frame(maxWidth: .infinity) .frame(height: 56) .background( - configuration.isPressed ? .blue : .blue + configuration.isPressed ? Color.appPrimary.opacity(0.8) : Color.appPrimary ) .cornerRadius(AppRadius.md) .scaleEffect(configuration.isPressed ? 0.98 : 1.0) @@ -81,10 +124,10 @@ struct SecondaryButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { configuration.label .font(.headline) - .foregroundColor(.blue) + .foregroundColor(.appPrimary) .frame(maxWidth: .infinity) .frame(height: 56) - .background(Color(.tertiarySystemGroupedBackground)) + .background(Color.appPrimary.opacity(0.1)) .cornerRadius(AppRadius.md) .scaleEffect(configuration.isPressed ? 0.98 : 1.0) .animation(.easeInOut(duration: 0.1), value: configuration.isPressed) @@ -95,11 +138,11 @@ struct TextFieldStyle: ViewModifier { func body(content: Content) -> some View { content .padding(AppSpacing.md) - .background(Color(.tertiarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.md) .overlay( RoundedRectangle(cornerRadius: AppRadius.md) - .stroke(Color(.opaqueSeparator), lineWidth: 1) + .stroke(Color.appTextSecondary.opacity(0.3), lineWidth: 1) ) } } @@ -116,31 +159,3 @@ extension View { } } -// MARK: - Color Extension for Hex Support - -extension Color { - init?(hex: String) { - let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) - var int: UInt64 = 0 - Scanner(string: hex).scanHexInt64(&int) - let a, r, g, b: UInt64 - switch hex.count { - case 3: // RGB (12-bit) - (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) - case 6: // RGB (24-bit) - (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) - case 8: // ARGB (32-bit) - (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) - default: - return nil - } - - self.init( - .sRGB, - red: Double(r) / 255, - green: Double(g) / 255, - blue: Double(b) / 255, - opacity: Double(a) / 255 - ) - } -} diff --git a/iosApp/iosApp/Documents/Components/DocumentCard.swift b/iosApp/iosApp/Documents/Components/DocumentCard.swift index 782673b..be96b9a 100644 --- a/iosApp/iosApp/Documents/Components/DocumentCard.swift +++ b/iosApp/iosApp/Documents/Components/DocumentCard.swift @@ -6,11 +6,11 @@ struct DocumentCard: View { var typeColor: Color { switch document.documentType { - case "warranty": return .blue - case "manual": return .purple - case "receipt": return .green - case "inspection": return .orange - default: return .gray + case "warranty": return Color.appPrimary + case "manual": return Color.appSecondary + case "receipt": return Color.appAccent + case "inspection": return Color.appAccent + default: return Color.appTextSecondary } } @@ -41,13 +41,13 @@ struct DocumentCard: View { Text(document.title) .font(.title3.weight(.semibold)) .fontWeight(.bold) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) .lineLimit(1) if let description = document.description_, !description.isEmpty { Text(description) .font(.callout) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) .lineLimit(2) } @@ -63,7 +63,7 @@ struct DocumentCard: View { if let fileSize = document.fileSize { Text(formatFileSize(Int(fileSize))) .font(.caption.weight(.medium)) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } } } @@ -71,11 +71,11 @@ struct DocumentCard: View { Spacer() Image(systemName: "chevron.right") - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) .font(.system(size: 14)) } .padding(AppSpacing.md) - .background(Color(.secondarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.md) .shadow(color: Color.black.opacity(0.05), radius: 2, x: 0, y: 1) } diff --git a/iosApp/iosApp/Documents/Components/EmptyStateView.swift b/iosApp/iosApp/Documents/Components/EmptyStateView.swift index eed9b74..c7c4edb 100644 --- a/iosApp/iosApp/Documents/Components/EmptyStateView.swift +++ b/iosApp/iosApp/Documents/Components/EmptyStateView.swift @@ -9,15 +9,15 @@ struct EmptyStateView: View { VStack(spacing: AppSpacing.md) { Image(systemName: icon) .font(.system(size: 64)) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) Text(title) .font(.title3.weight(.semibold)) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) Text(message) .font(.body) - .foregroundColor(Color(.tertiaryLabel)) + .foregroundColor(Color.appTextSecondary.opacity(0.7)) .multilineTextAlignment(.center) } .padding(AppSpacing.lg) diff --git a/iosApp/iosApp/Documents/Components/WarrantyCard.swift b/iosApp/iosApp/Documents/Components/WarrantyCard.swift index a923e73..851ead7 100644 --- a/iosApp/iosApp/Documents/Components/WarrantyCard.swift +++ b/iosApp/iosApp/Documents/Components/WarrantyCard.swift @@ -9,11 +9,11 @@ struct WarrantyCard: View { } var statusColor: Color { - if !document.isActive { return .gray } - if daysUntilExpiration < 0 { return .red } - if daysUntilExpiration < 30 { return .orange } - if daysUntilExpiration < 90 { return .yellow } - return .green + if !document.isActive { return Color.appTextSecondary } + if daysUntilExpiration < 0 { return Color.appError } + if daysUntilExpiration < 30 { return Color.appAccent } + if daysUntilExpiration < 90 { return Color.appAccent.opacity(0.7) } + return Color.appPrimary } var statusText: String { @@ -31,11 +31,11 @@ struct WarrantyCard: View { Text(document.title) .font(.title3.weight(.semibold)) .fontWeight(.bold) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) Text(document.itemName ?? "") .font(.body) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } Spacer() @@ -58,11 +58,11 @@ struct WarrantyCard: View { VStack(alignment: .leading, spacing: 2) { Text("Provider") .font(.caption.weight(.medium)) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) Text(document.provider ?? "N/A") .font(.body) .fontWeight(.medium) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) } Spacer() @@ -70,11 +70,11 @@ struct WarrantyCard: View { VStack(alignment: .trailing, spacing: 2) { Text("Expires") .font(.caption.weight(.medium)) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) Text(document.endDate ?? "N/A") .font(.body) .fontWeight(.medium) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) } } @@ -88,15 +88,15 @@ struct WarrantyCard: View { if let category = document.category { Text(getCategoryDisplayName(category)) .font(.caption.weight(.medium)) - .foregroundColor(Color(hex: "374151")) + .foregroundColor(Color.appTextPrimary) .padding(.horizontal, 8) .padding(.vertical, 4) - .background(Color(hex: "E5E7EB")) + .background(Color.appBackgroundSecondary.opacity(0.8)) .cornerRadius(4) } } .padding(AppSpacing.md) - .background(Color(.secondarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.md) .shadow(color: Color.black.opacity(0.05), radius: 2, x: 0, y: 1) } diff --git a/iosApp/iosApp/Documents/DocumentFormView.swift b/iosApp/iosApp/Documents/DocumentFormView.swift index bfab175..b464ce7 100644 --- a/iosApp/iosApp/Documents/DocumentFormView.swift +++ b/iosApp/iosApp/Documents/DocumentFormView.swift @@ -119,7 +119,7 @@ struct DocumentFormView: View { if !itemNameError.isEmpty { Text(itemNameError) .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } TextField("Model Number (optional)", text: $modelNumber) @@ -129,7 +129,7 @@ struct DocumentFormView: View { if !providerError.isEmpty { Text(providerError) .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } TextField("Provider Contact (optional)", text: $providerContact) @@ -138,8 +138,9 @@ struct DocumentFormView: View { } footer: { Text("Required for warranties: Item Name and Provider") .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } + .listRowBackground(Color.appBackgroundSecondary) Section("Warranty Claims") { TextField("Claim Phone (optional)", text: $claimPhone) @@ -149,12 +150,14 @@ struct DocumentFormView: View { TextField("Claim Website (optional)", text: $claimWebsite) .keyboardType(.URL) } + .listRowBackground(Color.appBackgroundSecondary) Section("Warranty Dates") { TextField("Purchase Date (YYYY-MM-DD)", text: $purchaseDate) TextField("Warranty Start Date (YYYY-MM-DD)", text: $startDate) TextField("Warranty End Date (YYYY-MM-DD)", text: $endDate) } + .listRowBackground(Color.appBackgroundSecondary) } } @@ -181,6 +184,7 @@ struct DocumentFormView: View { .frame(height: 200) } } + .listRowBackground(Color.appBackgroundSecondary) } Section("Photos") { @@ -200,6 +204,7 @@ struct DocumentFormView: View { .foregroundColor(.secondary) } } + .listRowBackground(Color.appBackgroundSecondary) } var body: some View { @@ -207,6 +212,9 @@ struct DocumentFormView: View { Form { formContent } + .listStyle(.plain) + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationTitle(isEditMode ? (isWarranty ? "Edit Warranty" : "Edit Document") : (isWarranty ? "Add Warranty" : "Add Document")) .navigationBarTitleDisplayMode(.inline) .toolbar { @@ -282,7 +290,7 @@ struct DocumentFormView: View { if !residenceError.isEmpty { Text(residenceError) .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } } } header: { @@ -290,8 +298,9 @@ struct DocumentFormView: View { } footer: { Text("Required") .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } + .listRowBackground(Color.appBackgroundSecondary) } // Document Type @@ -314,6 +323,7 @@ struct DocumentFormView: View { } } } + .listRowBackground(Color.appBackgroundSecondary) // Basic Information Section { @@ -321,7 +331,7 @@ struct DocumentFormView: View { if !titleError.isEmpty { Text(titleError) .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } TextField("Description (optional)", text: $description, axis: .vertical) @@ -331,8 +341,9 @@ struct DocumentFormView: View { } footer: { Text("Required: Title") .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } + .listRowBackground(Color.appBackgroundSecondary) // Warranty-specific fields warrantySection @@ -347,6 +358,7 @@ struct DocumentFormView: View { } } } + .listRowBackground(Color.appBackgroundSecondary) } // Additional Information @@ -356,12 +368,14 @@ struct DocumentFormView: View { TextField("Notes (optional)", text: $notes, axis: .vertical) .lineLimit(3...6) } + .listRowBackground(Color.appBackgroundSecondary) // Active Status (Edit mode only) if isEditMode { Section { Toggle("Active", isOn: $isActive) } + .listRowBackground(Color.appBackgroundSecondary) } // Photos diff --git a/iosApp/iosApp/Documents/DocumentsWarrantiesView.swift b/iosApp/iosApp/Documents/DocumentsWarrantiesView.swift index d01eac0..00278b4 100644 --- a/iosApp/iosApp/Documents/DocumentsWarrantiesView.swift +++ b/iosApp/iosApp/Documents/DocumentsWarrantiesView.swift @@ -28,7 +28,7 @@ struct DocumentsWarrantiesView: View { var body: some View { ZStack { - Color(.systemGroupedBackground).ignoresSafeArea() + Color.appBackgroundPrimary.ignoresSafeArea() VStack(spacing: 0) { // Segmented Control for Tabs @@ -104,7 +104,7 @@ struct DocumentsWarrantiesView: View { loadWarranties() }) { Image(systemName: showActiveOnly ? "checkmark.circle.fill" : "checkmark.circle") - .foregroundColor(showActiveOnly ? .green : Color(.secondaryLabel)) + .foregroundColor(showActiveOnly ? Color.appPrimary : Color.appTextSecondary) } } @@ -149,7 +149,7 @@ struct DocumentsWarrantiesView: View { } } label: { Image(systemName: "line.3.horizontal.decrease.circle") - .foregroundColor((selectedCategory != nil || selectedDocType != nil) ? .blue : Color(.secondaryLabel)) + .foregroundColor((selectedCategory != nil || selectedDocType != nil) ? Color.appPrimary : Color.appTextSecondary) } // Add Button @@ -158,7 +158,7 @@ struct DocumentsWarrantiesView: View { }) { Image(systemName: "plus.circle.fill") .font(.title2) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) } } } diff --git a/iosApp/iosApp/Login/LoginView.swift b/iosApp/iosApp/Login/LoginView.swift index 79227a6..d7827bf 100644 --- a/iosApp/iosApp/Login/LoginView.swift +++ b/iosApp/iosApp/Login/LoginView.swift @@ -26,7 +26,7 @@ struct LoginView: View { private var buttonBackgroundColor: Color { if viewModel.isLoading || !isFormValid { - return Color(.tertiaryLabel) + return Color.appTextSecondary } return .clear } @@ -39,7 +39,7 @@ struct LoginView: View { NavigationView { ZStack { // Background gradient - Color(.systemGroupedBackground) + Color.appBackgroundPrimary .ignoresSafeArea() ScrollView { @@ -52,9 +52,9 @@ struct LoginView: View { // App Icon with gradient ZStack { Circle() - .fill(LinearGradient(colors: [.blue, .blue.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) + .fill(LinearGradient(colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) .frame(width: 100, height: 100) - .shadow(color: .blue.opacity(0.3), radius: 20, y: 10) + .shadow(color: Color.appPrimary.opacity(0.3), radius: 20, y: 10) Image(systemName: "house.fill") .font(.system(size: 50, weight: .semibold)) @@ -64,11 +64,11 @@ struct LoginView: View { VStack(spacing: AppSpacing.xs) { Text("Welcome Back") .font(.title2.weight(.bold)) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) Text("Sign in to manage your properties") .font(.body) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } } @@ -78,11 +78,11 @@ struct LoginView: View { VStack(alignment: .leading, spacing: AppSpacing.xs) { Text("Email or Username") .font(.subheadline.weight(.medium)) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) HStack(spacing: AppSpacing.sm) { Image(systemName: "envelope.fill") - .foregroundColor(Color(.tertiaryLabel)) + .foregroundColor(Color.appTextSecondary) .frame(width: 20) TextField("Enter your email", text: $viewModel.username) @@ -100,13 +100,13 @@ struct LoginView: View { .accessibilityIdentifier(AccessibilityIdentifiers.Authentication.usernameField) } .padding(AppSpacing.md) - .background(Color(.secondarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.md) .overlay( RoundedRectangle(cornerRadius: AppRadius.md) - .stroke(focusedField == .username ? .blue : Color(.separator), lineWidth: 1.5) + .stroke(focusedField == .username ? Color.appPrimary : Color.appTextSecondary.opacity(0.3), lineWidth: 1.5) ) - .shadow(color: focusedField == .username ? .blue.opacity(0.1) : .clear, radius: 8) + .shadow(color: focusedField == .username ? Color.appPrimary.opacity(0.1) : .clear, radius: 8) .animation(.easeInOut(duration: 0.2), value: focusedField) } @@ -114,11 +114,11 @@ struct LoginView: View { VStack(alignment: .leading, spacing: AppSpacing.xs) { Text("Password") .font(.subheadline.weight(.medium)) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) HStack(spacing: AppSpacing.sm) { Image(systemName: "lock.fill") - .foregroundColor(Color(.tertiaryLabel)) + .foregroundColor(Color.appTextSecondary) .frame(width: 20) Group { @@ -147,19 +147,19 @@ struct LoginView: View { isPasswordVisible.toggle() }) { Image(systemName: isPasswordVisible ? "eye.slash.fill" : "eye.fill") - .foregroundColor(Color(.tertiaryLabel)) + .foregroundColor(Color.appTextSecondary) .frame(width: 20) } .accessibilityIdentifier(AccessibilityIdentifiers.Authentication.passwordVisibilityToggle) } .padding(AppSpacing.md) - .background(Color(.secondarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.md) .overlay( RoundedRectangle(cornerRadius: AppRadius.md) - .stroke(focusedField == .password ? .blue : Color(.separator), lineWidth: 1.5) + .stroke(focusedField == .password ? Color.appPrimary : Color.appTextSecondary.opacity(0.3), lineWidth: 1.5) ) - .shadow(color: focusedField == .password ? .blue.opacity(0.1) : .clear, radius: 8) + .shadow(color: focusedField == .password ? Color.appPrimary.opacity(0.1) : .clear, radius: 8) .animation(.easeInOut(duration: 0.2), value: focusedField) .onChange(of: viewModel.password) { _, _ in viewModel.clearError() @@ -173,7 +173,7 @@ struct LoginView: View { showPasswordReset = true } .font(.subheadline.weight(.medium)) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) .accessibilityIdentifier(AccessibilityIdentifiers.Authentication.forgotPasswordButton) } @@ -181,14 +181,14 @@ struct LoginView: View { if let errorMessage = viewModel.errorMessage { HStack(spacing: AppSpacing.sm) { Image(systemName: "exclamationmark.circle.fill") - .foregroundColor(.red) + .foregroundColor(Color.appError) Text(errorMessage) .font(.callout) - .foregroundColor(.red) + .foregroundColor(Color.appError) Spacer() } .padding(AppSpacing.md) - .background(.red.opacity(0.1)) + .background(Color.appError.opacity(0.1)) .cornerRadius(AppRadius.md) } @@ -203,19 +203,19 @@ struct LoginView: View { HStack(spacing: AppSpacing.xs) { Text("Don't have an account?") .font(.body) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) Button("Sign Up") { showingRegister = true } .font(.body) .fontWeight(.semibold) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) .accessibilityIdentifier(AccessibilityIdentifiers.Authentication.signUpButton) } } .padding(AppSpacing.xl) - .background(Color(.secondarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.xxl) .shadow(color: .black.opacity(0.08), radius: 20, y: 10) .padding(.horizontal, AppSpacing.lg) @@ -282,11 +282,11 @@ struct LoginView: View { } .frame(maxWidth: .infinity) .frame(height: 56) - .foregroundColor(.white) + .foregroundColor(Color.appTextOnPrimary) .background(loginButtonBackground) .cornerRadius(AppRadius.md) .shadow( - color: shouldShowShadow ? .blue.opacity(0.3) : .clear, + color: shouldShowShadow ? Color.appPrimary.opacity(0.3) : .clear, radius: 10, y: 5 ) @@ -294,9 +294,9 @@ struct LoginView: View { private var loginButtonBackground: AnyShapeStyle { if viewModel.isLoading || !isFormValid { - AnyShapeStyle(Color(.tertiaryLabel)) + AnyShapeStyle(Color.appTextSecondary) } else { - AnyShapeStyle(LinearGradient(colors: [.blue, .blue.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) + AnyShapeStyle(LinearGradient(colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) } } } diff --git a/iosApp/iosApp/MainTabView.swift b/iosApp/iosApp/MainTabView.swift index 80e04ce..ebf3289 100644 --- a/iosApp/iosApp/MainTabView.swift +++ b/iosApp/iosApp/MainTabView.swift @@ -51,6 +51,7 @@ struct MainTabView: View { .tag(4) .accessibilityIdentifier(AccessibilityIdentifiers.Navigation.profileTab) } + .tint(Color.appPrimary) .onChange(of: authManager.isAuthenticated) { _ in selectedTab = 0 } diff --git a/iosApp/iosApp/PasswordReset/ForgotPasswordView.swift b/iosApp/iosApp/PasswordReset/ForgotPasswordView.swift index 0d8ef95..3778d2e 100644 --- a/iosApp/iosApp/PasswordReset/ForgotPasswordView.swift +++ b/iosApp/iosApp/PasswordReset/ForgotPasswordView.swift @@ -13,7 +13,7 @@ struct ForgotPasswordView: View { VStack(spacing: 12) { Image(systemName: "key.fill") .font(.system(size: 60)) - .foregroundStyle(.blue.gradient) + .foregroundStyle(Color.appPrimary.gradient) .padding(.vertical) Text("Forgot Password?") @@ -22,7 +22,7 @@ struct ForgotPasswordView: View { Text("Enter your email address and we'll send you a verification code") .font(.subheadline) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) .multilineTextAlignment(.center) } .frame(maxWidth: .infinity) @@ -49,30 +49,33 @@ struct ForgotPasswordView: View { } footer: { Text("We'll send a 6-digit verification code to this address") } + .listRowBackground(Color.appBackgroundSecondary) // Error/Success Messages if let errorMessage = viewModel.errorMessage { Section { Label { Text(errorMessage) - .foregroundColor(.red) + .foregroundColor(Color.appError) } icon: { Image(systemName: "exclamationmark.triangle.fill") - .foregroundColor(.red) + .foregroundColor(Color.appError) } } + .listRowBackground(Color.appBackgroundSecondary) } if let successMessage = viewModel.successMessage { Section { Label { Text(successMessage) - .foregroundColor(.green) + .foregroundColor(Color.appAccent) } icon: { Image(systemName: "checkmark.circle.fill") - .foregroundColor(.green) + .foregroundColor(Color.appAccent) } } + .listRowBackground(Color.appBackgroundSecondary) } // Send Code Button @@ -99,12 +102,16 @@ struct ForgotPasswordView: View { HStack { Spacer() Text("Back to Login") - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) Spacer() } } } + .listRowBackground(Color.appBackgroundSecondary) } + .listStyle(.plain) + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationTitle("Reset Password") .navigationBarTitleDisplayMode(.inline) .onAppear { diff --git a/iosApp/iosApp/PasswordReset/ResetPasswordView.swift b/iosApp/iosApp/PasswordReset/ResetPasswordView.swift index ef7c055..86be831 100644 --- a/iosApp/iosApp/PasswordReset/ResetPasswordView.swift +++ b/iosApp/iosApp/PasswordReset/ResetPasswordView.swift @@ -20,16 +20,17 @@ struct ResetPasswordView: View { VStack(spacing: 12) { Image(systemName: "lock.rotation") .font(.system(size: 60)) - .foregroundStyle(.blue.gradient) + .foregroundStyle(Color.appPrimary.gradient) .padding(.vertical) Text("Set New Password") .font(.title2) .fontWeight(.bold) + .foregroundColor(Color.appTextPrimary) Text("Create a strong password to secure your account") .font(.subheadline) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) .multilineTextAlignment(.center) } .frame(maxWidth: .infinity) @@ -42,30 +43,34 @@ struct ResetPasswordView: View { VStack(alignment: .leading, spacing: 8) { HStack(spacing: 8) { Image(systemName: viewModel.newPassword.count >= 8 ? "checkmark.circle.fill" : "circle") - .foregroundColor(viewModel.newPassword.count >= 8 ? .green : .secondary) + .foregroundColor(viewModel.newPassword.count >= 8 ? Color.appPrimary : Color.appTextSecondary) Text("At least 8 characters") .font(.caption) + .foregroundColor(Color.appTextPrimary) } HStack(spacing: 8) { Image(systemName: hasLetter ? "checkmark.circle.fill" : "circle") - .foregroundColor(hasLetter ? .green : .secondary) + .foregroundColor(hasLetter ? Color.appPrimary : Color.appTextSecondary) Text("Contains letters") .font(.caption) + .foregroundColor(Color.appTextPrimary) } HStack(spacing: 8) { Image(systemName: hasNumber ? "checkmark.circle.fill" : "circle") - .foregroundColor(hasNumber ? .green : .secondary) + .foregroundColor(hasNumber ? Color.appPrimary : Color.appTextSecondary) Text("Contains numbers") .font(.caption) + .foregroundColor(Color.appTextPrimary) } HStack(spacing: 8) { Image(systemName: passwordsMatch ? "checkmark.circle.fill" : "circle") - .foregroundColor(passwordsMatch ? .green : .secondary) + .foregroundColor(passwordsMatch ? Color.appPrimary : Color.appTextSecondary) Text("Passwords match") .font(.caption) + .foregroundColor(Color.appTextPrimary) } } } header: { @@ -97,7 +102,7 @@ struct ResetPasswordView: View { isNewPasswordVisible.toggle() }) { Image(systemName: isNewPasswordVisible ? "eye.slash.fill" : "eye.fill") - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } .buttonStyle(.plain) } @@ -133,7 +138,7 @@ struct ResetPasswordView: View { isConfirmPasswordVisible.toggle() }) { Image(systemName: isConfirmPasswordVisible ? "eye.slash.fill" : "eye.fill") - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } .buttonStyle(.plain) } @@ -149,10 +154,10 @@ struct ResetPasswordView: View { Section { Label { Text(errorMessage) - .foregroundColor(.red) + .foregroundColor(Color.appError) } icon: { Image(systemName: "exclamationmark.triangle.fill") - .foregroundColor(.red) + .foregroundColor(Color.appError) } } } @@ -161,11 +166,11 @@ struct ResetPasswordView: View { Section { Label { Text(successMessage) - .foregroundColor(.green) + .foregroundColor(Color.appPrimary) .multilineTextAlignment(.center) } icon: { Image(systemName: "checkmark.circle.fill") - .foregroundColor(.green) + .foregroundColor(Color.appPrimary) } } } @@ -204,6 +209,9 @@ struct ResetPasswordView: View { } } } + .listStyle(.plain) + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationTitle("Reset Password") .navigationBarTitleDisplayMode(.inline) .navigationBarBackButtonHidden(true) diff --git a/iosApp/iosApp/PasswordReset/VerifyResetCodeView.swift b/iosApp/iosApp/PasswordReset/VerifyResetCodeView.swift index b6616f7..3d971e4 100644 --- a/iosApp/iosApp/PasswordReset/VerifyResetCodeView.swift +++ b/iosApp/iosApp/PasswordReset/VerifyResetCodeView.swift @@ -13,21 +13,22 @@ struct VerifyResetCodeView: View { VStack(spacing: 12) { Image(systemName: "envelope.badge.fill") .font(.system(size: 60)) - .foregroundStyle(.blue.gradient) + .foregroundStyle(Color.appPrimary.gradient) .padding(.vertical) Text("Check Your Email") .font(.title2) .fontWeight(.bold) + .foregroundColor(Color.appTextPrimary) Text("We sent a 6-digit code to") .font(.subheadline) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) Text(viewModel.email) .font(.subheadline) .fontWeight(.semibold) - .foregroundColor(.primary) + .foregroundColor(Color.appTextPrimary) } .frame(maxWidth: .infinity) .padding(.vertical) @@ -39,11 +40,13 @@ struct VerifyResetCodeView: View { Label { Text("Code expires in 15 minutes") .fontWeight(.semibold) + .foregroundColor(Color.appTextPrimary) } icon: { Image(systemName: "clock.fill") - .foregroundColor(.orange) + .foregroundColor(Color.appAccent) } } + .listRowBackground(Color.appBackgroundSecondary) // Code Input Section Section { @@ -66,30 +69,33 @@ struct VerifyResetCodeView: View { } footer: { Text("Enter the 6-digit code from your email") } + .listRowBackground(Color.appBackgroundSecondary) // Error/Success Messages if let errorMessage = viewModel.errorMessage { Section { Label { Text(errorMessage) - .foregroundColor(.red) + .foregroundColor(Color.appError) } icon: { Image(systemName: "exclamationmark.triangle.fill") - .foregroundColor(.red) + .foregroundColor(Color.appError) } } + .listRowBackground(Color.appBackgroundSecondary) } if let successMessage = viewModel.successMessage { Section { Label { Text(successMessage) - .foregroundColor(.green) + .foregroundColor(Color.appPrimary) } icon: { Image(systemName: "checkmark.circle.fill") - .foregroundColor(.green) + .foregroundColor(Color.appPrimary) } } + .listRowBackground(Color.appBackgroundSecondary) } // Verify Button @@ -110,13 +116,14 @@ struct VerifyResetCodeView: View { } .disabled(viewModel.code.count != 6 || viewModel.isLoading) } + .listRowBackground(Color.appBackgroundSecondary) // Help Section Section { VStack(spacing: 12) { Text("Didn't receive the code?") .font(.subheadline) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) Button(action: { // Clear code and go back to request new one @@ -131,13 +138,16 @@ struct VerifyResetCodeView: View { Text("Check your spam folder if you don't see it") .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) .multilineTextAlignment(.center) } .frame(maxWidth: .infinity) } .listRowBackground(Color.clear) } + .listStyle(.plain) + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationTitle("Verify Code") .navigationBarTitleDisplayMode(.inline) .navigationBarBackButtonHidden(true) diff --git a/iosApp/iosApp/Profile/ProfileTabView.swift b/iosApp/iosApp/Profile/ProfileTabView.swift index 7007184..139c4bb 100644 --- a/iosApp/iosApp/Profile/ProfileTabView.swift +++ b/iosApp/iosApp/Profile/ProfileTabView.swift @@ -11,18 +11,20 @@ struct ProfileTabView: View { Image(systemName: "person.circle.fill") .resizable() .frame(width: 60, height: 60) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) VStack(alignment: .leading, spacing: 4) { Text("User Profile") .font(.headline) + .foregroundColor(Color.appTextPrimary) Text("Manage your account") .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } } .padding(.vertical, 8) + .listRowBackground(Color.appBackgroundSecondary) } Section("Account") { @@ -30,7 +32,7 @@ struct ProfileTabView: View { showingProfileEdit = true }) { Label("Edit Profile", systemImage: "person.crop.circle") - .foregroundColor(.primary) + .foregroundColor(Color.appTextPrimary) } NavigationLink(destination: Text("Notifications")) { @@ -41,15 +43,17 @@ struct ProfileTabView: View { Label("Privacy", systemImage: "lock.shield") } } + .listRowBackground(Color.appBackgroundSecondary) Section { Button(action: { showingLogoutAlert = true }) { Label("Log Out", systemImage: "rectangle.portrait.and.arrow.right") - .foregroundColor(.red) + .foregroundColor(Color.appError) } .accessibilityIdentifier(AccessibilityIdentifiers.Profile.logoutButton) + .listRowBackground(Color.appBackgroundSecondary) } Section { @@ -57,13 +61,17 @@ struct ProfileTabView: View { Text("MyCrib") .font(.caption) .fontWeight(.semibold) + .foregroundColor(Color.appTextPrimary) Text("Version 1.0.0") .font(.caption2) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } + .listRowBackground(Color.appBackgroundSecondary) } } + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationTitle("Profile") .sheet(isPresented: $showingProfileEdit) { ProfileView() diff --git a/iosApp/iosApp/Profile/ProfileView.swift b/iosApp/iosApp/Profile/ProfileView.swift index 93d0f00..491220f 100644 --- a/iosApp/iosApp/Profile/ProfileView.swift +++ b/iosApp/iosApp/Profile/ProfileView.swift @@ -16,7 +16,7 @@ struct ProfileView: View { ProgressView() Text("Loading profile...") .font(.subheadline) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) .padding(.top, 8) } } else { @@ -25,11 +25,12 @@ struct ProfileView: View { VStack(spacing: 16) { Image(systemName: "person.circle.fill") .font(.system(size: 60)) - .foregroundStyle(.blue.gradient) + .foregroundStyle(Color.appPrimary.gradient) Text("Profile Settings") .font(.title2) .fontWeight(.bold) + .foregroundColor(Color.appTextPrimary) } .frame(maxWidth: .infinity) .padding(.vertical) @@ -57,6 +58,7 @@ struct ProfileView: View { } header: { Text("Personal Information") } + .listRowBackground(Color.appBackgroundSecondary) Section { TextField("Email", text: $viewModel.email) @@ -73,29 +75,32 @@ struct ProfileView: View { } footer: { Text("Email is required and must be unique") } + .listRowBackground(Color.appBackgroundSecondary) if let errorMessage = viewModel.errorMessage { Section { HStack { Image(systemName: "exclamationmark.triangle.fill") - .foregroundColor(.red) + .foregroundColor(Color.appError) Text(errorMessage) - .foregroundColor(.red) + .foregroundColor(Color.appError) .font(.subheadline) } } + .listRowBackground(Color.appBackgroundSecondary) } if let successMessage = viewModel.successMessage { Section { HStack { Image(systemName: "checkmark.circle.fill") - .foregroundColor(.green) + .foregroundColor(Color.appPrimary) Text(successMessage) - .foregroundColor(.green) + .foregroundColor(Color.appPrimary) .font(.subheadline) } } + .listRowBackground(Color.appBackgroundSecondary) } Section { @@ -113,7 +118,11 @@ struct ProfileView: View { } .disabled(viewModel.isLoading || viewModel.email.isEmpty) } + .listRowBackground(Color.appBackgroundSecondary) } + .listStyle(.plain) + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationTitle("Profile") .navigationBarTitleDisplayMode(.inline) .toolbar { diff --git a/iosApp/iosApp/Register/RegisterView.swift b/iosApp/iosApp/Register/RegisterView.swift index 4841995..dbdf164 100644 --- a/iosApp/iosApp/Register/RegisterView.swift +++ b/iosApp/iosApp/Register/RegisterView.swift @@ -18,7 +18,7 @@ struct RegisterView: View { VStack(spacing: 16) { Image(systemName: "person.badge.plus") .font(.system(size: 60)) - .foregroundStyle(.blue.gradient) + .foregroundStyle(Color.appPrimary.gradient) Text("Join MyCrib") .font(.largeTitle) @@ -26,7 +26,7 @@ struct RegisterView: View { Text("Start managing your properties today") .font(.subheadline) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } .frame(maxWidth: .infinity) .padding(.vertical) @@ -57,6 +57,7 @@ struct RegisterView: View { } header: { Text("Account Information") } + .listRowBackground(Color.appBackgroundSecondary) Section { SecureField("Password", text: $viewModel.password) @@ -79,17 +80,19 @@ struct RegisterView: View { } footer: { Text("Password must be secure") } + .listRowBackground(Color.appBackgroundSecondary) if let errorMessage = viewModel.errorMessage { Section { HStack { Image(systemName: "exclamationmark.triangle.fill") - .foregroundColor(.red) + .foregroundColor(Color.appError) Text(errorMessage) - .foregroundColor(.red) + .foregroundColor(Color.appError) .font(.subheadline) } } + .listRowBackground(Color.appBackgroundSecondary) } Section { @@ -108,7 +111,11 @@ struct RegisterView: View { .disabled(viewModel.isLoading) .accessibilityIdentifier(AccessibilityIdentifiers.Authentication.registerButton) } + .listRowBackground(Color.appBackgroundSecondary) } + .listStyle(.plain) + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationTitle("Create Account") .navigationBarTitleDisplayMode(.inline) .toolbar { diff --git a/iosApp/iosApp/Residence/JoinResidenceView.swift b/iosApp/iosApp/Residence/JoinResidenceView.swift index f9ca98c..40396b7 100644 --- a/iosApp/iosApp/Residence/JoinResidenceView.swift +++ b/iosApp/iosApp/Residence/JoinResidenceView.swift @@ -28,14 +28,16 @@ struct JoinResidenceView: View { Text("Enter Share Code") } footer: { Text("Enter the 6-character code shared with you to join a residence") - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } + .listRowBackground(Color.appBackgroundSecondary) if let error = viewModel.errorMessage { Section { Text(error) - .foregroundColor(.red) + .foregroundColor(Color.appError) } + .listRowBackground(Color.appBackgroundSecondary) } Section { @@ -54,7 +56,11 @@ struct JoinResidenceView: View { } .disabled(shareCode.count != 6 || viewModel.isLoading) } + .listRowBackground(Color.appBackgroundSecondary) } + .listStyle(.plain) + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationTitle("Join Residence") .navigationBarTitleDisplayMode(.inline) .toolbar { diff --git a/iosApp/iosApp/Residence/ManageUsersView.swift b/iosApp/iosApp/Residence/ManageUsersView.swift index 9eb813d..d245653 100644 --- a/iosApp/iosApp/Residence/ManageUsersView.swift +++ b/iosApp/iosApp/Residence/ManageUsersView.swift @@ -17,7 +17,7 @@ struct ManageUsersView: View { var body: some View { NavigationView { ZStack { - Color(.systemGroupedBackground) + Color.appBackgroundPrimary .ignoresSafeArea() if isLoading { @@ -63,6 +63,9 @@ struct ManageUsersView: View { } } } + .listStyle(.plain) + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationTitle("Manage Users") .navigationBarTitleDisplayMode(.inline) .toolbar { diff --git a/iosApp/iosApp/Residence/ResidenceDetailView.swift b/iosApp/iosApp/Residence/ResidenceDetailView.swift index c0ba2f0..7874321 100644 --- a/iosApp/iosApp/Residence/ResidenceDetailView.swift +++ b/iosApp/iosApp/Residence/ResidenceDetailView.swift @@ -30,9 +30,9 @@ struct ResidenceDetailView: View { var body: some View { ZStack { - Color(.systemGroupedBackground) + Color.appBackgroundPrimary .ignoresSafeArea() - + mainContent } .navigationBarTitleDisplayMode(.inline) @@ -174,7 +174,7 @@ private extension ResidenceDetailView { ProgressView() Text("Loading residence...") .font(.subheadline) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } } @@ -209,7 +209,7 @@ private extension ResidenceDetailView { ProgressView("Loading tasks...") } else if let tasksError = tasksError { Text("Error loading tasks: \(tasksError)") - .foregroundColor(.red) + .foregroundColor(Color.appError) .padding() } } @@ -266,7 +266,7 @@ private extension ResidenceDetailView { showDeleteConfirmation = true } label: { Image(systemName: "trash") - .foregroundStyle(.red) + .foregroundStyle(Color.appError) } .accessibilityIdentifier(AccessibilityIdentifiers.Residence.deleteButton) } diff --git a/iosApp/iosApp/Residence/ResidencesListView.swift b/iosApp/iosApp/Residence/ResidencesListView.swift index d2bd0b0..fe09794 100644 --- a/iosApp/iosApp/Residence/ResidencesListView.swift +++ b/iosApp/iosApp/Residence/ResidencesListView.swift @@ -10,7 +10,7 @@ struct ResidencesListView: View { var body: some View { ZStack { - Color(.systemGroupedBackground) + Color.appBackgroundPrimary .ignoresSafeArea() if viewModel.myResidences == nil && viewModel.isLoading { @@ -19,7 +19,7 @@ struct ResidencesListView: View { .scaleEffect(1.2) Text("Loading properties...") .font(.body) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } } else if let response = viewModel.myResidences { if response.residences.isEmpty { @@ -37,10 +37,10 @@ struct ResidencesListView: View { VStack(alignment: .leading, spacing: AppSpacing.xxs) { Text("Your Properties") .font(.title3.weight(.semibold)) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) Text("\(response.residences.count) \(response.residences.count == 1 ? "property" : "properties")") .font(.callout) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } Spacer() } @@ -75,7 +75,7 @@ struct ResidencesListView: View { }) { Image(systemName: "person.badge.plus") .font(.system(size: 18, weight: .semibold)) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) } Button(action: { @@ -83,7 +83,7 @@ struct ResidencesListView: View { }) { Image(systemName: "plus.circle.fill") .font(.system(size: 22, weight: .semibold)) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) } .accessibilityIdentifier(AccessibilityIdentifiers.Residence.addButton) } diff --git a/iosApp/iosApp/ResidenceFormView.swift b/iosApp/iosApp/ResidenceFormView.swift index 3dd7a3c..0f98886 100644 --- a/iosApp/iosApp/ResidenceFormView.swift +++ b/iosApp/iosApp/ResidenceFormView.swift @@ -55,7 +55,7 @@ struct ResidenceFormView: View { if !nameError.isEmpty { Text(nameError) .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } Picker("Property Type", selection: $selectedPropertyType) { @@ -70,8 +70,9 @@ struct ResidenceFormView: View { } footer: { Text("Required: Name") .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } + .listRowBackground(Color.appBackgroundSecondary) Section { TextField("Street Address", text: $streetAddress) @@ -100,6 +101,7 @@ struct ResidenceFormView: View { } header: { Text("Address") } + .listRowBackground(Color.appBackgroundSecondary) Section(header: Text("Property Features")) { HStack { @@ -139,6 +141,7 @@ struct ResidenceFormView: View { .focused($focusedField, equals: .yearBuilt) .accessibilityIdentifier(AccessibilityIdentifiers.Residence.yearBuiltField) } + .listRowBackground(Color.appBackgroundSecondary) Section(header: Text("Additional Details")) { TextField("Description (optional)", text: $description, axis: .vertical) @@ -148,15 +151,20 @@ struct ResidenceFormView: View { Toggle("Primary Residence", isOn: $isPrimary) .accessibilityIdentifier(AccessibilityIdentifiers.Residence.isPrimaryToggle) } + .listRowBackground(Color.appBackgroundSecondary) if let errorMessage = viewModel.errorMessage { Section { Text(errorMessage) - .foregroundColor(.red) + .foregroundColor(Color.appError) .font(.caption) } + .listRowBackground(Color.appBackgroundSecondary) } } + .listStyle(.plain) + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationTitle(isEditMode ? "Edit Residence" : "Add Residence") .navigationBarTitleDisplayMode(.inline) .toolbar { diff --git a/iosApp/iosApp/Subviews/Auth/LoginHeader.swift b/iosApp/iosApp/Subviews/Auth/LoginHeader.swift index 114ce82..5a0991f 100644 --- a/iosApp/iosApp/Subviews/Auth/LoginHeader.swift +++ b/iosApp/iosApp/Subviews/Auth/LoginHeader.swift @@ -7,11 +7,12 @@ struct LoginHeader: View { .resizable() .aspectRatio(contentMode: .fit) .frame(width: 80, height: 80) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) Text("MyCrib") .font(.largeTitle) .fontWeight(.bold) + .foregroundColor(Color.appTextPrimary) } .padding(.top, 60) .padding(.bottom, 20) diff --git a/iosApp/iosApp/Subviews/Auth/RegisterHeader.swift b/iosApp/iosApp/Subviews/Auth/RegisterHeader.swift index 436131b..92de4f6 100644 --- a/iosApp/iosApp/Subviews/Auth/RegisterHeader.swift +++ b/iosApp/iosApp/Subviews/Auth/RegisterHeader.swift @@ -7,15 +7,16 @@ struct RegisterHeader: View { .resizable() .aspectRatio(contentMode: .fit) .frame(width: 64, height: 64) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) Text("Join MyCrib") .font(.largeTitle) .fontWeight(.bold) + .foregroundColor(Color.appTextPrimary) Text("Start managing your properties today") .font(.subheadline) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } .padding(.top, 40) .padding(.bottom, 20) diff --git a/iosApp/iosApp/Subviews/Common/ErrorMessageView.swift b/iosApp/iosApp/Subviews/Common/ErrorMessageView.swift index 3b2bcd3..1530102 100644 --- a/iosApp/iosApp/Subviews/Common/ErrorMessageView.swift +++ b/iosApp/iosApp/Subviews/Common/ErrorMessageView.swift @@ -7,21 +7,21 @@ struct ErrorMessageView: View { var body: some View { HStack { Image(systemName: "exclamationmark.triangle.fill") - .foregroundColor(.red) + .foregroundColor(Color.appError) Text(message) .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) Spacer() Button(action: onDismiss) { Image(systemName: "xmark.circle.fill") - .foregroundColor(.red) + .foregroundColor(Color.appError) } } .padding() - .background(Color.red.opacity(0.1)) + .background(Color.appError.opacity(0.1)) .cornerRadius(8) } } diff --git a/iosApp/iosApp/Subviews/Common/ErrorView.swift b/iosApp/iosApp/Subviews/Common/ErrorView.swift index c43d23a..d0c47ed 100644 --- a/iosApp/iosApp/Subviews/Common/ErrorView.swift +++ b/iosApp/iosApp/Subviews/Common/ErrorView.swift @@ -8,18 +8,18 @@ struct ErrorView: View { VStack(spacing: 16) { Image(systemName: "exclamationmark.triangle") .font(.system(size: 64)) - .foregroundColor(.red) + .foregroundColor(Color.appError) Text("Error: \(message)") - .foregroundColor(.red) + .foregroundColor(Color.appError) .multilineTextAlignment(.center) Button(action: retryAction) { Text("Retry") .padding(.horizontal, 32) .padding(.vertical, 12) - .background(Color.blue) - .foregroundColor(.white) + .background(Color.appPrimary) + .foregroundColor(Color.appTextOnPrimary) .cornerRadius(8) } } diff --git a/iosApp/iosApp/Subviews/Common/HomeNavigationCard.swift b/iosApp/iosApp/Subviews/Common/HomeNavigationCard.swift index 8f147cb..3cb977e 100644 --- a/iosApp/iosApp/Subviews/Common/HomeNavigationCard.swift +++ b/iosApp/iosApp/Subviews/Common/HomeNavigationCard.swift @@ -10,13 +10,13 @@ struct HomeNavigationCard: View { // Icon with gradient background ZStack { RoundedRectangle(cornerRadius: AppRadius.md) - .fill(LinearGradient(colors: [.blue, .blue.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) + .fill(LinearGradient(colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) .frame(width: 60, height: 60) - .shadow(color: .blue.opacity(0.3), radius: 8, y: 4) + .shadow(color: Color.appPrimary.opacity(0.3), radius: 8, y: 4) Image(systemName: icon) .font(.system(size: 28, weight: .semibold)) - .foregroundColor(.white) + .foregroundColor(Color.appTextOnPrimary) } // Text Content @@ -24,11 +24,11 @@ struct HomeNavigationCard: View { Text(title) .font(.title3.weight(.semibold)) .fontWeight(.semibold) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) Text(subtitle) .font(.callout) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } Spacer() @@ -36,10 +36,10 @@ struct HomeNavigationCard: View { // Chevron Image(systemName: "chevron.right") .font(.system(size: 16, weight: .semibold)) - .foregroundColor(Color(.tertiaryLabel)) + .foregroundColor(Color.appTextSecondary.opacity(0.7)) } .padding(AppSpacing.lg) - .background(Color(.secondarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.lg) .shadow(color: AppShadow.md.color, radius: AppShadow.md.radius, x: AppShadow.md.x, y: AppShadow.md.y) } diff --git a/iosApp/iosApp/Subviews/Common/ImageThumbnailView.swift b/iosApp/iosApp/Subviews/Common/ImageThumbnailView.swift index e1ca048..19d26d4 100644 --- a/iosApp/iosApp/Subviews/Common/ImageThumbnailView.swift +++ b/iosApp/iosApp/Subviews/Common/ImageThumbnailView.swift @@ -19,7 +19,7 @@ struct ImageThumbnailView: View { Button(action: onRemove) { Image(systemName: "xmark.circle.fill") .font(.title3) - .foregroundStyle(.white) + .foregroundStyle(Color.appTextOnPrimary) .background { Circle() .fill(.black.opacity(0.6)) diff --git a/iosApp/iosApp/Subviews/Common/OverviewCard.swift b/iosApp/iosApp/Subviews/Common/OverviewCard.swift index e41422e..d46ad91 100644 --- a/iosApp/iosApp/Subviews/Common/OverviewCard.swift +++ b/iosApp/iosApp/Subviews/Common/OverviewCard.swift @@ -11,17 +11,17 @@ struct OverviewCard: View { HStack(spacing: AppSpacing.sm) { ZStack { Circle() - .fill(LinearGradient(colors: [.blue, .blue.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) + .fill(LinearGradient(colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) .frame(width: 44, height: 44) Image(systemName: "chart.bar.fill") .font(.system(size: 20, weight: .semibold)) - .foregroundColor(.white) + .foregroundColor(Color.appTextOnPrimary) } Text("Overview") .font(.title3.weight(.semibold)) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) } Spacer() } @@ -32,7 +32,7 @@ struct OverviewCard: View { icon: "house.fill", value: "\(summary.totalResidences)", label: "Properties", - color: .blue + color: Color.appPrimary ) Divider() @@ -42,7 +42,7 @@ struct OverviewCard: View { icon: "list.bullet", value: "\(summary.totalTasks)", label: "Total Tasks", - color: .blue + color: Color.appPrimary ) Divider() @@ -52,12 +52,12 @@ struct OverviewCard: View { icon: "clock.fill", value: "\(summary.totalPending)", label: "Pending", - color: .orange + color: Color.appAccent ) } } .padding(AppSpacing.xl) - .background(Color(.secondarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.xl) .shadow(color: AppShadow.lg.color, radius: AppShadow.lg.radius, x: AppShadow.lg.x, y: AppShadow.lg.y) .padding(.horizontal, AppSpacing.md) diff --git a/iosApp/iosApp/Subviews/Common/StatView.swift b/iosApp/iosApp/Subviews/Common/StatView.swift index 2228126..4b87be0 100644 --- a/iosApp/iosApp/Subviews/Common/StatView.swift +++ b/iosApp/iosApp/Subviews/Common/StatView.swift @@ -4,7 +4,7 @@ struct StatView: View { let icon: String let value: String let label: String - var color: Color = .blue + var color: Color = Color.appPrimary var body: some View { VStack(spacing: AppSpacing.sm) { @@ -21,11 +21,11 @@ struct StatView: View { Text(value) .font(.title2.weight(.semibold)) .fontWeight(.bold) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) Text(label) .font(.footnote.weight(.medium)) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) .multilineTextAlignment(.center) } .frame(maxWidth: .infinity) diff --git a/iosApp/iosApp/Subviews/Residence/EmptyResidencesView.swift b/iosApp/iosApp/Subviews/Residence/EmptyResidencesView.swift index d01e3ad..dbad3e4 100644 --- a/iosApp/iosApp/Subviews/Residence/EmptyResidencesView.swift +++ b/iosApp/iosApp/Subviews/Residence/EmptyResidencesView.swift @@ -5,15 +5,16 @@ struct EmptyResidencesView: View { VStack(spacing: 16) { Image(systemName: "house") .font(.system(size: 80)) - .foregroundColor(.blue.opacity(0.6)) + .foregroundColor(Color.appPrimary.opacity(0.6)) Text("No properties yet") .font(.title2) .fontWeight(.semibold) + .foregroundColor(Color.appTextPrimary) Text("Add your first property to get started!") .font(.body) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } } } diff --git a/iosApp/iosApp/Subviews/Residence/PropertyDetailItem.swift b/iosApp/iosApp/Subviews/Residence/PropertyDetailItem.swift index 6b19073..3513310 100644 --- a/iosApp/iosApp/Subviews/Residence/PropertyDetailItem.swift +++ b/iosApp/iosApp/Subviews/Residence/PropertyDetailItem.swift @@ -9,15 +9,16 @@ struct PropertyDetailItem: View { VStack(spacing: 4) { Image(systemName: icon) .font(.caption) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) Text(value) .font(.subheadline) .fontWeight(.semibold) + .foregroundColor(Color.appTextPrimary) Text(label) .font(.caption2) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } } } diff --git a/iosApp/iosApp/Subviews/Residence/PropertyHeaderCard.swift b/iosApp/iosApp/Subviews/Residence/PropertyHeaderCard.swift index b250407..810057d 100644 --- a/iosApp/iosApp/Subviews/Residence/PropertyHeaderCard.swift +++ b/iosApp/iosApp/Subviews/Residence/PropertyHeaderCard.swift @@ -9,17 +9,18 @@ struct PropertyHeaderCard: View { HStack { Image(systemName: "house.fill") .font(.title2) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) VStack(alignment: .leading, spacing: 4) { Text(residence.name) .font(.title2) .fontWeight(.bold) + .foregroundColor(Color.appTextPrimary) if let propertyType = residence.propertyType { Text(propertyType) .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } } @@ -32,18 +33,19 @@ struct PropertyHeaderCard: View { if let streetAddress = residence.streetAddress { Label(streetAddress, systemImage: "mappin.circle.fill") .font(.subheadline) + .foregroundColor(Color.appTextPrimary) } if residence.city != nil || residence.stateProvince != nil || residence.postalCode != nil { Text("\(residence.city ?? ""), \(residence.stateProvince ?? "") \(residence.postalCode ?? "")") .font(.subheadline) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } if let country = residence.country, !country.isEmpty { Text(country) .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } } @@ -62,8 +64,9 @@ struct PropertyHeaderCard: View { } } .padding(20) - .background(Color.blue.opacity(0.1)) + .background(Color.appBackgroundSecondary) .cornerRadius(16) + .shadow(color: AppShadow.md.color, radius: AppShadow.md.radius, x: AppShadow.md.x, y: AppShadow.md.y) } } diff --git a/iosApp/iosApp/Subviews/Residence/ResidenceCard.swift b/iosApp/iosApp/Subviews/Residence/ResidenceCard.swift index ee16808..119c5f7 100644 --- a/iosApp/iosApp/Subviews/Residence/ResidenceCard.swift +++ b/iosApp/iosApp/Subviews/Residence/ResidenceCard.swift @@ -10,26 +10,26 @@ struct ResidenceCard: View { HStack(spacing: AppSpacing.sm) { ZStack { RoundedRectangle(cornerRadius: AppRadius.sm) - .fill(LinearGradient(colors: [.blue, .blue.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) + .fill(LinearGradient(colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) .frame(width: 44, height: 44) - .shadow(color: .blue.opacity(0.3), radius: 6, y: 3) + .shadow(color: Color.appPrimary.opacity(0.3), radius: 6, y: 3) Image(systemName: "house.fill") .font(.system(size: 20, weight: .semibold)) - .foregroundColor(.white) + .foregroundColor(Color.appTextOnPrimary) } VStack(alignment: .leading, spacing: AppSpacing.xxs) { Text(residence.name) .font(.title3.weight(.semibold)) .fontWeight(.bold) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) .lineLimit(1) if let propertyType = residence.propertyType { Text(propertyType) .font(.caption.weight(.medium)) - .foregroundColor(Color(.tertiaryLabel)) + .foregroundColor(Color.appTextSecondary) .textCase(.uppercase) .tracking(0.5) } @@ -40,11 +40,11 @@ struct ResidenceCard: View { if residence.isPrimary { ZStack { Circle() - .fill(.purple.opacity(0.1)) + .fill(Color.appAccent.opacity(0.2)) .frame(width: 32, height: 32) Image(systemName: "star.fill") .font(.system(size: 14, weight: .bold)) - .foregroundColor(.purple) + .foregroundColor(Color.appAccent) } } } @@ -55,10 +55,10 @@ struct ResidenceCard: View { HStack(spacing: AppSpacing.xxs) { Image(systemName: "mappin.circle.fill") .font(.system(size: 12, weight: .medium)) - .foregroundColor(Color(.tertiaryLabel)) + .foregroundColor(Color.appTextSecondary) Text(streetAddress) .font(.callout) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } } @@ -66,10 +66,10 @@ struct ResidenceCard: View { HStack(spacing: AppSpacing.xxs) { Image(systemName: "location.fill") .font(.system(size: 12, weight: .medium)) - .foregroundColor(Color(.tertiaryLabel)) + .foregroundColor(Color.appTextSecondary) Text("\(residence.city ?? ""), \(residence.stateProvince ?? "")") .font(.callout) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } } } @@ -86,13 +86,13 @@ struct ResidenceCard: View { icon: category.icons.ios, value: "\(category.count)", label: category.displayName, - color: Color(hex: category.color) ?? .gray + color: Color(hex: category.color) ?? Color.appTextSecondary ) } } } .padding(AppSpacing.md) - .background(Color(.secondarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.lg) .shadow(color: AppShadow.md.color, radius: AppShadow.md.radius, x: AppShadow.md.x, y: AppShadow.md.y) } @@ -160,5 +160,5 @@ struct ResidenceCard: View { updatedAt: "2024-01-01T00:00:00Z" )) .padding() - .background(Color(.systemGroupedBackground)) + .background(Color.appBackgroundPrimary) } diff --git a/iosApp/iosApp/Subviews/Residence/ShareCodeCard.swift b/iosApp/iosApp/Subviews/Residence/ShareCodeCard.swift index 29445fc..9b51ac3 100644 --- a/iosApp/iosApp/Subviews/Residence/ShareCodeCard.swift +++ b/iosApp/iosApp/Subviews/Residence/ShareCodeCard.swift @@ -14,17 +14,17 @@ struct ShareCodeCard: View { VStack(alignment: .leading, spacing: 4) { Text("Share Code") .font(.subheadline) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) if let shareCode = shareCode { Text(shareCode.code) .font(.title) .fontWeight(.bold) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) } else { Text("No active code") .font(.body) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } } @@ -43,11 +43,11 @@ struct ShareCodeCard: View { if shareCode != nil { Text("Share this code with others to give them access to \(residenceName)") .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } } .padding() - .background(Color.blue.opacity(0.1)) + .background(Color.appPrimary.opacity(0.1)) .cornerRadius(12) } } diff --git a/iosApp/iosApp/Subviews/Residence/SummaryCard.swift b/iosApp/iosApp/Subviews/Residence/SummaryCard.swift index f4fd69b..7208eb8 100644 --- a/iosApp/iosApp/Subviews/Residence/SummaryCard.swift +++ b/iosApp/iosApp/Subviews/Residence/SummaryCard.swift @@ -46,8 +46,9 @@ struct SummaryCard: View { } } .padding(20) - .background(Color.blue.opacity(0.1)) + .background(Color.appBackgroundSecondary) .cornerRadius(16) + .shadow(color: AppShadow.md.color, radius: AppShadow.md.radius, x: AppShadow.md.x, y: AppShadow.md.y) } } diff --git a/iosApp/iosApp/Subviews/Residence/SummaryStatView.swift b/iosApp/iosApp/Subviews/Residence/SummaryStatView.swift index eb4e808..f78b5d1 100644 --- a/iosApp/iosApp/Subviews/Residence/SummaryStatView.swift +++ b/iosApp/iosApp/Subviews/Residence/SummaryStatView.swift @@ -9,15 +9,16 @@ struct SummaryStatView: View { VStack(spacing: 8) { Image(systemName: icon) .font(.title3) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) Text(value) .font(.title2) .fontWeight(.bold) + .foregroundColor(Color.appTextPrimary) Text(label) .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) .multilineTextAlignment(.center) } .frame(maxWidth: .infinity) diff --git a/iosApp/iosApp/Subviews/Residence/TaskStatChip.swift b/iosApp/iosApp/Subviews/Residence/TaskStatChip.swift index c2701ef..cfc0149 100644 --- a/iosApp/iosApp/Subviews/Residence/TaskStatChip.swift +++ b/iosApp/iosApp/Subviews/Residence/TaskStatChip.swift @@ -19,7 +19,7 @@ struct TaskStatChip: View { Text(label) .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } } } diff --git a/iosApp/iosApp/Subviews/Residence/UserListItem.swift b/iosApp/iosApp/Subviews/Residence/UserListItem.swift index 05dd0e7..2f4f78a 100644 --- a/iosApp/iosApp/Subviews/Residence/UserListItem.swift +++ b/iosApp/iosApp/Subviews/Residence/UserListItem.swift @@ -15,15 +15,16 @@ struct UserListItem: View { Text(user.username) .font(.body) .fontWeight(.medium) + .foregroundColor(Color.appTextPrimary) if isOwner { Text("Owner") .font(.caption) .fontWeight(.semibold) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) .padding(.horizontal, 6) .padding(.vertical, 2) - .background(Color.blue.opacity(0.1)) + .background(Color.appPrimary.opacity(0.1)) .cornerRadius(4) } } @@ -31,7 +32,7 @@ struct UserListItem: View { if !user.email.isEmpty { Text(user.email) .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } let fullName = [user.firstName, user.lastName] @@ -42,7 +43,7 @@ struct UserListItem: View { if !fullName.isEmpty { Text(fullName) .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } } @@ -51,12 +52,12 @@ struct UserListItem: View { if isPrimaryOwner && !isOwner { Button(action: onRemove) { Image(systemName: "trash") - .foregroundColor(.red) + .foregroundColor(Color.appError) } } } .padding() - .background(Color(.systemBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(12) .padding(.horizontal) } diff --git a/iosApp/iosApp/Subviews/Task/CompletionCardView.swift b/iosApp/iosApp/Subviews/Task/CompletionCardView.swift index 3b00d5c..71f5218 100644 --- a/iosApp/iosApp/Subviews/Task/CompletionCardView.swift +++ b/iosApp/iosApp/Subviews/Task/CompletionCardView.swift @@ -11,7 +11,7 @@ struct CompletionCardView: View { Text(formatDate(completion.completionDate)) .font(.caption) .fontWeight(.semibold) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) Spacer() @@ -23,10 +23,10 @@ struct CompletionCardView: View { .font(.caption) .fontWeight(.bold) } - .foregroundColor(.orange) + .foregroundColor(Color.appAccent) .padding(.horizontal, 8) .padding(.vertical, 4) - .background(Color.orange.opacity(0.1)) + .background(Color.appAccent.opacity(0.1)) .cornerRadius(6) } } @@ -36,38 +36,38 @@ struct CompletionCardView: View { HStack(alignment: .top, spacing: 6) { Image(systemName: "wrench.and.screwdriver") .font(.caption2) - .foregroundColor(.blue) + .foregroundColor(Color.appPrimary) VStack(alignment: .leading, spacing: 2) { Text("By: \(contractorDetails.name)") .font(.caption2) .fontWeight(.medium) - .foregroundColor(.primary) + .foregroundColor(Color.appTextPrimary) if let company = contractorDetails.company { Text(company) .font(.caption2) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } } } } else if let completedBy = completion.completedByName { Text("By: \(completedBy)") .font(.caption2) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } if let cost = completion.actualCost { Text("Cost: $\(cost)") .font(.caption2) - .foregroundColor(.green) + .foregroundColor(Color.appPrimary) .fontWeight(.medium) } if let notes = completion.notes { Text(notes) .font(.caption2) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) .lineLimit(2) } @@ -85,14 +85,14 @@ struct CompletionCardView: View { } .frame(maxWidth: .infinity) .padding(.vertical, 8) - .background(Color.blue.opacity(0.1)) - .foregroundColor(.blue) + .background(Color.appPrimary.opacity(0.1)) + .foregroundColor(Color.appPrimary) .cornerRadius(8) } } } .padding(12) - .background(Color(.systemGray6)) + .background(Color.appBackgroundSecondary.opacity(0.5)) .cornerRadius(8) .sheet(isPresented: $showPhotoSheet) { if let images = completion.images { diff --git a/iosApp/iosApp/Subviews/Task/DynamicTaskCard.swift b/iosApp/iosApp/Subviews/Task/DynamicTaskCard.swift index 9f6e852..0061456 100644 --- a/iosApp/iosApp/Subviews/Task/DynamicTaskCard.swift +++ b/iosApp/iosApp/Subviews/Task/DynamicTaskCard.swift @@ -38,21 +38,21 @@ struct DynamicTaskCard: View { if let description = task.description_, !description.isEmpty { Text(description) .font(.subheadline) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) .lineLimit(2) } HStack { Label(task.frequency.displayName, systemImage: "repeat") .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) Spacer() if let due_date = task.dueDate { Label(formatDate(due_date), systemImage: "calendar") .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } } @@ -62,15 +62,15 @@ struct DynamicTaskCard: View { VStack(alignment: .leading, spacing: 8) { HStack { Image(systemName: "checkmark.circle.fill") - .foregroundColor(.green) + .foregroundColor(Color.appAccent) Text("Completions (\(task.completions.count))") .font(.caption) .fontWeight(.semibold) - .foregroundColor(.primary) + .foregroundColor(Color.appTextPrimary) Spacer() Image(systemName: isCompletionsExpanded ? "chevron.up" : "chevron.down") .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } .contentShape(Rectangle()) .onTapGesture { @@ -102,12 +102,12 @@ struct DynamicTaskCard: View { } .frame(maxWidth: .infinity) .padding(.vertical, 12) - .background(Color.blue.opacity(0.1)) - .foregroundColor(.blue) + .background(Color.appPrimary.opacity(0.1)) + .foregroundColor(Color.appPrimary) .cornerRadius(8) .overlay( RoundedRectangle(cornerRadius: 8) - .stroke(Color.blue, lineWidth: 2) + .stroke(Color.appPrimary, lineWidth: 2) ) } .zIndex(10) @@ -115,7 +115,7 @@ struct DynamicTaskCard: View { } } .padding(16) - .background(Color(.secondarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(12) .shadow(color: Color.black.opacity(0.1), radius: 5, x: 0, y: 2) .simultaneousGesture(TapGesture(), including: .subviews) diff --git a/iosApp/iosApp/Subviews/Task/DynamicTaskColumnView.swift b/iosApp/iosApp/Subviews/Task/DynamicTaskColumnView.swift index bcced8a..b981902 100644 --- a/iosApp/iosApp/Subviews/Task/DynamicTaskColumnView.swift +++ b/iosApp/iosApp/Subviews/Task/DynamicTaskColumnView.swift @@ -18,7 +18,7 @@ struct DynamicTaskColumnView: View { } private var columnColor: Color { - Color(hex: column.color) ?? .primary + Color(hex: column.color) ?? Color.appTextPrimary } var body: some View { @@ -40,7 +40,7 @@ struct DynamicTaskColumnView: View { Text("\(column.count)") .font(.caption) .fontWeight(.semibold) - .foregroundColor(.white) + .foregroundColor(Color.appTextOnPrimary) .padding(.horizontal, 8) .padding(.vertical, 4) .background(columnColor) @@ -55,7 +55,7 @@ struct DynamicTaskColumnView: View { Text("No tasks") .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } .frame(maxWidth: .infinity) .padding(.top, 40) diff --git a/iosApp/iosApp/Subviews/Task/EmptyTasksView.swift b/iosApp/iosApp/Subviews/Task/EmptyTasksView.swift index a9fddd3..8d1b5cc 100644 --- a/iosApp/iosApp/Subviews/Task/EmptyTasksView.swift +++ b/iosApp/iosApp/Subviews/Task/EmptyTasksView.swift @@ -5,15 +5,15 @@ struct EmptyTasksView: View { VStack(spacing: 12) { Image(systemName: "checkmark.circle") .font(.system(size: 48)) - .foregroundColor(.gray.opacity(0.5)) + .foregroundColor(Color.appTextSecondary.opacity(0.5)) Text("No tasks yet") .font(.subheadline) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } .frame(maxWidth: .infinity) .padding(32) - .background(Color(.systemBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(12) } } diff --git a/iosApp/iosApp/Subviews/Task/PhotoViewerSheet.swift b/iosApp/iosApp/Subviews/Task/PhotoViewerSheet.swift index 3025640..e0eaf8a 100644 --- a/iosApp/iosApp/Subviews/Task/PhotoViewerSheet.swift +++ b/iosApp/iosApp/Subviews/Task/PhotoViewerSheet.swift @@ -32,9 +32,9 @@ struct PhotoViewerSheet: View { VStack { Image(systemName: "photo") .font(.system(size: 60)) - .foregroundColor(.gray) + .foregroundColor(Color.appTextSecondary) Text("Failed to load image") - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } .frame(height: 300) @unknown default: @@ -46,12 +46,14 @@ struct PhotoViewerSheet: View { VStack(alignment: .leading, spacing: 8) { Text("Caption") .font(.headline) + .foregroundColor(Color.appTextPrimary) Text(caption) .font(.body) + .foregroundColor(Color.appTextPrimary) } .frame(maxWidth: .infinity, alignment: .leading) .padding() - .background(Color(.systemGray6)) + .background(Color.appBackgroundSecondary) .cornerRadius(12) .padding(.horizontal) } @@ -104,10 +106,10 @@ struct PhotoViewerSheet: View { VStack { Image(systemName: "photo") .font(.system(size: 40)) - .foregroundColor(.gray) + .foregroundColor(Color.appTextSecondary) Text("Failed to load") .font(.caption2) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } .frame(height: 150) @unknown default: @@ -119,7 +121,7 @@ struct PhotoViewerSheet: View { if let caption = image.caption { Text(caption) .font(.caption2) - .foregroundColor(.primary) + .foregroundColor(Color.appTextPrimary) .lineLimit(2) .multilineTextAlignment(.leading) } diff --git a/iosApp/iosApp/Subviews/Task/PriorityBadge.swift b/iosApp/iosApp/Subviews/Task/PriorityBadge.swift index e789bfa..98bc1a2 100644 --- a/iosApp/iosApp/Subviews/Task/PriorityBadge.swift +++ b/iosApp/iosApp/Subviews/Task/PriorityBadge.swift @@ -21,10 +21,10 @@ struct PriorityBadge: View { private var priorityColor: Color { switch priority.lowercased() { - case "high": return .red - case "medium": return .orange - case "low": return .green - default: return Color(.tertiaryLabel) + case "high": return Color.appError + case "medium": return Color.appAccent + case "low": return Color.appPrimary + default: return Color.appTextSecondary.opacity(0.7) } } } @@ -36,5 +36,5 @@ struct PriorityBadge: View { PriorityBadge(priority: "low") } .padding() - .background(Color(.systemGroupedBackground)) + .background(Color.appBackgroundPrimary) } diff --git a/iosApp/iosApp/Subviews/Task/StatusBadge.swift b/iosApp/iosApp/Subviews/Task/StatusBadge.swift index b42fc83..7b3063c 100644 --- a/iosApp/iosApp/Subviews/Task/StatusBadge.swift +++ b/iosApp/iosApp/Subviews/Task/StatusBadge.swift @@ -24,11 +24,11 @@ struct StatusBadge: View { private var statusColor: Color { switch status { - case "completed": return .green - case "in_progress": return .orange - case "pending": return .orange - case "cancelled": return .red - default: return Color(.tertiaryLabel) + case "completed": return Color.appPrimary + case "in_progress": return Color.appAccent + case "pending": return Color.appAccent + case "cancelled": return Color.appError + default: return Color.appTextSecondary.opacity(0.7) } } } @@ -41,5 +41,5 @@ struct StatusBadge: View { StatusBadge(status: "cancelled") } .padding() - .background(Color(.systemGroupedBackground)) + .background(Color.appBackgroundPrimary) } diff --git a/iosApp/iosApp/Subviews/Task/TaskActionButtons.swift b/iosApp/iosApp/Subviews/Task/TaskActionButtons.swift index c6d5d12..72f62a9 100644 --- a/iosApp/iosApp/Subviews/Task/TaskActionButtons.swift +++ b/iosApp/iosApp/Subviews/Task/TaskActionButtons.swift @@ -38,7 +38,7 @@ struct CancelTaskButton: View { .frame(maxWidth: .infinity) } .buttonStyle(.bordered) - .tint(.red) + .tint(Color.appError) .alert("Cancel Task", isPresented: $showConfirmation) { Button("Cancel", role: .cancel) { } Button("Cancel Task", role: .destructive) { @@ -79,7 +79,7 @@ struct UncancelTaskButton: View { .frame(maxWidth: .infinity) } .buttonStyle(.borderedProminent) - .tint(.blue) + .tint(Color.appPrimary) } } @@ -111,7 +111,7 @@ struct MarkInProgressButton: View { .frame(maxWidth: .infinity) } .buttonStyle(.bordered) - .tint(.orange) + .tint(Color.appAccent) } } @@ -198,6 +198,6 @@ struct UnarchiveTaskButton: View { .frame(maxWidth: .infinity) } .buttonStyle(.bordered) - .tint(.blue) + .tint(Color.appPrimary) } } diff --git a/iosApp/iosApp/Subviews/Task/TaskCard.swift b/iosApp/iosApp/Subviews/Task/TaskCard.swift index 759f92a..fc3f05f 100644 --- a/iosApp/iosApp/Subviews/Task/TaskCard.swift +++ b/iosApp/iosApp/Subviews/Task/TaskCard.swift @@ -20,7 +20,7 @@ struct TaskCard: View { VStack(alignment: .leading, spacing: AppSpacing.xs) { Text(task.title) .font(.title3.weight(.semibold)) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) .lineLimit(2) if let status = task.status { @@ -37,7 +37,7 @@ struct TaskCard: View { if let description = task.description_, !description.isEmpty { Text(description) .font(.callout) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) .lineLimit(3) } @@ -46,14 +46,14 @@ struct TaskCard: View { HStack(spacing: AppSpacing.xxs) { Image(systemName: "repeat") .font(.system(size: 12, weight: .medium)) - .foregroundColor(Color(.tertiaryLabel)) + .foregroundColor(Color.appTextSecondary.opacity(0.7)) Text(task.frequency.displayName) .font(.caption.weight(.medium)) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } .padding(.horizontal, AppSpacing.sm) .padding(.vertical, AppSpacing.xxs) - .background(Color(.tertiarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.xs) Spacer() @@ -62,14 +62,14 @@ struct TaskCard: View { HStack(spacing: AppSpacing.xxs) { Image(systemName: "calendar") .font(.system(size: 12, weight: .medium)) - .foregroundColor(Color(.tertiaryLabel)) + .foregroundColor(Color.appTextSecondary.opacity(0.7)) Text(formatDate(dueDate)) .font(.caption.weight(.medium)) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } .padding(.horizontal, AppSpacing.sm) .padding(.vertical, AppSpacing.xxs) - .background(Color(.tertiarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.xs) } } @@ -83,20 +83,20 @@ struct TaskCard: View { HStack(spacing: AppSpacing.xs) { ZStack { Circle() - .fill(Color.green.opacity(0.1)) + .fill(Color.appAccent.opacity(0.1)) .frame(width: 24, height: 24) Image(systemName: "checkmark.circle.fill") .font(.system(size: 14, weight: .semibold)) - .foregroundColor(.green) + .foregroundColor(Color.appAccent) } Text("Completions (\(task.completions.count))") .font(.footnote.weight(.medium)) .fontWeight(.semibold) - .foregroundColor(Color(.label)) + .foregroundColor(Color.appTextPrimary) Spacer() Image(systemName: isCompletionsExpanded ? "chevron.up" : "chevron.down") .font(.caption) - .foregroundColor(Color(.secondaryLabel)) + .foregroundColor(Color.appTextSecondary) } .contentShape(Rectangle()) .onTapGesture { @@ -127,8 +127,8 @@ struct TaskCard: View { } .frame(maxWidth: .infinity) .frame(height: 44) - .foregroundColor(.orange) - .background(Color.orange.opacity(0.1)) + .foregroundColor(Color.appAccent) + .background(Color.appAccent.opacity(0.1)) .cornerRadius(AppRadius.md) } } @@ -144,8 +144,8 @@ struct TaskCard: View { } .frame(maxWidth: .infinity) .frame(height: 44) - .foregroundColor(.white) - .background(.green) + .foregroundColor(Color.appTextOnPrimary) + .background(Color.appPrimary) .cornerRadius(AppRadius.md) } } @@ -164,8 +164,8 @@ struct TaskCard: View { } .frame(maxWidth: .infinity) .frame(height: 36) - .foregroundColor(.blue) - .background(Color(.tertiarySystemGroupedBackground)) + .foregroundColor(Color.appPrimary) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.sm) } @@ -179,8 +179,8 @@ struct TaskCard: View { } .frame(maxWidth: .infinity) .frame(height: 36) - .foregroundColor(.red) - .background(Color.red.opacity(0.1)) + .foregroundColor(Color.appError) + .background(Color.appError.opacity(0.1)) .cornerRadius(AppRadius.sm) } } else if let onUncancel = onUncancel { @@ -193,8 +193,8 @@ struct TaskCard: View { } .frame(maxWidth: .infinity) .frame(height: 36) - .foregroundColor(.white) - .background(.blue) + .foregroundColor(Color.appTextOnPrimary) + .background(Color.appPrimary) .cornerRadius(AppRadius.sm) } } @@ -211,8 +211,8 @@ struct TaskCard: View { } .frame(maxWidth: .infinity) .frame(height: 36) - .foregroundColor(.blue) - .background(Color(.tertiarySystemGroupedBackground)) + .foregroundColor(Color.appPrimary) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.sm) } } @@ -227,8 +227,8 @@ struct TaskCard: View { } .frame(maxWidth: .infinity) .frame(height: 36) - .foregroundColor(Color(.secondaryLabel)) - .background(Color(.tertiarySystemGroupedBackground)) + .foregroundColor(Color.appTextSecondary) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.sm) } } @@ -236,7 +236,7 @@ struct TaskCard: View { } } .padding(AppSpacing.md) - .background(Color(.secondarySystemGroupedBackground)) + .background(Color.appBackgroundSecondary) .cornerRadius(AppRadius.lg) .shadow(color: AppShadow.md.color, radius: AppShadow.md.radius, x: AppShadow.md.x, y: AppShadow.md.y) } @@ -287,5 +287,5 @@ struct TaskCard: View { ) } .padding() - .background(Color(.systemGroupedBackground)) + .background(Color.appBackgroundPrimary) } diff --git a/iosApp/iosApp/Subviews/Task/TaskPill.swift b/iosApp/iosApp/Subviews/Task/TaskPill.swift index 7980fe6..45c54fd 100644 --- a/iosApp/iosApp/Subviews/Task/TaskPill.swift +++ b/iosApp/iosApp/Subviews/Task/TaskPill.swift @@ -24,9 +24,9 @@ struct TaskPill: View { #Preview { HStack(spacing: 8) { - TaskPill(count: 12, label: "Total", color: .blue) - TaskPill(count: 5, label: "Pending", color: .orange) - TaskPill(count: 3, label: "Done", color: .green) + TaskPill(count: 12, label: "Total", color: Color.appPrimary) + TaskPill(count: 5, label: "Pending", color: Color.appAccent) + TaskPill(count: 3, label: "Done", color: Color.appPrimary) } .padding() } diff --git a/iosApp/iosApp/Subviews/Task/TasksSection.swift b/iosApp/iosApp/Subviews/Task/TasksSection.swift index c1a76c1..5185cc1 100644 --- a/iosApp/iosApp/Subviews/Task/TasksSection.swift +++ b/iosApp/iosApp/Subviews/Task/TasksSection.swift @@ -20,6 +20,7 @@ struct TasksSection: View { Text("Tasks") .font(.title2) .fontWeight(.bold) + .foregroundColor(Color.appTextPrimary) if hasNoTasks { EmptyTasksView() diff --git a/iosApp/iosApp/Task/AllTasksView.swift b/iosApp/iosApp/Task/AllTasksView.swift index 43c99d1..d48d805 100644 --- a/iosApp/iosApp/Task/AllTasksView.swift +++ b/iosApp/iosApp/Task/AllTasksView.swift @@ -99,7 +99,7 @@ struct AllTasksView: View { @ViewBuilder private var mainContent: some View { ZStack { - Color(.systemGroupedBackground) + Color.appBackgroundPrimary .ignoresSafeArea() if hasNoTasks && isLoadingTasks { @@ -113,18 +113,19 @@ struct AllTasksView: View { // Empty state with big button VStack(spacing: 24) { Spacer() - + Image(systemName: "checklist") .font(.system(size: 64)) - .foregroundStyle(.blue.opacity(0.6)) - + .foregroundStyle(Color.appPrimary.opacity(0.6)) + Text("No tasks yet") .font(.title2) .fontWeight(.semibold) - + .foregroundColor(Color.appTextPrimary) + Text("Create your first task to get started") .font(.body) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) .multilineTextAlignment(.center) Button(action: { @@ -147,7 +148,7 @@ struct AllTasksView: View { if residenceViewModel.myResidences?.residences.isEmpty ?? true { Text("Add a property first from the Residences tab") .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } Spacer() @@ -216,6 +217,8 @@ struct AllTasksView: View { } } } + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationTitle("All Tasks") .navigationBarTitleDisplayMode(.inline) .toolbar { diff --git a/iosApp/iosApp/Task/CompleteTaskView.swift b/iosApp/iosApp/Task/CompleteTaskView.swift index fa267b1..350ab2f 100644 --- a/iosApp/iosApp/Task/CompleteTaskView.swift +++ b/iosApp/iosApp/Task/CompleteTaskView.swift @@ -52,6 +52,7 @@ struct CompleteTaskView: View { } header: { Text("Task Details") } + .listRowBackground(Color.appBackgroundSecondary) // Contractor Selection Section Section { @@ -89,6 +90,7 @@ struct CompleteTaskView: View { } footer: { Text("Select a contractor if they completed this work, or leave blank for manual entry.") } + .listRowBackground(Color.appBackgroundSecondary) // Completion Details Section Section { @@ -117,6 +119,7 @@ struct CompleteTaskView: View { } footer: { Text("Add any additional details about completing this task.") } + .listRowBackground(Color.appBackgroundSecondary) // Notes Section Section { @@ -132,6 +135,7 @@ struct CompleteTaskView: View { } footer: { Text("Optional notes about the work completed.") } + .listRowBackground(Color.appBackgroundSecondary) // Rating Section Section { @@ -165,6 +169,7 @@ struct CompleteTaskView: View { } footer: { Text("Rate the quality of work from 1 to 5 stars.") } + .listRowBackground(Color.appBackgroundSecondary) // Images Section Section { @@ -175,7 +180,7 @@ struct CompleteTaskView: View { }) { Label("Take Photo", systemImage: "camera") .frame(maxWidth: .infinity) - .foregroundStyle(.blue) + .foregroundStyle(Color.appPrimary) } .buttonStyle(.bordered) @@ -187,7 +192,7 @@ struct CompleteTaskView: View { ) { Label("Library", systemImage: "photo.on.rectangle.angled") .frame(maxWidth: .infinity) - .foregroundStyle(.blue) + .foregroundStyle(Color.appPrimary) } .buttonStyle(.bordered) } @@ -228,6 +233,7 @@ struct CompleteTaskView: View { } footer: { Text("Add up to 5 photos documenting the completed work.") } + .listRowBackground(Color.appBackgroundSecondary) // Complete Button Section Section { @@ -243,11 +249,14 @@ struct CompleteTaskView: View { .frame(maxWidth: .infinity) .fontWeight(.semibold) } - .listRowBackground(isSubmitting ? Color.gray : Color.green) - .foregroundStyle(.white) + .listRowBackground(isSubmitting ? Color.gray : Color.appPrimary) + .foregroundStyle(Color.appTextOnPrimary) .disabled(isSubmitting) } } + .listStyle(.plain) + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationTitle("Complete Task") .navigationBarTitleDisplayMode(.inline) .toolbar { @@ -397,7 +406,7 @@ struct ContractorPickerView: View { Spacer() if selectedContractor == nil { Image(systemName: "checkmark") - .foregroundStyle(.blue) + .foregroundStyle(Color.appPrimary) } } } @@ -411,7 +420,7 @@ struct ContractorPickerView: View { } } else if let errorMessage = contractorViewModel.errorMessage { Text(errorMessage) - .foregroundStyle(.red) + .foregroundStyle(Color.appError) .font(.caption) } else { ForEach(contractorViewModel.contractors, id: \.id) { contractor in @@ -445,7 +454,7 @@ struct ContractorPickerView: View { if selectedContractor?.id == contractor.id { Image(systemName: "checkmark") - .foregroundStyle(.blue) + .foregroundStyle(Color.appPrimary) } } } diff --git a/iosApp/iosApp/Task/TaskFormView.swift b/iosApp/iosApp/Task/TaskFormView.swift index d4b8d81..113e6be 100644 --- a/iosApp/iosApp/Task/TaskFormView.swift +++ b/iosApp/iosApp/Task/TaskFormView.swift @@ -107,15 +107,16 @@ struct TaskFormView: View { if !residenceError.isEmpty { Text(residenceError) .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } } header: { Text("Property") } footer: { Text("Required") .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } + .listRowBackground(Color.appBackgroundSecondary) } Section { @@ -125,7 +126,7 @@ struct TaskFormView: View { if !titleError.isEmpty { Text(titleError) .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } TextField("Description (optional)", text: $description, axis: .vertical) @@ -136,8 +137,9 @@ struct TaskFormView: View { } footer: { Text("Required: Title") .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } + .listRowBackground(Color.appBackgroundSecondary) Section { Picker("Category", selection: $selectedCategory) { @@ -151,8 +153,9 @@ struct TaskFormView: View { } footer: { Text("Required") .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } + .listRowBackground(Color.appBackgroundSecondary) Section { Picker("Frequency", selection: $selectedFrequency) { @@ -174,8 +177,9 @@ struct TaskFormView: View { } footer: { Text("Required: Frequency") .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } + .listRowBackground(Color.appBackgroundSecondary) Section { Picker("Priority", selection: $selectedPriority) { @@ -196,21 +200,24 @@ struct TaskFormView: View { } footer: { Text("Required: Both Priority and Status") .font(.caption) - .foregroundColor(.red) + .foregroundColor(Color.appError) } + .listRowBackground(Color.appBackgroundSecondary) Section(header: Text("Cost")) { TextField("Estimated Cost (optional)", text: $estimatedCost) .keyboardType(.decimalPad) .focused($focusedField, equals: .estimatedCost) } + .listRowBackground(Color.appBackgroundSecondary) if let errorMessage = viewModel.errorMessage { Section { Text(errorMessage) - .foregroundColor(.red) + .foregroundColor(Color.appError) .font(.caption) } + .listRowBackground(Color.appBackgroundSecondary) } } .disabled(isLoadingLookups) @@ -221,12 +228,15 @@ struct TaskFormView: View { ProgressView() .scaleEffect(1.5) Text("Loading...") - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) } .frame(maxWidth: .infinity, maxHeight: .infinity) - .background(Color(uiColor: .systemBackground).opacity(0.8)) + .background(Color.appBackgroundPrimary.opacity(0.8)) } } + .listStyle(.plain) + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationTitle(isEditMode ? "Edit Task" : "Add Task") .navigationBarTitleDisplayMode(.inline) .toolbar { diff --git a/iosApp/iosApp/VerifyEmail/VerifyEmailView.swift b/iosApp/iosApp/VerifyEmail/VerifyEmailView.swift index 9652e94..09e935f 100644 --- a/iosApp/iosApp/VerifyEmail/VerifyEmailView.swift +++ b/iosApp/iosApp/VerifyEmail/VerifyEmailView.swift @@ -9,7 +9,7 @@ struct VerifyEmailView: View { var body: some View { NavigationView { ZStack { - Color(.systemGroupedBackground) + Color.appBackgroundPrimary .ignoresSafeArea() ScrollView { @@ -20,16 +20,17 @@ struct VerifyEmailView: View { VStack(spacing: 12) { Image(systemName: "envelope.badge.shield.half.filled") .font(.system(size: 60)) - .foregroundStyle(.blue.gradient) + .foregroundStyle(Color.appPrimary.gradient) .padding(.bottom, 8) Text("Verify Your Email") .font(.title) .fontWeight(.bold) + .foregroundColor(Color.appTextPrimary) Text("You must verify your email address to continue") .font(.subheadline) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) .multilineTextAlignment(.center) .padding(.horizontal) } @@ -38,12 +39,12 @@ struct VerifyEmailView: View { GroupBox { HStack(spacing: 12) { Image(systemName: "exclamationmark.shield.fill") - .foregroundColor(.orange) + .foregroundColor(Color.appAccent) .font(.title2) Text("Email verification is required. Check your inbox for a 6-digit code.") .font(.subheadline) - .foregroundColor(.primary) + .foregroundColor(Color.appTextPrimary) .fontWeight(.semibold) } .padding(.vertical, 4) @@ -54,6 +55,7 @@ struct VerifyEmailView: View { VStack(alignment: .leading, spacing: 12) { Text("Verification Code") .font(.headline) + .foregroundColor(Color.appTextPrimary) .padding(.horizontal) TextField("000000", text: $viewModel.code) @@ -75,7 +77,7 @@ struct VerifyEmailView: View { Text("Code must be 6 digits") .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) .padding(.horizontal) } @@ -103,10 +105,10 @@ struct VerifyEmailView: View { .frame(height: 50) .background( viewModel.code.count == 6 && !viewModel.isLoading - ? Color.blue + ? Color.appPrimary : Color.gray.opacity(0.3) ) - .foregroundColor(.white) + .foregroundColor(Color.appTextOnPrimary) .cornerRadius(12) } .disabled(viewModel.code.count != 6 || viewModel.isLoading) @@ -117,12 +119,15 @@ struct VerifyEmailView: View { // Help Text Text("Didn't receive the code? Check your spam folder or contact support.") .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(Color.appTextSecondary) .multilineTextAlignment(.center) .padding(.horizontal, 32) } } } + .listStyle(.plain) + .scrollContentBackground(.hidden) + .background(Color.appBackgroundPrimary) .navigationBarTitleDisplayMode(.inline) .navigationBarBackButtonHidden(true) .interactiveDismissDisabled(true)