diff --git a/composeApp/src/commonMain/kotlin/com/example/mycrib/ui/screens/DocumentsScreen.kt b/composeApp/src/commonMain/kotlin/com/example/mycrib/ui/screens/DocumentsScreen.kt
index 99837a2..f490273 100644
--- a/composeApp/src/commonMain/kotlin/com/example/mycrib/ui/screens/DocumentsScreen.kt
+++ b/composeApp/src/commonMain/kotlin/com/example/mycrib/ui/screens/DocumentsScreen.kt
@@ -77,7 +77,7 @@ fun DocumentsScreen(
Icon(
if (showActiveOnly) Icons.Default.CheckCircle else Icons.Default.CheckCircleOutline,
"Filter active",
- tint = if (showActiveOnly) Color(0xFF10B981) else LocalContentColor.current
+ tint = if (showActiveOnly) MaterialTheme.colorScheme.secondary else LocalContentColor.current
)
}
}
@@ -89,7 +89,7 @@ fun DocumentsScreen(
Icons.Default.FilterList,
"Filters",
tint = if (selectedCategory != null || selectedDocType != null)
- Color(0xFF3B82F6) else LocalContentColor.current
+ MaterialTheme.colorScheme.primary else LocalContentColor.current
)
}
diff --git a/iosApp/MyCribExtension.entitlements b/iosApp/MyCribExtension.entitlements
index 52e1157..b513af7 100644
--- a/iosApp/MyCribExtension.entitlements
+++ b/iosApp/MyCribExtension.entitlements
@@ -4,7 +4,7 @@
com.apple.security.application-groups
- group.com.tt.mycrib.MyCrib
+ group.com.tt.mycrib.MyCribDev
diff --git a/iosApp/iosApp.xcodeproj/project.pbxproj b/iosApp/iosApp.xcodeproj/project.pbxproj
index d4a69b9..6bb7ff5 100644
--- a/iosApp/iosApp.xcodeproj/project.pbxproj
+++ b/iosApp/iosApp.xcodeproj/project.pbxproj
@@ -394,7 +394,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- PRODUCT_BUNDLE_IDENTIFIER = com.tt.mycrib.MyCrib;
+ PRODUCT_BUNDLE_IDENTIFIER = com.tt.mycrib.MyCribDev;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -423,7 +423,7 @@
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.tt.mycrib.MyCrib.MyCrib;
+ PRODUCT_BUNDLE_IDENTIFIER = com.tt.mycrib.MyCribDev.MyCribDev;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -457,7 +457,7 @@
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.tt.mycrib.MyCrib.MyCrib;
+ PRODUCT_BUNDLE_IDENTIFIER = com.tt.mycrib.MyCribDev.MyCribDev;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -663,7 +663,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- PRODUCT_BUNDLE_IDENTIFIER = com.tt.mycrib.MyCrib;
+ PRODUCT_BUNDLE_IDENTIFIER = com.tt.mycrib.MyCribDev;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
diff --git a/iosApp/iosApp/Contractor/ContractorCard.swift b/iosApp/iosApp/Contractor/ContractorCard.swift
index bc26bca..c9e3db5 100644
--- a/iosApp/iosApp/Contractor/ContractorCard.swift
+++ b/iosApp/iosApp/Contractor/ContractorCard.swift
@@ -10,12 +10,12 @@ struct ContractorCard: View {
// Avatar
ZStack {
Circle()
- .fill(AppColors.primary.opacity(0.1))
+ .fill(.blue.opacity(0.1))
.frame(width: 56, height: 56)
Image(systemName: "person.fill")
.font(.title2)
- .foregroundColor(AppColors.primary)
+ .foregroundColor(.blue)
}
// Content
@@ -24,13 +24,13 @@ struct ContractorCard: View {
HStack(spacing: AppSpacing.xxs) {
Text(contractor.name)
.font(.title3.weight(.semibold))
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
.lineLimit(1)
if contractor.isFavorite {
Image(systemName: "star.fill")
.font(.caption)
- .foregroundColor(AppColors.warning)
+ .foregroundColor(.orange)
}
}
@@ -38,7 +38,7 @@ struct ContractorCard: View {
if let company = contractor.company {
Text(company)
.font(.body)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
.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(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
// Rating
if let rating = contractor.averageRating, rating.doubleValue > 0 {
Label(String(format: "%.1f", rating.doubleValue), systemImage: "star.fill")
.font(.caption.weight(.medium))
- .foregroundColor(AppColors.warning)
+ .foregroundColor(.orange)
}
// Task count
if contractor.taskCount > 0 {
Label("\(contractor.taskCount) tasks", systemImage: "checkmark.circle")
.font(.caption.weight(.medium))
- .foregroundColor(AppColors.success)
+ .foregroundColor(.green)
}
}
}
@@ -73,17 +73,17 @@ struct ContractorCard: View {
Button(action: onToggleFavorite) {
Image(systemName: contractor.isFavorite ? "star.fill" : "star")
.font(.title3)
- .foregroundColor(contractor.isFavorite ? AppColors.warning : AppColors.textTertiary)
+ .foregroundColor(contractor.isFavorite ? .orange : Color(.tertiaryLabel))
}
.buttonStyle(PlainButtonStyle())
// Chevron
Image(systemName: "chevron.right")
.font(.caption)
- .foregroundColor(AppColors.textTertiary)
+ .foregroundColor(Color(.tertiaryLabel))
}
.padding(AppSpacing.md)
- .background(AppColors.surface)
+ .background(Color(.secondarySystemGroupedBackground))
.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 2691c59..2fd4a62 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 {
- AppColors.background.ignoresSafeArea()
+ Color(.systemGroupedBackground).ignoresSafeArea()
if viewModel.isLoading {
ProgressView()
@@ -29,24 +29,24 @@ struct ContractorDetailView: View {
// Avatar
ZStack {
Circle()
- .fill(AppColors.primary.opacity(0.1))
+ .fill(.blue.opacity(0.1))
.frame(width: 80, height: 80)
Image(systemName: "person.fill")
.font(.system(size: 40))
- .foregroundColor(AppColors.primary)
+ .foregroundColor(.blue)
}
// Name
Text(contractor.name)
.font(.title3.weight(.semibold))
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
// Company
if let company = contractor.company {
Text(company)
.font(.title3.weight(.semibold))
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
// Specialty Badge
@@ -59,8 +59,8 @@ struct ContractorDetailView: View {
}
.padding(.horizontal, AppSpacing.sm)
.padding(.vertical, AppSpacing.xxs)
- .background(AppColors.primary.opacity(0.1))
- .foregroundColor(AppColors.primary)
+ .background(.blue.opacity(0.1))
+ .foregroundColor(.blue)
.cornerRadius(AppRadius.full)
}
@@ -69,41 +69,41 @@ struct ContractorDetailView: View {
HStack(spacing: AppSpacing.xxs) {
ForEach(0..<5) { index in
Image(systemName: index < Int(rating.doubleValue) ? "star.fill" : "star")
- .foregroundColor(AppColors.warning)
+ .foregroundColor(.orange)
.font(.caption)
}
Text(String(format: "%.1f", rating.doubleValue))
.font(.title3.weight(.semibold))
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
}
if contractor.taskCount > 0 {
Text("\(contractor.taskCount) completed tasks")
.font(.callout)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
}
}
.padding(AppSpacing.lg)
.frame(maxWidth: .infinity)
- .background(AppColors.surface)
+ .background(Color(.secondarySystemGroupedBackground))
.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") {
- DetailRow(icon: "phone", label: "Phone", value: contractor.phone, iconColor: AppColors.primary)
+ DetailRow(icon: "phone", label: "Phone", value: contractor.phone, iconColor: .blue)
if let email = contractor.email {
- DetailRow(icon: "envelope", label: "Email", value: email, iconColor: AppColors.accent)
+ DetailRow(icon: "envelope", label: "Email", value: email, iconColor: .purple)
}
if let secondaryPhone = contractor.secondaryPhone {
- DetailRow(icon: "phone", label: "Secondary Phone", value: secondaryPhone, iconColor: AppColors.success)
+ DetailRow(icon: "phone", label: "Secondary Phone", value: secondaryPhone, iconColor: .green)
}
if let website = contractor.website {
- DetailRow(icon: "globe", label: "Website", value: website, iconColor: AppColors.warning)
+ DetailRow(icon: "globe", label: "Website", value: website, iconColor: .orange)
}
}
@@ -111,7 +111,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: AppColors.primary)
+ DetailRow(icon: "doc.badge", label: "License Number", value: licenseNumber, iconColor: .blue)
}
}
}
@@ -130,7 +130,7 @@ struct ContractorDetailView: View {
icon: "mappin.circle",
label: "Location",
value: addressComponents.joined(separator: "\n"),
- iconColor: AppColors.error
+ iconColor: .red
)
}
}
@@ -141,7 +141,8 @@ struct ContractorDetailView: View {
DetailSection(title: "Notes") {
Text(notes)
.font(.body)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
+ .frame(maxWidth: .infinity, alignment: .leading)
.padding(AppSpacing.md)
}
}
@@ -150,11 +151,11 @@ struct ContractorDetailView: View {
DetailSection(title: "Task History") {
HStack {
Image(systemName: "checkmark.circle")
- .foregroundColor(AppColors.success)
+ .foregroundColor(.green)
Spacer()
Text("\(contractor.taskCount) completed tasks")
.font(.body)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
.padding(AppSpacing.md)
}
@@ -188,7 +189,7 @@ struct ContractorDetailView: View {
}
} label: {
Image(systemName: "ellipsis.circle")
- .foregroundColor(AppColors.primary)
+ .foregroundColor(.blue)
}
}
}
@@ -236,13 +237,13 @@ struct DetailSection: View {
VStack(alignment: .leading, spacing: AppSpacing.sm) {
Text(title)
.font(.headline)
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
.padding(.horizontal, AppSpacing.md)
VStack(spacing: 0) {
content()
}
- .background(AppColors.surface)
+ .background(Color(.secondarySystemGroupedBackground))
.cornerRadius(AppRadius.lg)
.shadow(color: AppShadow.sm.color, radius: AppShadow.sm.radius, x: AppShadow.sm.x, y: AppShadow.sm.y)
}
@@ -254,7 +255,7 @@ struct DetailRow: View {
let icon: String
let label: String
let value: String
- var iconColor: Color = AppColors.textSecondary
+ var iconColor: Color = Color(.secondaryLabel)
var body: some View {
HStack(alignment: .top, spacing: AppSpacing.sm) {
@@ -265,11 +266,11 @@ struct DetailRow: View {
VStack(alignment: .leading, spacing: AppSpacing.xxs) {
Text(label)
.font(.caption.weight(.medium))
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
Text(value)
.font(.body)
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
}
Spacer()
diff --git a/iosApp/iosApp/Contractor/ContractorFormSheet.swift b/iosApp/iosApp/Contractor/ContractorFormSheet.swift
index a1a1944..9c63460 100644
--- a/iosApp/iosApp/Contractor/ContractorFormSheet.swift
+++ b/iosApp/iosApp/Contractor/ContractorFormSheet.swift
@@ -47,38 +47,235 @@ struct ContractorFormSheet: View {
var body: some View {
NavigationStack {
- ZStack {
- AppColors.background.ignoresSafeArea()
-
- ScrollView {
- VStack(spacing: AppSpacing.lg) {
- basicInformationSection
- contactInformationSection
- businessDetailsSection
- addressSection
- notesSection
- favoriteToggle
- errorMessage
+ Form {
+ // Basic Information
+ Section {
+ HStack {
+ Image(systemName: "person")
+ .foregroundColor(.blue)
+ .frame(width: 24)
+ TextField("Name", text: $name)
+ .focused($focusedField, equals: .name)
+ }
+
+ HStack {
+ Image(systemName: "building.2")
+ .foregroundColor(.purple)
+ .frame(width: 24)
+ TextField("Company", text: $company)
+ .focused($focusedField, equals: .company)
+ }
+ } header: {
+ Text("Basic Information")
+ }
+
+ // Contact Information
+ Section {
+ HStack {
+ Image(systemName: "phone.fill")
+ .foregroundColor(.green)
+ .frame(width: 24)
+ TextField("Phone", text: $phone)
+ .keyboardType(.phonePad)
+ .focused($focusedField, equals: .phone)
+ }
+
+ HStack {
+ Image(systemName: "envelope.fill")
+ .foregroundColor(.orange)
+ .frame(width: 24)
+ TextField("Email", text: $email)
+ .keyboardType(.emailAddress)
+ .textInputAutocapitalization(.never)
+ .autocorrectionDisabled()
+ .focused($focusedField, equals: .email)
+ }
+
+ HStack {
+ Image(systemName: "phone.badge.plus")
+ .foregroundColor(.green)
+ .frame(width: 24)
+ TextField("Secondary Phone", text: $secondaryPhone)
+ .keyboardType(.phonePad)
+ .focused($focusedField, equals: .secondaryPhone)
+ }
+ } header: {
+ Text("Contact Information")
+ } footer: {
+ Text("Required: Name and Phone")
+ .font(.caption)
+ }
+
+ // Business Details
+ Section {
+ Button(action: { showingSpecialtyPicker = true }) {
+ HStack {
+ Image(systemName: "wrench.and.screwdriver")
+ .foregroundColor(.blue)
+ .frame(width: 24)
+ Text(specialty.isEmpty ? "Specialty" : specialty)
+ .foregroundColor(specialty.isEmpty ? Color(.placeholderText) : Color(.label))
+ Spacer()
+ Image(systemName: "chevron.down")
+ .font(.caption)
+ .foregroundColor(Color(.tertiaryLabel))
+ }
+ }
+
+ HStack {
+ Image(systemName: "doc.badge")
+ .foregroundColor(.purple)
+ .frame(width: 24)
+ TextField("License Number", text: $licenseNumber)
+ .focused($focusedField, equals: .licenseNumber)
+ }
+
+ HStack {
+ Image(systemName: "globe")
+ .foregroundColor(.blue)
+ .frame(width: 24)
+ TextField("Website", text: $website)
+ .keyboardType(.URL)
+ .textInputAutocapitalization(.never)
+ .autocorrectionDisabled()
+ .focused($focusedField, equals: .website)
+ }
+ } header: {
+ Text("Business Details")
+ }
+
+ // Address
+ Section {
+ HStack {
+ Image(systemName: "location.fill")
+ .foregroundColor(.red)
+ .frame(width: 24)
+ TextField("Street Address", text: $address)
+ .focused($focusedField, equals: .address)
+ }
+
+ HStack {
+ Image(systemName: "building.2.crop.circle")
+ .foregroundColor(.blue)
+ .frame(width: 24)
+ TextField("City", text: $city)
+ .focused($focusedField, equals: .city)
+ }
+
+ HStack(spacing: AppSpacing.sm) {
+ HStack {
+ Image(systemName: "map")
+ .foregroundColor(.green)
+ .frame(width: 24)
+ TextField("State", text: $state)
+ .focused($focusedField, equals: .state)
+ }
+
+ Divider()
+ .frame(height: 24)
+
+ TextField("ZIP", text: $zipCode)
+ .keyboardType(.numberPad)
+ .focused($focusedField, equals: .zipCode)
+ .frame(maxWidth: 100)
+ }
+ } header: {
+ Text("Address")
+ }
+
+ // Notes
+ Section {
+ HStack(alignment: .top) {
+ Image(systemName: "note.text")
+ .foregroundColor(.orange)
+ .frame(width: 24)
+ .padding(.top, 8)
+
+ TextEditor(text: $notes)
+ .frame(height: 100)
+ .focused($focusedField, equals: .notes)
+ }
+ } header: {
+ Text("Notes")
+ } footer: {
+ Text("Private notes about this contractor")
+ .font(.caption)
+ }
+
+ // Favorite
+ Section {
+ Toggle(isOn: $isFavorite) {
+ Label("Mark as Favorite", systemImage: "star.fill")
+ .foregroundColor(isFavorite ? .orange : Color(.label))
+ }
+ .tint(.orange)
+ }
+
+ // Error Message
+ if let error = viewModel.errorMessage {
+ Section {
+ HStack {
+ Image(systemName: "exclamationmark.triangle.fill")
+ .foregroundColor(.red)
+ Text(error)
+ .font(.callout)
+ .foregroundColor(.red)
+ }
}
- .padding(AppSpacing.md)
}
}
.navigationTitle(contractor == nil ? "Add Contractor" : "Edit Contractor")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
- ToolbarItem(placement: .navigationBarLeading) {
- cancelButton
+ ToolbarItem(placement: .cancellationAction) {
+ Button("Cancel") {
+ dismiss()
+ }
}
- ToolbarItem(placement: .navigationBarTrailing) {
- saveButton
+ ToolbarItem(placement: .confirmationAction) {
+ Button(action: saveContractor) {
+ if viewModel.isCreating || viewModel.isUpdating {
+ ProgressView()
+ } else {
+ Text(contractor == nil ? "Add" : "Save")
+ .bold()
+ }
+ }
+ .disabled(!canSave || viewModel.isCreating || viewModel.isUpdating)
}
}
.sheet(isPresented: $showingSpecialtyPicker) {
- SpecialtyPickerView(
- selectedSpecialty: $specialty,
- specialties: specialties
- )
+ NavigationStack {
+ List {
+ ForEach(specialties, id: \.self) { spec in
+ Button(action: {
+ specialty = spec
+ showingSpecialtyPicker = false
+ }) {
+ HStack {
+ Text(spec)
+ .foregroundColor(Color(.label))
+ Spacer()
+ if specialty == spec {
+ Image(systemName: "checkmark")
+ .foregroundColor(.blue)
+ }
+ }
+ }
+ }
+ }
+ .navigationTitle("Select Specialty")
+ .navigationBarTitleDisplayMode(.inline)
+ .toolbar {
+ ToolbarItem(placement: .confirmationAction) {
+ Button("Done") {
+ showingSpecialtyPicker = false
+ }
+ }
+ }
+ }
+ .presentationDetents([.medium, .large])
}
.onAppear {
loadContractorData()
@@ -87,229 +284,6 @@ struct ContractorFormSheet: View {
}
}
- // MARK: - Toolbar Items
-
- private var cancelButton: some View {
- Button("Cancel") {
- dismiss()
- }
- .foregroundColor(AppColors.textSecondary)
- }
-
- private var saveButton: some View {
- Button(action: saveContractor) {
- if viewModel.isCreating || viewModel.isUpdating {
- ProgressView()
- } else {
- Text(contractor == nil ? "Add" : "Save")
- .foregroundColor(canSave ? AppColors.primary : AppColors.textTertiary)
- }
- }
- .disabled(!canSave || viewModel.isCreating || viewModel.isUpdating)
- }
-
- // MARK: - Form Sections
-
- private var basicInformationSection: some View {
- VStack(spacing: AppSpacing.sm) {
- SectionHeader(title: "Basic Information")
-
- FormTextField(
- title: "Name *",
- text: $name,
- icon: "person",
- focused: $focusedField,
- field: .name
- )
-
- FormTextField(
- title: "Company",
- text: $company,
- icon: "building.2",
- focused: $focusedField,
- field: .company
- )
- }
- }
-
- private var contactInformationSection: some View {
- VStack(spacing: AppSpacing.sm) {
- SectionHeader(title: "Contact Information")
-
- FormTextField(
- title: "Phone *",
- text: $phone,
- icon: "phone",
- keyboardType: .phonePad,
- focused: $focusedField,
- field: .phone
- )
-
- FormTextField(
- title: "Email",
- text: $email,
- icon: "envelope",
- keyboardType: .emailAddress,
- focused: $focusedField,
- field: .email
- )
-
- FormTextField(
- title: "Secondary Phone",
- text: $secondaryPhone,
- icon: "phone",
- keyboardType: .phonePad,
- focused: $focusedField,
- field: .secondaryPhone
- )
- }
- }
-
- private var businessDetailsSection: some View {
- VStack(spacing: AppSpacing.sm) {
- SectionHeader(title: "Business Details")
-
- specialtyPickerButton
-
- FormTextField(
- title: "License Number",
- text: $licenseNumber,
- icon: "doc.badge",
- focused: $focusedField,
- field: .licenseNumber
- )
-
- FormTextField(
- title: "Website",
- text: $website,
- icon: "globe",
- keyboardType: .URL,
- focused: $focusedField,
- field: .website
- )
- }
- }
-
- private var specialtyPickerButton: some View {
- Button(action: { showingSpecialtyPicker = true }) {
- HStack {
- Image(systemName: "wrench.and.screwdriver")
- .foregroundColor(AppColors.textSecondary)
- .frame(width: 20)
-
- Text(specialty.isEmpty ? "Specialty" : specialty)
- .foregroundColor(specialty.isEmpty ? AppColors.textTertiary : AppColors.textPrimary)
-
- Spacer()
-
- Image(systemName: "chevron.down")
- .font(.caption)
- .foregroundColor(AppColors.textTertiary)
- }
- .padding(AppSpacing.md)
- .background(AppColors.surface)
- .cornerRadius(AppRadius.md)
- .overlay(
- RoundedRectangle(cornerRadius: AppRadius.md)
- .stroke(AppColors.border, lineWidth: 1)
- )
- }
- }
-
- private var addressSection: some View {
- VStack(spacing: AppSpacing.sm) {
- SectionHeader(title: "Address")
-
- FormTextField(
- title: "Street Address",
- text: $address,
- icon: "mappin",
- focused: $focusedField,
- field: .address
- )
-
- HStack(spacing: AppSpacing.sm) {
- FormTextField(
- title: "City",
- text: $city,
- focused: $focusedField,
- field: .city
- )
-
- FormTextField(
- title: "State",
- text: $state,
- focused: $focusedField,
- field: .state
- )
- .frame(maxWidth: 100)
- }
-
- FormTextField(
- title: "ZIP Code",
- text: $zipCode,
- keyboardType: .numberPad,
- focused: $focusedField,
- field: .zipCode
- )
- }
- }
-
- private var notesSection: some View {
- VStack(alignment: .leading, spacing: AppSpacing.xxs) {
- SectionHeader(title: "Notes")
-
- HStack {
- Image(systemName: "note.text")
- .foregroundColor(AppColors.textSecondary)
- .frame(width: 20)
-
- Text("Private Notes")
- .font(.footnote.weight(.medium))
- .foregroundColor(AppColors.textSecondary)
- }
-
- TextEditor(text: $notes)
- .frame(height: 100)
- .padding(AppSpacing.sm)
- .background(AppColors.surface)
- .cornerRadius(AppRadius.md)
- .overlay(
- RoundedRectangle(cornerRadius: AppRadius.md)
- .stroke(AppColors.border, lineWidth: 1)
- )
- .focused($focusedField, equals: .notes)
- }
- }
-
- private var favoriteToggle: some View {
- Toggle(isOn: $isFavorite) {
- HStack {
- Image(systemName: "star.fill")
- .foregroundColor(isFavorite ? AppColors.warning : AppColors.textSecondary)
- Text("Mark as Favorite")
- .font(.body)
- .foregroundColor(AppColors.textPrimary)
- }
- }
- .padding(AppSpacing.md)
- .background(AppColors.surface)
- .cornerRadius(AppRadius.md)
- }
-
- @ViewBuilder
- private var errorMessage: some View {
- if let error = viewModel.errorMessage {
- Text(error)
- .font(.callout)
- .foregroundColor(AppColors.error)
- .padding(AppSpacing.sm)
- .frame(maxWidth: .infinity)
- .background(AppColors.error.opacity(0.1))
- .cornerRadius(AppRadius.md)
- }
- }
-
// MARK: - Data Loading
private func loadContractorData() {
@@ -399,98 +373,3 @@ struct ContractorFormSheet: View {
}
}
}
-
-// MARK: - Section Header
-struct SectionHeader: View {
- let title: String
-
- var body: some View {
- HStack {
- Text(title)
- .font(.headline)
- .foregroundColor(AppColors.textPrimary)
- Spacer()
- }
- }
-}
-
-// MARK: - Form Text Field
-struct FormTextField: View {
- let title: String
- @Binding var text: String
- var icon: String? = nil
- var keyboardType: UIKeyboardType = .default
- var focused: FocusState.Binding
- var field: ContractorFormField
-
- var body: some View {
- VStack(alignment: .leading, spacing: AppSpacing.xxs) {
- if let icon = icon {
- HStack {
- Image(systemName: icon)
- .foregroundColor(AppColors.textSecondary)
- .frame(width: 20)
-
- Text(title)
- .font(.footnote.weight(.medium))
- .foregroundColor(AppColors.textSecondary)
- }
- } else {
- Text(title)
- .font(.footnote.weight(.medium))
- .foregroundColor(AppColors.textSecondary)
- }
-
- TextField("", text: $text)
- .keyboardType(keyboardType)
- .autocapitalization(keyboardType == .emailAddress ? .none : .words)
- .padding(AppSpacing.md)
- .background(AppColors.surface)
- .cornerRadius(AppRadius.md)
- .overlay(
- RoundedRectangle(cornerRadius: AppRadius.md)
- .stroke(AppColors.border, lineWidth: 1)
- )
- .focused(focused, equals: field)
- }
- }
-}
-
-// MARK: - Specialty Picker
-struct SpecialtyPickerView: View {
- @Environment(\.dismiss) private var dismiss
- @Binding var selectedSpecialty: String
- let specialties: [String]
-
- var body: some View {
- NavigationView {
- List {
- ForEach(specialties, id: \.self) { specialty in
- Button(action: {
- selectedSpecialty = specialty
- dismiss()
- }) {
- HStack {
- Text(specialty)
- .foregroundColor(AppColors.textPrimary)
- Spacer()
- if selectedSpecialty == specialty {
- Image(systemName: "checkmark")
- .foregroundColor(AppColors.primary)
- }
- }
- }
- }
- }
- .navigationTitle("Select Specialty")
- .navigationBarTitleDisplayMode(.inline)
- .toolbar {
- ToolbarItem(placement: .navigationBarTrailing) {
- Button("Done") {
- dismiss()
- }
- }
- }
- }
- }
-}
diff --git a/iosApp/iosApp/Contractor/ContractorsListView.swift b/iosApp/iosApp/Contractor/ContractorsListView.swift
index d7b4b95..d398f07 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 {
- AppColors.background.ignoresSafeArea()
+ Color(.systemGroupedBackground).ignoresSafeArea()
VStack(spacing: 0) {
// Search Bar
@@ -115,7 +115,7 @@ struct ContractorsListView: View {
loadContractors()
}) {
Image(systemName: showFavoritesOnly ? "star.fill" : "star")
- .foregroundColor(showFavoritesOnly ? AppColors.warning : AppColors.textSecondary)
+ .foregroundColor(showFavoritesOnly ? .orange : Color(.secondaryLabel))
}
// Specialty Filter
@@ -139,14 +139,14 @@ struct ContractorsListView: View {
}
} label: {
Image(systemName: "line.3.horizontal.decrease.circle")
- .foregroundColor(selectedSpecialty != nil ? AppColors.primary : AppColors.textSecondary)
+ .foregroundColor(selectedSpecialty != nil ? .blue : Color(.secondaryLabel))
}
// Add Button
Button(action: { showingAddSheet = true }) {
Image(systemName: "plus.circle.fill")
.font(.title2)
- .foregroundColor(AppColors.primary)
+ .foregroundColor(.blue)
}
}
}
@@ -201,7 +201,7 @@ struct SearchBar: View {
var body: some View {
HStack(spacing: AppSpacing.sm) {
Image(systemName: "magnifyingglass")
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
TextField(placeholder, text: $text)
.font(.body)
@@ -209,12 +209,12 @@ struct SearchBar: View {
if !text.isEmpty {
Button(action: { text = "" }) {
Image(systemName: "xmark.circle.fill")
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
}
}
.padding(AppSpacing.sm)
- .background(AppColors.surface)
+ .background(Color(.secondarySystemGroupedBackground))
.cornerRadius(AppRadius.md)
.shadow(color: AppShadow.sm.color, radius: AppShadow.sm.radius, x: AppShadow.sm.x, y: AppShadow.sm.y)
}
@@ -242,8 +242,8 @@ struct FilterChip: View {
}
.padding(.horizontal, AppSpacing.sm)
.padding(.vertical, AppSpacing.xxs)
- .background(AppColors.primary.opacity(0.1))
- .foregroundColor(AppColors.primary)
+ .background(.blue.opacity(0.1))
+ .foregroundColor(.blue)
.cornerRadius(AppRadius.full)
}
}
@@ -256,16 +256,16 @@ struct EmptyContractorsView: View {
VStack(spacing: AppSpacing.md) {
Image(systemName: "person.badge.plus")
.font(.system(size: 64))
- .foregroundColor(AppColors.textTertiary)
+ .foregroundColor(Color(.tertiaryLabel))
Text(hasFilters ? "No contractors found" : "No contractors yet")
.font(.title3.weight(.semibold))
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
if !hasFilters {
Text("Add your first contractor to get started")
.font(.callout)
- .foregroundColor(AppColors.textTertiary)
+ .foregroundColor(Color(.tertiaryLabel))
}
}
.padding(AppSpacing.xl)
diff --git a/iosApp/iosApp/Design/DesignSystem.swift b/iosApp/iosApp/Design/DesignSystem.swift
index c449010..f60ea54 100644
--- a/iosApp/iosApp/Design/DesignSystem.swift
+++ b/iosApp/iosApp/Design/DesignSystem.swift
@@ -3,55 +3,6 @@ import SwiftUI
// MARK: - Design System
// Modern, sleek design system for MyCrib with Light and Dark mode support
-struct AppColors {
- // Primary Colors - Modern blue gradient
- static let primary = Color(hex: "2563EB") ?? .blue
- static let primaryLight = Color(hex: "3B82F6") ?? .blue
- static let primaryDark = Color(hex: "1E40AF") ?? .blue
-
- // Accent Colors
- static let accent = Color(hex: "8B5CF6") ?? .purple
- static let accentLight = Color(hex: "A78BFA") ?? .purple
-
- // Semantic Colors
- static let success = Color(hex: "10B981") ?? .green
- static let warning = Color(hex: "F59E0B") ?? .orange
- static let error = Color(hex: "EF4444") ?? .red
- static let info = Color(hex: "3B82F6") ?? .blue
-
- // Adaptive Neutral Colors - Automatically adapt to light/dark mode
- static let background = Color(uiColor: .systemGroupedBackground)
- static let surface = Color(uiColor: .secondarySystemGroupedBackground)
- static let surfaceSecondary = Color(uiColor: .tertiarySystemGroupedBackground)
-
- static let textPrimary = Color(uiColor: .label)
- static let textSecondary = Color(uiColor: .secondaryLabel)
- static let textTertiary = Color(uiColor: .tertiaryLabel)
-
- static let border = Color(uiColor: .separator)
- static let borderLight = Color(uiColor: .opaqueSeparator)
-
- // Task Status Colors
- static let taskUpcoming = Color(hex: "3B82F6") ?? .blue
- static let taskInProgress = Color(hex: "F59E0B") ?? .orange
- static let taskCompleted = Color(hex: "10B981") ?? .green
- static let taskCanceled = Color(hex: "6B7280") ?? .gray
- static let taskArchived = Color(hex: "9CA3AF") ?? .gray
-
- // Gradient
- static let primaryGradient = LinearGradient(
- colors: [primary, primaryLight],
- startPoint: .topLeading,
- endPoint: .bottomTrailing
- )
-
- static let accentGradient = LinearGradient(
- colors: [accent, accentLight],
- startPoint: .topLeading,
- endPoint: .bottomTrailing
- )
-}
-
struct AppSpacing {
static let xxs: CGFloat = 4
static let xs: CGFloat = 8
@@ -102,7 +53,7 @@ struct CardStyle: ViewModifier {
func body(content: Content) -> some View {
content
- .background(AppColors.surface)
+ .background(Color(.secondarySystemGroupedBackground))
.cornerRadius(AppRadius.lg)
.shadow(color: shadow.color, radius: shadow.radius, x: shadow.x, y: shadow.y)
}
@@ -118,7 +69,7 @@ struct PrimaryButtonStyle: ButtonStyle {
.frame(maxWidth: .infinity)
.frame(height: 56)
.background(
- configuration.isPressed ? AppColors.primaryDark : AppColors.primary
+ configuration.isPressed ? .blue : .blue
)
.cornerRadius(AppRadius.md)
.scaleEffect(configuration.isPressed ? 0.98 : 1.0)
@@ -130,10 +81,10 @@ struct SecondaryButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.font(.headline)
- .foregroundColor(AppColors.primary)
+ .foregroundColor(.blue)
.frame(maxWidth: .infinity)
.frame(height: 56)
- .background(AppColors.surfaceSecondary)
+ .background(Color(.tertiarySystemGroupedBackground))
.cornerRadius(AppRadius.md)
.scaleEffect(configuration.isPressed ? 0.98 : 1.0)
.animation(.easeInOut(duration: 0.1), value: configuration.isPressed)
@@ -144,11 +95,11 @@ struct TextFieldStyle: ViewModifier {
func body(content: Content) -> some View {
content
.padding(AppSpacing.md)
- .background(AppColors.surfaceSecondary)
+ .background(Color(.tertiarySystemGroupedBackground))
.cornerRadius(AppRadius.md)
.overlay(
RoundedRectangle(cornerRadius: AppRadius.md)
- .stroke(AppColors.borderLight, lineWidth: 1)
+ .stroke(Color(.opaqueSeparator), lineWidth: 1)
)
}
}
diff --git a/iosApp/iosApp/Documents/Components/DocumentCard.swift b/iosApp/iosApp/Documents/Components/DocumentCard.swift
index fce56d6..782673b 100644
--- a/iosApp/iosApp/Documents/Components/DocumentCard.swift
+++ b/iosApp/iosApp/Documents/Components/DocumentCard.swift
@@ -8,8 +8,8 @@ struct DocumentCard: View {
switch document.documentType {
case "warranty": return .blue
case "manual": return .purple
- case "receipt": return AppColors.success
- case "inspection": return AppColors.warning
+ case "receipt": return .green
+ case "inspection": return .orange
default: return .gray
}
}
@@ -41,13 +41,13 @@ struct DocumentCard: View {
Text(document.title)
.font(.title3.weight(.semibold))
.fontWeight(.bold)
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
.lineLimit(1)
if let description = document.description_, !description.isEmpty {
Text(description)
.font(.callout)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
.lineLimit(2)
}
@@ -63,7 +63,7 @@ struct DocumentCard: View {
if let fileSize = document.fileSize {
Text(formatFileSize(Int(fileSize)))
.font(.caption.weight(.medium))
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
}
}
@@ -71,11 +71,11 @@ struct DocumentCard: View {
Spacer()
Image(systemName: "chevron.right")
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
.font(.system(size: 14))
}
.padding(AppSpacing.md)
- .background(AppColors.surface)
+ .background(Color(.secondarySystemGroupedBackground))
.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 4ebde9e..eed9b74 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(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
Text(title)
.font(.title3.weight(.semibold))
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
Text(message)
.font(.body)
- .foregroundColor(AppColors.textTertiary)
+ .foregroundColor(Color(.tertiaryLabel))
.multilineTextAlignment(.center)
}
.padding(AppSpacing.lg)
diff --git a/iosApp/iosApp/Documents/Components/WarrantyCard.swift b/iosApp/iosApp/Documents/Components/WarrantyCard.swift
index ded9342..a923e73 100644
--- a/iosApp/iosApp/Documents/Components/WarrantyCard.swift
+++ b/iosApp/iosApp/Documents/Components/WarrantyCard.swift
@@ -10,10 +10,10 @@ struct WarrantyCard: View {
var statusColor: Color {
if !document.isActive { return .gray }
- if daysUntilExpiration < 0 { return AppColors.error }
- if daysUntilExpiration < 30 { return AppColors.warning }
+ if daysUntilExpiration < 0 { return .red }
+ if daysUntilExpiration < 30 { return .orange }
if daysUntilExpiration < 90 { return .yellow }
- return AppColors.success
+ return .green
}
var statusText: String {
@@ -31,11 +31,11 @@ struct WarrantyCard: View {
Text(document.title)
.font(.title3.weight(.semibold))
.fontWeight(.bold)
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
Text(document.itemName ?? "")
.font(.body)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
Spacer()
@@ -58,11 +58,11 @@ struct WarrantyCard: View {
VStack(alignment: .leading, spacing: 2) {
Text("Provider")
.font(.caption.weight(.medium))
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
Text(document.provider ?? "N/A")
.font(.body)
.fontWeight(.medium)
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
}
Spacer()
@@ -70,11 +70,11 @@ struct WarrantyCard: View {
VStack(alignment: .trailing, spacing: 2) {
Text("Expires")
.font(.caption.weight(.medium))
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
Text(document.endDate ?? "N/A")
.font(.body)
.fontWeight(.medium)
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
}
}
@@ -96,7 +96,7 @@ struct WarrantyCard: View {
}
}
.padding(AppSpacing.md)
- .background(AppColors.surface)
+ .background(Color(.secondarySystemGroupedBackground))
.cornerRadius(AppRadius.md)
.shadow(color: Color.black.opacity(0.05), radius: 2, x: 0, y: 1)
}
diff --git a/iosApp/iosApp/Documents/DocumentDetailView.swift b/iosApp/iosApp/Documents/DocumentDetailView.swift
index 5e364db..1f5210a 100644
--- a/iosApp/iosApp/Documents/DocumentDetailView.swift
+++ b/iosApp/iosApp/Documents/DocumentDetailView.swift
@@ -400,6 +400,9 @@ struct DocumentDetailView: View {
.font(.body)
}
.frame(maxWidth: .infinity, alignment: .leading)
+ .padding(12)
+ .background(Color(.secondarySystemGroupedBackground))
+ .cornerRadius(8)
}
private func getStatusColor(isActive: Bool, daysUntilExpiration: Int32) -> Color {
diff --git a/iosApp/iosApp/Documents/DocumentsWarrantiesView.swift b/iosApp/iosApp/Documents/DocumentsWarrantiesView.swift
index b72b8c7..d01eac0 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 {
- AppColors.background.ignoresSafeArea()
+ Color(.systemGroupedBackground).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 ? AppColors.success : AppColors.textSecondary)
+ .foregroundColor(showActiveOnly ? .green : Color(.secondaryLabel))
}
}
@@ -149,7 +149,7 @@ struct DocumentsWarrantiesView: View {
}
} label: {
Image(systemName: "line.3.horizontal.decrease.circle")
- .foregroundColor((selectedCategory != nil || selectedDocType != nil) ? AppColors.primary : AppColors.textSecondary)
+ .foregroundColor((selectedCategory != nil || selectedDocType != nil) ? .blue : Color(.secondaryLabel))
}
// Add Button
@@ -158,7 +158,7 @@ struct DocumentsWarrantiesView: View {
}) {
Image(systemName: "plus.circle.fill")
.font(.title2)
- .foregroundColor(AppColors.primary)
+ .foregroundColor(.blue)
}
}
}
diff --git a/iosApp/iosApp/HomeScreenView.swift b/iosApp/iosApp/HomeScreenView.swift
index 8e28873..23338b6 100644
--- a/iosApp/iosApp/HomeScreenView.swift
+++ b/iosApp/iosApp/HomeScreenView.swift
@@ -8,7 +8,7 @@ struct HomeScreenView: View {
var body: some View {
NavigationView {
ZStack {
- AppColors.background
+ Color(.systemGroupedBackground)
.ignoresSafeArea()
if viewModel.isLoading {
@@ -17,7 +17,7 @@ struct HomeScreenView: View {
.scaleEffect(1.2)
Text("Loading...")
.font(.body)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
} else {
ScrollView(showsIndicators: false) {
@@ -27,11 +27,11 @@ struct HomeScreenView: View {
Text("Hello!")
.font(.title.weight(.bold))
.fontWeight(.bold)
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
Text("Welcome to MyCrib")
.font(.body)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, AppSpacing.md)
@@ -80,7 +80,7 @@ struct HomeScreenView: View {
Image(systemName: "rectangle.portrait.and.arrow.right")
.font(.system(size: 18, weight: .semibold))
}
- .foregroundColor(AppColors.error)
+ .foregroundColor(.red)
}
}
}
diff --git a/iosApp/iosApp/Info.plist b/iosApp/iosApp/Info.plist
index 7ae9ca1..bb16c76 100644
--- a/iosApp/iosApp/Info.plist
+++ b/iosApp/iosApp/Info.plist
@@ -15,6 +15,8 @@
+ ITSAppUsesNonExemptEncryption
+
UIBackgroundModes
remote-notification
diff --git a/iosApp/iosApp/Login/LoginView.swift b/iosApp/iosApp/Login/LoginView.swift
index 5f685eb..4c02d00 100644
--- a/iosApp/iosApp/Login/LoginView.swift
+++ b/iosApp/iosApp/Login/LoginView.swift
@@ -25,7 +25,7 @@ struct LoginView: View {
private var buttonBackgroundColor: Color {
if viewModel.isLoading || !isFormValid {
- return AppColors.textTertiary
+ return Color(.tertiaryLabel)
}
return .clear
}
@@ -38,7 +38,7 @@ struct LoginView: View {
NavigationView {
ZStack {
// Background gradient
- AppColors.background
+ Color(.systemGroupedBackground)
.ignoresSafeArea()
ScrollView {
@@ -51,9 +51,9 @@ struct LoginView: View {
// App Icon with gradient
ZStack {
Circle()
- .fill(AppColors.primaryGradient)
+ .fill(LinearGradient(colors: [.blue, .blue.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing))
.frame(width: 100, height: 100)
- .shadow(color: AppColors.primary.opacity(0.3), radius: 20, y: 10)
+ .shadow(color: .blue.opacity(0.3), radius: 20, y: 10)
Image(systemName: "house.fill")
.font(.system(size: 50, weight: .semibold))
@@ -63,11 +63,11 @@ struct LoginView: View {
VStack(spacing: AppSpacing.xs) {
Text("Welcome Back")
.font(.title2.weight(.bold))
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
Text("Sign in to manage your properties")
.font(.body)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
}
@@ -77,11 +77,11 @@ struct LoginView: View {
VStack(alignment: .leading, spacing: AppSpacing.xs) {
Text("Email or Username")
.font(.subheadline.weight(.medium))
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
HStack(spacing: AppSpacing.sm) {
Image(systemName: "envelope.fill")
- .foregroundColor(AppColors.textTertiary)
+ .foregroundColor(Color(.tertiaryLabel))
.frame(width: 20)
TextField("Enter your email", text: $viewModel.username)
@@ -98,13 +98,13 @@ struct LoginView: View {
}
}
.padding(AppSpacing.md)
- .background(AppColors.surface)
+ .background(Color(.secondarySystemGroupedBackground))
.cornerRadius(AppRadius.md)
.overlay(
RoundedRectangle(cornerRadius: AppRadius.md)
- .stroke(focusedField == .username ? AppColors.primary : AppColors.border, lineWidth: 1.5)
+ .stroke(focusedField == .username ? .blue : Color(.separator), lineWidth: 1.5)
)
- .shadow(color: focusedField == .username ? AppColors.primary.opacity(0.1) : .clear, radius: 8)
+ .shadow(color: focusedField == .username ? .blue.opacity(0.1) : .clear, radius: 8)
.animation(.easeInOut(duration: 0.2), value: focusedField)
}
@@ -112,11 +112,11 @@ struct LoginView: View {
VStack(alignment: .leading, spacing: AppSpacing.xs) {
Text("Password")
.font(.subheadline.weight(.medium))
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
HStack(spacing: AppSpacing.sm) {
Image(systemName: "lock.fill")
- .foregroundColor(AppColors.textTertiary)
+ .foregroundColor(Color(.tertiaryLabel))
.frame(width: 20)
Group {
@@ -143,18 +143,18 @@ struct LoginView: View {
isPasswordVisible.toggle()
}) {
Image(systemName: isPasswordVisible ? "eye.slash.fill" : "eye.fill")
- .foregroundColor(AppColors.textTertiary)
+ .foregroundColor(Color(.tertiaryLabel))
.frame(width: 20)
}
}
.padding(AppSpacing.md)
- .background(AppColors.surface)
+ .background(Color(.secondarySystemGroupedBackground))
.cornerRadius(AppRadius.md)
.overlay(
RoundedRectangle(cornerRadius: AppRadius.md)
- .stroke(focusedField == .password ? AppColors.primary : AppColors.border, lineWidth: 1.5)
+ .stroke(focusedField == .password ? .blue : Color(.separator), lineWidth: 1.5)
)
- .shadow(color: focusedField == .password ? AppColors.primary.opacity(0.1) : .clear, radius: 8)
+ .shadow(color: focusedField == .password ? .blue.opacity(0.1) : .clear, radius: 8)
.animation(.easeInOut(duration: 0.2), value: focusedField)
.onChange(of: viewModel.password) { _, _ in
viewModel.clearError()
@@ -168,21 +168,21 @@ struct LoginView: View {
showPasswordReset = true
}
.font(.subheadline.weight(.medium))
- .foregroundColor(AppColors.primary)
+ .foregroundColor(.blue)
}
// Error Message
if let errorMessage = viewModel.errorMessage {
HStack(spacing: AppSpacing.sm) {
Image(systemName: "exclamationmark.circle.fill")
- .foregroundColor(AppColors.error)
+ .foregroundColor(.red)
Text(errorMessage)
.font(.callout)
- .foregroundColor(AppColors.error)
+ .foregroundColor(.red)
Spacer()
}
.padding(AppSpacing.md)
- .background(AppColors.error.opacity(0.1))
+ .background(.red.opacity(0.1))
.cornerRadius(AppRadius.md)
}
@@ -196,18 +196,18 @@ struct LoginView: View {
HStack(spacing: AppSpacing.xs) {
Text("Don't have an account?")
.font(.body)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
Button("Sign Up") {
showingRegister = true
}
.font(.body)
.fontWeight(.semibold)
- .foregroundColor(AppColors.primary)
+ .foregroundColor(.blue)
}
}
.padding(AppSpacing.xl)
- .background(AppColors.surface)
+ .background(Color(.secondarySystemGroupedBackground))
.cornerRadius(AppRadius.xxl)
.shadow(color: .black.opacity(0.08), radius: 20, y: 10)
.padding(.horizontal, AppSpacing.lg)
@@ -285,18 +285,17 @@ struct LoginView: View {
.background(loginButtonBackground)
.cornerRadius(AppRadius.md)
.shadow(
- color: shouldShowShadow ? AppColors.primary.opacity(0.3) : .clear,
+ color: shouldShowShadow ? .blue.opacity(0.3) : .clear,
radius: 10,
y: 5
)
}
- @ViewBuilder
- private var loginButtonBackground: some View {
+ private var loginButtonBackground: AnyShapeStyle {
if viewModel.isLoading || !isFormValid {
- AppColors.textTertiary
+ AnyShapeStyle(Color(.tertiaryLabel))
} else {
- AppColors.primaryGradient
+ AnyShapeStyle(LinearGradient(colors: [.blue, .blue.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing))
}
}
}
diff --git a/iosApp/iosApp/PushNotifications/AppDelegate.swift b/iosApp/iosApp/PushNotifications/AppDelegate.swift
index 45de65f..876ad89 100644
--- a/iosApp/iosApp/PushNotifications/AppDelegate.swift
+++ b/iosApp/iosApp/PushNotifications/AppDelegate.swift
@@ -16,9 +16,23 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele
await PushNotificationManager.shared.requestNotificationPermission()
}
+ // Clear badge when app launches
+ Task { @MainActor in
+ PushNotificationManager.shared.clearBadge()
+ }
+
return true
}
+ // MARK: - App Lifecycle
+
+ func applicationDidBecomeActive(_ application: UIApplication) {
+ // Clear badge when app becomes active
+ Task { @MainActor in
+ PushNotificationManager.shared.clearBadge()
+ }
+ }
+
// MARK: - Remote Notifications
func application(
diff --git a/iosApp/iosApp/Residence/ResidencesListView.swift b/iosApp/iosApp/Residence/ResidencesListView.swift
index 63ecd53..b92943f 100644
--- a/iosApp/iosApp/Residence/ResidencesListView.swift
+++ b/iosApp/iosApp/Residence/ResidencesListView.swift
@@ -8,7 +8,7 @@ struct ResidencesListView: View {
var body: some View {
ZStack {
- AppColors.background
+ Color(.systemGroupedBackground)
.ignoresSafeArea()
if viewModel.myResidences == nil && viewModel.isLoading {
@@ -17,7 +17,7 @@ struct ResidencesListView: View {
.scaleEffect(1.2)
Text("Loading properties...")
.font(.body)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
} else if let error = viewModel.errorMessage {
ErrorView(message: error) {
@@ -39,10 +39,10 @@ struct ResidencesListView: View {
VStack(alignment: .leading, spacing: AppSpacing.xxs) {
Text("Your Properties")
.font(.title3.weight(.semibold))
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
Text("\(response.residences.count) \(response.residences.count == 1 ? "property" : "properties")")
.font(.callout)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
Spacer()
}
@@ -77,7 +77,7 @@ struct ResidencesListView: View {
}) {
Image(systemName: "person.badge.plus")
.font(.system(size: 18, weight: .semibold))
- .foregroundColor(AppColors.primary)
+ .foregroundColor(.blue)
}
Button(action: {
@@ -85,7 +85,7 @@ struct ResidencesListView: View {
}) {
Image(systemName: "plus.circle.fill")
.font(.system(size: 22, weight: .semibold))
- .foregroundColor(AppColors.primary)
+ .foregroundColor(.blue)
}
}
}
diff --git a/iosApp/iosApp/Subviews/Common/HomeNavigationCard.swift b/iosApp/iosApp/Subviews/Common/HomeNavigationCard.swift
index e550e60..8f147cb 100644
--- a/iosApp/iosApp/Subviews/Common/HomeNavigationCard.swift
+++ b/iosApp/iosApp/Subviews/Common/HomeNavigationCard.swift
@@ -10,9 +10,9 @@ struct HomeNavigationCard: View {
// Icon with gradient background
ZStack {
RoundedRectangle(cornerRadius: AppRadius.md)
- .fill(AppColors.primaryGradient)
+ .fill(LinearGradient(colors: [.blue, .blue.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing))
.frame(width: 60, height: 60)
- .shadow(color: AppColors.primary.opacity(0.3), radius: 8, y: 4)
+ .shadow(color: .blue.opacity(0.3), radius: 8, y: 4)
Image(systemName: icon)
.font(.system(size: 28, weight: .semibold))
@@ -24,11 +24,11 @@ struct HomeNavigationCard: View {
Text(title)
.font(.title3.weight(.semibold))
.fontWeight(.semibold)
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
Text(subtitle)
.font(.callout)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
Spacer()
@@ -36,10 +36,10 @@ struct HomeNavigationCard: View {
// Chevron
Image(systemName: "chevron.right")
.font(.system(size: 16, weight: .semibold))
- .foregroundColor(AppColors.textTertiary)
+ .foregroundColor(Color(.tertiaryLabel))
}
.padding(AppSpacing.lg)
- .background(AppColors.surface)
+ .background(Color(.secondarySystemGroupedBackground))
.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/OverviewCard.swift b/iosApp/iosApp/Subviews/Common/OverviewCard.swift
index e6cba2f..e41422e 100644
--- a/iosApp/iosApp/Subviews/Common/OverviewCard.swift
+++ b/iosApp/iosApp/Subviews/Common/OverviewCard.swift
@@ -11,7 +11,7 @@ struct OverviewCard: View {
HStack(spacing: AppSpacing.sm) {
ZStack {
Circle()
- .fill(AppColors.primaryGradient)
+ .fill(LinearGradient(colors: [.blue, .blue.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing))
.frame(width: 44, height: 44)
Image(systemName: "chart.bar.fill")
@@ -21,7 +21,7 @@ struct OverviewCard: View {
Text("Overview")
.font(.title3.weight(.semibold))
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
}
Spacer()
}
@@ -32,7 +32,7 @@ struct OverviewCard: View {
icon: "house.fill",
value: "\(summary.totalResidences)",
label: "Properties",
- color: AppColors.primary
+ color: .blue
)
Divider()
@@ -42,7 +42,7 @@ struct OverviewCard: View {
icon: "list.bullet",
value: "\(summary.totalTasks)",
label: "Total Tasks",
- color: AppColors.info
+ color: .blue
)
Divider()
@@ -52,12 +52,12 @@ struct OverviewCard: View {
icon: "clock.fill",
value: "\(summary.totalPending)",
label: "Pending",
- color: AppColors.warning
+ color: .orange
)
}
}
.padding(AppSpacing.xl)
- .background(AppColors.surface)
+ .background(Color(.secondarySystemGroupedBackground))
.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 af2e12f..2228126 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 = AppColors.primary
+ var color: Color = .blue
var body: some View {
VStack(spacing: AppSpacing.sm) {
@@ -21,11 +21,11 @@ struct StatView: View {
Text(value)
.font(.title2.weight(.semibold))
.fontWeight(.bold)
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
Text(label)
.font(.footnote.weight(.medium))
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
.multilineTextAlignment(.center)
}
.frame(maxWidth: .infinity)
diff --git a/iosApp/iosApp/Subviews/Residence/ResidenceCard.swift b/iosApp/iosApp/Subviews/Residence/ResidenceCard.swift
index d68f7f6..2931c6a 100644
--- a/iosApp/iosApp/Subviews/Residence/ResidenceCard.swift
+++ b/iosApp/iosApp/Subviews/Residence/ResidenceCard.swift
@@ -10,9 +10,9 @@ struct ResidenceCard: View {
HStack(spacing: AppSpacing.sm) {
ZStack {
RoundedRectangle(cornerRadius: AppRadius.sm)
- .fill(AppColors.primaryGradient)
+ .fill(LinearGradient(colors: [.blue, .blue.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing))
.frame(width: 44, height: 44)
- .shadow(color: AppColors.primary.opacity(0.3), radius: 6, y: 3)
+ .shadow(color: .blue.opacity(0.3), radius: 6, y: 3)
Image(systemName: "house.fill")
.font(.system(size: 20, weight: .semibold))
@@ -23,12 +23,12 @@ struct ResidenceCard: View {
Text(residence.name)
.font(.title3.weight(.semibold))
.fontWeight(.bold)
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
.lineLimit(1)
Text(residence.propertyType)
.font(.caption.weight(.medium))
- .foregroundColor(AppColors.textTertiary)
+ .foregroundColor(Color(.tertiaryLabel))
.textCase(.uppercase)
.tracking(0.5)
}
@@ -38,11 +38,11 @@ struct ResidenceCard: View {
if residence.isPrimary {
ZStack {
Circle()
- .fill(AppColors.accent.opacity(0.1))
+ .fill(.purple.opacity(0.1))
.frame(width: 32, height: 32)
Image(systemName: "star.fill")
.font(.system(size: 14, weight: .bold))
- .foregroundColor(AppColors.accent)
+ .foregroundColor(.purple)
}
}
}
@@ -52,19 +52,19 @@ struct ResidenceCard: View {
HStack(spacing: AppSpacing.xxs) {
Image(systemName: "mappin.circle.fill")
.font(.system(size: 12, weight: .medium))
- .foregroundColor(AppColors.textTertiary)
+ .foregroundColor(Color(.tertiaryLabel))
Text(residence.streetAddress)
.font(.callout)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
HStack(spacing: AppSpacing.xxs) {
Image(systemName: "location.fill")
.font(.system(size: 12, weight: .medium))
- .foregroundColor(AppColors.textTertiary)
+ .foregroundColor(Color(.tertiaryLabel))
Text("\(residence.city), \(residence.stateProvince)")
.font(.callout)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
}
.padding(.vertical, AppSpacing.xs)
@@ -77,26 +77,26 @@ struct ResidenceCard: View {
icon: "list.bullet",
value: "\(residence.taskSummary.total)",
label: "Tasks",
- color: AppColors.info
+ color: .blue
)
TaskStatChip(
icon: "checkmark.circle.fill",
value: "\(residence.taskSummary.completed)",
label: "Done",
- color: AppColors.success
+ color: .green
)
TaskStatChip(
icon: "clock.fill",
value: "\(residence.taskSummary.pending)",
label: "Pending",
- color: AppColors.warning
+ color: .orange
)
}
}
.padding(AppSpacing.md)
- .background(AppColors.surface)
+ .background(Color(.secondarySystemGroupedBackground))
.cornerRadius(AppRadius.lg)
.shadow(color: AppShadow.md.color, radius: AppShadow.md.radius, x: AppShadow.md.x, y: AppShadow.md.y)
}
@@ -138,5 +138,5 @@ struct ResidenceCard: View {
updatedAt: "2024-01-01T00:00:00Z"
))
.padding()
- .background(AppColors.background)
+ .background(Color(.systemGroupedBackground))
}
diff --git a/iosApp/iosApp/Subviews/Task/CompletionCardView.swift b/iosApp/iosApp/Subviews/Task/CompletionCardView.swift
index 8f168cc..3b00d5c 100644
--- a/iosApp/iosApp/Subviews/Task/CompletionCardView.swift
+++ b/iosApp/iosApp/Subviews/Task/CompletionCardView.swift
@@ -36,7 +36,7 @@ struct CompletionCardView: View {
HStack(alignment: .top, spacing: 6) {
Image(systemName: "wrench.and.screwdriver")
.font(.caption2)
- .foregroundColor(AppColors.primary)
+ .foregroundColor(.blue)
VStack(alignment: .leading, spacing: 2) {
Text("By: \(contractorDetails.name)")
diff --git a/iosApp/iosApp/Subviews/Task/DynamicTaskCard.swift b/iosApp/iosApp/Subviews/Task/DynamicTaskCard.swift
index b92cc7c..9f6e852 100644
--- a/iosApp/iosApp/Subviews/Task/DynamicTaskCard.swift
+++ b/iosApp/iosApp/Subviews/Task/DynamicTaskCard.swift
@@ -13,6 +13,8 @@ struct DynamicTaskCard: View {
let onArchive: () -> Void
let onUnarchive: () -> Void
+ @State private var isCompletionsExpanded = false
+
var body: some View {
let _ = print("📋 DynamicTaskCard - Task: \(task.title), ButtonTypes: \(buttonTypes)")
@@ -20,7 +22,7 @@ struct DynamicTaskCard: View {
HStack {
VStack(alignment: .leading, spacing: 4) {
Text(task.title)
- .font(.headline)
+ .font(.title3)
.foregroundColor(.primary)
if let status = task.status {
@@ -64,10 +66,23 @@ struct DynamicTaskCard: View {
Text("Completions (\(task.completions.count))")
.font(.caption)
.fontWeight(.semibold)
+ .foregroundColor(.primary)
+ Spacer()
+ Image(systemName: isCompletionsExpanded ? "chevron.up" : "chevron.down")
+ .font(.caption)
+ .foregroundColor(.secondary)
+ }
+ .contentShape(Rectangle())
+ .onTapGesture {
+ withAnimation(.spring(response: 0.3, dampingFraction: 0.7)) {
+ isCompletionsExpanded.toggle()
+ }
}
- ForEach(task.completions, id: \.id) { completion in
- CompletionCardView(completion: completion)
+ if isCompletionsExpanded {
+ ForEach(task.completions, id: \.id) { completion in
+ CompletionCardView(completion: completion)
+ }
}
}
}
@@ -87,18 +102,22 @@ struct DynamicTaskCard: View {
}
.frame(maxWidth: .infinity)
.padding(.vertical, 12)
- .background(Color.blue)
- .foregroundColor(.white)
+ .background(Color.blue.opacity(0.1))
+ .foregroundColor(.blue)
.cornerRadius(8)
+ .overlay(
+ RoundedRectangle(cornerRadius: 8)
+ .stroke(Color.blue, lineWidth: 2)
+ )
}
.zIndex(10)
.menuOrder(.fixed)
}
}
.padding(16)
- .background(Color(.systemBackground))
+ .background(Color(.secondarySystemGroupedBackground))
.cornerRadius(12)
- .shadow(color: Color.black.opacity(0.05), radius: 3, x: 0, y: 2)
+ .shadow(color: Color.black.opacity(0.1), radius: 5, x: 0, y: 2)
.simultaneousGesture(TapGesture(), including: .subviews)
}
diff --git a/iosApp/iosApp/Subviews/Task/PriorityBadge.swift b/iosApp/iosApp/Subviews/Task/PriorityBadge.swift
index a9c8e65..e789bfa 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 AppColors.error
- case "medium": return AppColors.warning
- case "low": return AppColors.success
- default: return AppColors.textTertiary
+ case "high": return .red
+ case "medium": return .orange
+ case "low": return .green
+ default: return Color(.tertiaryLabel)
}
}
}
@@ -36,5 +36,5 @@ struct PriorityBadge: View {
PriorityBadge(priority: "low")
}
.padding()
- .background(AppColors.background)
+ .background(Color(.systemGroupedBackground))
}
diff --git a/iosApp/iosApp/Subviews/Task/StatusBadge.swift b/iosApp/iosApp/Subviews/Task/StatusBadge.swift
index a65e2c9..b42fc83 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 AppColors.success
- case "in_progress": return AppColors.taskInProgress
- case "pending": return AppColors.warning
- case "cancelled": return AppColors.error
- default: return AppColors.textTertiary
+ case "completed": return .green
+ case "in_progress": return .orange
+ case "pending": return .orange
+ case "cancelled": return .red
+ default: return Color(.tertiaryLabel)
}
}
}
@@ -41,5 +41,5 @@ struct StatusBadge: View {
StatusBadge(status: "cancelled")
}
.padding()
- .background(AppColors.background)
+ .background(Color(.systemGroupedBackground))
}
diff --git a/iosApp/iosApp/Subviews/Task/TaskCard.swift b/iosApp/iosApp/Subviews/Task/TaskCard.swift
index 48f44b5..8d51b1d 100644
--- a/iosApp/iosApp/Subviews/Task/TaskCard.swift
+++ b/iosApp/iosApp/Subviews/Task/TaskCard.swift
@@ -11,6 +11,8 @@ struct TaskCard: View {
let onArchive: (() -> Void)?
let onUnarchive: (() -> Void)?
+ @State private var isCompletionsExpanded = false
+
var body: some View {
VStack(alignment: .leading, spacing: AppSpacing.md) {
// Header
@@ -18,7 +20,7 @@ struct TaskCard: View {
VStack(alignment: .leading, spacing: AppSpacing.xs) {
Text(task.title)
.font(.title3.weight(.semibold))
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
.lineLimit(2)
if let status = task.status {
@@ -35,7 +37,7 @@ struct TaskCard: View {
if let description = task.description_, !description.isEmpty {
Text(description)
.font(.callout)
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
.lineLimit(3)
}
@@ -44,14 +46,14 @@ struct TaskCard: View {
HStack(spacing: AppSpacing.xxs) {
Image(systemName: "repeat")
.font(.system(size: 12, weight: .medium))
- .foregroundColor(AppColors.textTertiary)
+ .foregroundColor(Color(.tertiaryLabel))
Text(task.frequency.displayName)
.font(.caption.weight(.medium))
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
.padding(.horizontal, AppSpacing.sm)
.padding(.vertical, AppSpacing.xxs)
- .background(AppColors.surfaceSecondary)
+ .background(Color(.tertiarySystemGroupedBackground))
.cornerRadius(AppRadius.xs)
Spacer()
@@ -60,14 +62,14 @@ struct TaskCard: View {
HStack(spacing: AppSpacing.xxs) {
Image(systemName: "calendar")
.font(.system(size: 12, weight: .medium))
- .foregroundColor(AppColors.textTertiary)
+ .foregroundColor(Color(.tertiaryLabel))
Text(formatDate(dueDate))
.font(.caption.weight(.medium))
- .foregroundColor(AppColors.textSecondary)
+ .foregroundColor(Color(.secondaryLabel))
}
.padding(.horizontal, AppSpacing.sm)
.padding(.vertical, AppSpacing.xxs)
- .background(AppColors.surfaceSecondary)
+ .background(Color(.tertiarySystemGroupedBackground))
.cornerRadius(AppRadius.xs)
}
}
@@ -81,20 +83,32 @@ struct TaskCard: View {
HStack(spacing: AppSpacing.xs) {
ZStack {
Circle()
- .fill(AppColors.success.opacity(0.1))
+ .fill(Color.green.opacity(0.1))
.frame(width: 24, height: 24)
Image(systemName: "checkmark.circle.fill")
.font(.system(size: 14, weight: .semibold))
- .foregroundColor(AppColors.success)
+ .foregroundColor(.green)
}
Text("Completions (\(task.completions.count))")
.font(.footnote.weight(.medium))
.fontWeight(.semibold)
- .foregroundColor(AppColors.textPrimary)
+ .foregroundColor(Color(.label))
+ Spacer()
+ Image(systemName: isCompletionsExpanded ? "chevron.up" : "chevron.down")
+ .font(.caption)
+ .foregroundColor(Color(.secondaryLabel))
+ }
+ .contentShape(Rectangle())
+ .onTapGesture {
+ withAnimation(.spring(response: 0.3, dampingFraction: 0.7)) {
+ isCompletionsExpanded.toggle()
+ }
}
- ForEach(task.completions, id: \.id) { completion in
- CompletionCardView(completion: completion)
+ if isCompletionsExpanded {
+ ForEach(task.completions, id: \.id) { completion in
+ CompletionCardView(completion: completion)
+ }
}
}
}
@@ -113,8 +127,8 @@ struct TaskCard: View {
}
.frame(maxWidth: .infinity)
.frame(height: 44)
- .foregroundColor(AppColors.warning)
- .background(AppColors.warning.opacity(0.1))
+ .foregroundColor(.orange)
+ .background(Color.orange.opacity(0.1))
.cornerRadius(AppRadius.md)
}
}
@@ -131,7 +145,7 @@ struct TaskCard: View {
.frame(maxWidth: .infinity)
.frame(height: 44)
.foregroundColor(.white)
- .background(AppColors.success)
+ .background(.green)
.cornerRadius(AppRadius.md)
}
}
@@ -150,8 +164,8 @@ struct TaskCard: View {
}
.frame(maxWidth: .infinity)
.frame(height: 36)
- .foregroundColor(AppColors.primary)
- .background(AppColors.surfaceSecondary)
+ .foregroundColor(.blue)
+ .background(Color(.tertiarySystemGroupedBackground))
.cornerRadius(AppRadius.sm)
}
@@ -165,8 +179,8 @@ struct TaskCard: View {
}
.frame(maxWidth: .infinity)
.frame(height: 36)
- .foregroundColor(AppColors.error)
- .background(AppColors.error.opacity(0.1))
+ .foregroundColor(.red)
+ .background(Color.red.opacity(0.1))
.cornerRadius(AppRadius.sm)
}
} else if let onUncancel = onUncancel {
@@ -180,7 +194,7 @@ struct TaskCard: View {
.frame(maxWidth: .infinity)
.frame(height: 36)
.foregroundColor(.white)
- .background(AppColors.primary)
+ .background(.blue)
.cornerRadius(AppRadius.sm)
}
}
@@ -197,8 +211,8 @@ struct TaskCard: View {
}
.frame(maxWidth: .infinity)
.frame(height: 36)
- .foregroundColor(AppColors.primary)
- .background(AppColors.surfaceSecondary)
+ .foregroundColor(.blue)
+ .background(Color(.tertiarySystemGroupedBackground))
.cornerRadius(AppRadius.sm)
}
}
@@ -213,8 +227,8 @@ struct TaskCard: View {
}
.frame(maxWidth: .infinity)
.frame(height: 36)
- .foregroundColor(AppColors.textSecondary)
- .background(AppColors.surfaceSecondary)
+ .foregroundColor(Color(.secondaryLabel))
+ .background(Color(.tertiarySystemGroupedBackground))
.cornerRadius(AppRadius.sm)
}
}
@@ -222,7 +236,7 @@ struct TaskCard: View {
}
}
.padding(AppSpacing.md)
- .background(AppColors.surface)
+ .background(Color(.secondarySystemGroupedBackground))
.cornerRadius(AppRadius.lg)
.shadow(color: AppShadow.md.color, radius: AppShadow.md.radius, x: AppShadow.md.x, y: AppShadow.md.y)
}
@@ -271,5 +285,5 @@ struct TaskCard: View {
)
}
.padding()
- .background(AppColors.background)
+ .background(Color(.systemGroupedBackground))
}
diff --git a/iosApp/iosApp/Task/CompleteTaskView.swift b/iosApp/iosApp/Task/CompleteTaskView.swift
index a140e35..dd56d30 100644
--- a/iosApp/iosApp/Task/CompleteTaskView.swift
+++ b/iosApp/iosApp/Task/CompleteTaskView.swift
@@ -393,7 +393,7 @@ struct ContractorPickerView: View {
Spacer()
if selectedContractor == nil {
Image(systemName: "checkmark")
- .foregroundStyle(AppColors.primary)
+ .foregroundStyle(.blue)
}
}
}
@@ -441,7 +441,7 @@ struct ContractorPickerView: View {
if selectedContractor?.id == contractor.id {
Image(systemName: "checkmark")
- .foregroundStyle(AppColors.primary)
+ .foregroundStyle(.blue)
}
}
}
diff --git a/iosApp/iosApp/iosApp.entitlements b/iosApp/iosApp/iosApp.entitlements
index 9abf63f..3cd8c3d 100644
--- a/iosApp/iosApp/iosApp.entitlements
+++ b/iosApp/iosApp/iosApp.entitlements
@@ -6,7 +6,7 @@
development
com.apple.security.application-groups
- group.com.tt.mycrib.MyCrib
+ group.com.tt.mycrib.MyCribDev