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