diff --git a/composeApp/src/commonMain/kotlin/com/example/casera/network/AuthApi.kt b/composeApp/src/commonMain/kotlin/com/example/casera/network/AuthApi.kt index 8b75af3..fd36755 100644 --- a/composeApp/src/commonMain/kotlin/com/example/casera/network/AuthApi.kt +++ b/composeApp/src/commonMain/kotlin/com/example/casera/network/AuthApi.kt @@ -100,7 +100,7 @@ class AuthApi(private val client: HttpClient = ApiClient.httpClient) { suspend fun updateProfile(token: String, request: UpdateProfileRequest): ApiResult { return try { - val response = client.put("$baseUrl/auth/update-profile/") { + val response = client.put("$baseUrl/auth/profile/") { header("Authorization", "Token $token") contentType(ContentType.Application.Json) setBody(request) diff --git a/iosApp/Casera/MyCrib.swift b/iosApp/Casera/MyCrib.swift index 67df031..e88d75f 100644 --- a/iosApp/Casera/MyCrib.swift +++ b/iosApp/Casera/MyCrib.swift @@ -162,19 +162,6 @@ struct SmallWidgetView: View { var body: some View { VStack(alignment: .leading, spacing: 0) { - // Header - HStack(spacing: 6) { - Image(systemName: "house.fill") - .font(.system(size: 14, weight: .semibold)) - .foregroundStyle(.blue) - - Text("Casera") - .font(.system(size: 14, weight: .bold)) - .foregroundStyle(.primary) - - Spacer() - } - // Task Count VStack(alignment: .leading, spacing: 4) { Text("\(entry.taskCount)") @@ -410,16 +397,8 @@ struct LargeWidgetView: View { VStack(alignment: .leading, spacing: 6) { // Header HStack(spacing: 6) { - Image(systemName: "house.fill") - .font(.system(size: 16, weight: .semibold)) - .foregroundStyle(.blue) - - Text("Casera") - .font(.system(size: 16, weight: .bold)) - .foregroundStyle(.primary) - Spacer() - + Text("\(entry.taskCount)") .font(.system(size: 22, weight: .bold)) .foregroundStyle(.blue) @@ -483,7 +462,9 @@ struct LargeTaskRowView: View { HStack(spacing: 10) { if let residenceName = task.residenceName { HStack(spacing: 2) { - Image(systemName: "house.fill") + Image("icon") + .resizable() + .frame(width: 7, height: 7) .font(.system(size: 7)) Text(residenceName) .font(.system(size: 9)) diff --git a/iosApp/iosApp.xcodeproj/project.pbxproj b/iosApp/iosApp.xcodeproj/project.pbxproj index 28d14c7..98a35b9 100644 --- a/iosApp/iosApp.xcodeproj/project.pbxproj +++ b/iosApp/iosApp.xcodeproj/project.pbxproj @@ -85,6 +85,13 @@ ); target = 1CBF1BEC2ECD9768001BF56C /* CaseraUITests */; }; + 1C87A67A2EDCC3100081E450 /* Exceptions for "iosApp" folder in "CaseraExtension" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Assets.xcassets, + ); + target = 1C07893C2EBC218B00392B46 /* CaseraExtension */; + }; 1CBF1C072ECD97AC001BF56C /* Exceptions for "CaseraTests" folder in "CaseraTests" target */ = { isa = PBXFileSystemSynchronizedBuildFileExceptionSet; membershipExceptions = ( @@ -135,6 +142,7 @@ isa = PBXFileSystemSynchronizedRootGroup; exceptions = ( 84D9B4B86A80D013B8CBB951 /* Exceptions for "iosApp" folder in "Casera" target */, + 1C87A67A2EDCC3100081E450 /* Exceptions for "iosApp" folder in "CaseraExtension" target */, 1C77EDA12ECE784100A53003 /* Exceptions for "iosApp" folder in "CaseraUITests" target */, ); path = iosApp; diff --git a/iosApp/iosApp/Assets.xcassets/house_outline.imageset/Contents.json b/iosApp/iosApp/Assets.xcassets/house_outline.imageset/Contents.json new file mode 100644 index 0000000..bd99210 --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/house_outline.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "house_outline.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosApp/iosApp/Assets.xcassets/house_outline.imageset/house_outline.pdf b/iosApp/iosApp/Assets.xcassets/house_outline.imageset/house_outline.pdf new file mode 100644 index 0000000..ede7350 Binary files /dev/null and b/iosApp/iosApp/Assets.xcassets/house_outline.imageset/house_outline.pdf differ diff --git a/iosApp/iosApp/Assets.xcassets/icon.imageset/Contents.json b/iosApp/iosApp/Assets.xcassets/icon.imageset/Contents.json new file mode 100644 index 0000000..dd9e55c --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/icon.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "icon.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosApp/iosApp/Assets.xcassets/icon.imageset/icon.pdf b/iosApp/iosApp/Assets.xcassets/icon.imageset/icon.pdf new file mode 100644 index 0000000..f3c56d0 Binary files /dev/null and b/iosApp/iosApp/Assets.xcassets/icon.imageset/icon.pdf differ diff --git a/iosApp/iosApp/Assets.xcassets/tab_view_house.imageset/Contents.json b/iosApp/iosApp/Assets.xcassets/tab_view_house.imageset/Contents.json new file mode 100644 index 0000000..0391e21 --- /dev/null +++ b/iosApp/iosApp/Assets.xcassets/tab_view_house.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "filename" : "house_outline 2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "house_outline 1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "house_outline.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iosApp/iosApp/Assets.xcassets/tab_view_house.imageset/house_outline 1.png b/iosApp/iosApp/Assets.xcassets/tab_view_house.imageset/house_outline 1.png new file mode 100644 index 0000000..70bf1f1 Binary files /dev/null and b/iosApp/iosApp/Assets.xcassets/tab_view_house.imageset/house_outline 1.png differ diff --git a/iosApp/iosApp/Assets.xcassets/tab_view_house.imageset/house_outline 2.png b/iosApp/iosApp/Assets.xcassets/tab_view_house.imageset/house_outline 2.png new file mode 100644 index 0000000..7e965e2 Binary files /dev/null and b/iosApp/iosApp/Assets.xcassets/tab_view_house.imageset/house_outline 2.png differ diff --git a/iosApp/iosApp/Assets.xcassets/tab_view_house.imageset/house_outline.png b/iosApp/iosApp/Assets.xcassets/tab_view_house.imageset/house_outline.png new file mode 100644 index 0000000..052759d Binary files /dev/null and b/iosApp/iosApp/Assets.xcassets/tab_view_house.imageset/house_outline.png differ diff --git a/iosApp/iosApp/Contractor/ContractorCard.swift b/iosApp/iosApp/Contractor/ContractorCard.swift index 3f87043..5a70f59 100644 --- a/iosApp/iosApp/Contractor/ContractorCard.swift +++ b/iosApp/iosApp/Contractor/ContractorCard.swift @@ -8,15 +8,15 @@ struct ContractorCard: View { var body: some View { HStack(spacing: AppSpacing.md) { // Avatar - ZStack { - Circle() - .fill(Color.appPrimary.opacity(0.1)) - .frame(width: 56, height: 56) - - Image(systemName: "person.fill") - .font(.title2) - .foregroundColor(Color.appPrimary) - } +// ZStack { +// Circle() +// .fill(Color.appPrimary.opacity(0.1)) +// .frame(width: 56, height: 56) +// +// Image(systemName: "person.fill") +// .font(.title2) +// .foregroundColor(Color.appPrimary) +// } // Content VStack(alignment: .leading, spacing: AppSpacing.xxs) { diff --git a/iosApp/iosApp/Contractor/ContractorFormSheet.swift b/iosApp/iosApp/Contractor/ContractorFormSheet.swift index 30c1ee8..3689ae5 100644 --- a/iosApp/iosApp/Contractor/ContractorFormSheet.swift +++ b/iosApp/iosApp/Contractor/ContractorFormSheet.swift @@ -428,10 +428,12 @@ struct ContractorFormSheet: View { // Set residence if contractor has one if let residenceId = contractor.residenceId { selectedResidenceId = residenceId.int32Value - // Try to find residence name from loaded residences - if let residences = residenceViewModel.myResidences?.residences, - let residence = residences.first(where: { $0.id == residenceId.int32Value }) { - selectedResidenceName = residence.name + if let selectedResidenceId { + ComposeApp.ResidenceViewModel().getResidence(id: selectedResidenceId, onResult: { result in + if let success = result as? ApiResultSuccess { + self.selectedResidenceName = success.data?.name + } + }) } } diff --git a/iosApp/iosApp/Documents/Components/DocumentCard.swift b/iosApp/iosApp/Documents/Components/DocumentCard.swift index b98ff5e..50172e4 100644 --- a/iosApp/iosApp/Documents/Components/DocumentCard.swift +++ b/iosApp/iosApp/Documents/Components/DocumentCard.swift @@ -27,14 +27,18 @@ struct DocumentCard: View { var body: some View { HStack(spacing: AppSpacing.md) { // Document Icon - ZStack { - RoundedRectangle(cornerRadius: 8) - .fill(typeColor.opacity(0.1)) - .frame(width: 56, height: 56) - + VStack { Image(systemName: typeIcon) .font(.system(size: 24)) .foregroundColor(typeColor) + .background(content: { + RoundedRectangle(cornerRadius: 8) + .fill(typeColor.opacity(0.1)) + .frame(width: 56, height: 56) + }) + .padding(AppSpacing.md) + + Spacer() } VStack(alignment: .leading, spacing: 4) { diff --git a/iosApp/iosApp/Login/LoginView.swift b/iosApp/iosApp/Login/LoginView.swift index 1993954..89a0163 100644 --- a/iosApp/iosApp/Login/LoginView.swift +++ b/iosApp/iosApp/Login/LoginView.swift @@ -53,12 +53,7 @@ struct LoginView: View { VStack(spacing: AppSpacing.lg) { // App Icon with gradient ZStack { - Circle() - .fill(LinearGradient(colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) - .frame(width: 100, height: 100) - .shadow(color: Color.appPrimary.opacity(0.3), radius: 20, y: 10) - - Image(systemName: "house.fill") + Image("icon") .font(.system(size: 50, weight: .semibold)) .foregroundStyle(.white) } diff --git a/iosApp/iosApp/MainTabView.swift b/iosApp/iosApp/MainTabView.swift index b0ba183..1aca547 100644 --- a/iosApp/iosApp/MainTabView.swift +++ b/iosApp/iosApp/MainTabView.swift @@ -13,7 +13,7 @@ struct MainTabView: View { } .id(refreshID) .tabItem { - Label("Residences", systemImage: "house.fill") + Label("Residences", image: "tab_view_house") } .tag(0) .accessibilityIdentifier(AccessibilityIdentifiers.Navigation.residencesTab) diff --git a/iosApp/iosApp/Profile/NotificationPreferencesView.swift b/iosApp/iosApp/Profile/NotificationPreferencesView.swift index e0eb20e..b94bbf4 100644 --- a/iosApp/iosApp/Profile/NotificationPreferencesView.swift +++ b/iosApp/iosApp/Profile/NotificationPreferencesView.swift @@ -152,8 +152,16 @@ struct NotificationPreferencesView: View { .foregroundColor(Color.appTextSecondary) } } icon: { - Image(systemName: "house.fill") - .foregroundColor(Color.appPrimary) + Image("house_outline") + .resizable() + .frame(width: 22, height: 22) + .foregroundColor(Color.appTextOnPrimary) + .background(content: { + RoundedRectangle(cornerRadius: AppRadius.sm) + .fill(LinearGradient(colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) + .frame(width: 22, height: 22) + .shadow(color: Color.appPrimary.opacity(0.3), radius: 6, y: 3) + }) } } .tint(Color.appPrimary) diff --git a/iosApp/iosApp/Profile/ProfileTabView.swift b/iosApp/iosApp/Profile/ProfileTabView.swift index e93446d..752b179 100644 --- a/iosApp/iosApp/Profile/ProfileTabView.swift +++ b/iosApp/iosApp/Profile/ProfileTabView.swift @@ -14,26 +14,26 @@ struct ProfileTabView: View { var body: some View { List { - Section { - HStack { - Image(systemName: "person.circle.fill") - .resizable() - .frame(width: 60, height: 60) - .foregroundColor(Color.appPrimary) - - VStack(alignment: .leading, spacing: 4) { - Text("User Profile") - .font(.headline) - .foregroundColor(Color.appTextPrimary) - - Text("Manage your account") - .font(.caption) - .foregroundColor(Color.appTextSecondary) - } - } - .padding(.vertical, 8) - .listRowBackground(Color.appBackgroundSecondary) - } +// Section { +// HStack { +// Image(systemName: "person.circle.fill") +// .resizable() +// .frame(width: 60, height: 60) +// .foregroundColor(Color.appPrimary) +// +// VStack(alignment: .leading, spacing: 4) { +// Text("User Profile") +// .font(.headline) +// .foregroundColor(Color.appTextPrimary) +// +// Text("Manage your account") +// .font(.caption) +// .foregroundColor(Color.appTextSecondary) +// } +// } +// .padding(.vertical, 8) +// .listRowBackground(Color.appBackgroundSecondary) +// } Section("Account") { Button(action: { diff --git a/iosApp/iosApp/Subviews/Auth/LoginHeader.swift b/iosApp/iosApp/Subviews/Auth/LoginHeader.swift index 23a494c..919d415 100644 --- a/iosApp/iosApp/Subviews/Auth/LoginHeader.swift +++ b/iosApp/iosApp/Subviews/Auth/LoginHeader.swift @@ -3,7 +3,7 @@ import SwiftUI struct LoginHeader: View { var body: some View { VStack(spacing: 8) { - Image(systemName: "house.fill") + Image("icon") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 80, height: 80) diff --git a/iosApp/iosApp/Subviews/Common/OverviewCard.swift b/iosApp/iosApp/Subviews/Common/OverviewCard.swift index 4d11f06..e702535 100644 --- a/iosApp/iosApp/Subviews/Common/OverviewCard.swift +++ b/iosApp/iosApp/Subviews/Common/OverviewCard.swift @@ -29,7 +29,7 @@ struct OverviewCard: View { // Stats Grid HStack(spacing: AppSpacing.md) { StatView( - icon: "house.fill", + icon: "house_outline", value: "\(summary.totalResidences)", label: "Properties", color: Color.appPrimary diff --git a/iosApp/iosApp/Subviews/Common/StatView.swift b/iosApp/iosApp/Subviews/Common/StatView.swift index 4b87be0..ff55df3 100644 --- a/iosApp/iosApp/Subviews/Common/StatView.swift +++ b/iosApp/iosApp/Subviews/Common/StatView.swift @@ -13,9 +13,22 @@ struct StatView: View { .fill(color.opacity(0.1)) .frame(width: 48, height: 48) - Image(systemName: icon) - .font(.system(size: 22, weight: .semibold)) - .foregroundColor(color) + if icon == "house_outline" { + Image("house_outline") + .resizable() + .frame(width: 22, height: 22) + .foregroundColor(Color.appTextOnPrimary) + .background(content: { + RoundedRectangle(cornerRadius: AppRadius.sm) + .fill(LinearGradient(colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) + .frame(width: 22, height: 22) + .shadow(color: Color.appPrimary.opacity(0.3), radius: 6, y: 3) + }) + } else { + Image(systemName: icon) + .font(.system(size: 22, weight: .semibold)) + .foregroundColor(color) + } } Text(value) diff --git a/iosApp/iosApp/Subviews/Residence/PropertyHeaderCard.swift b/iosApp/iosApp/Subviews/Residence/PropertyHeaderCard.swift index 8f53c4f..be8558d 100644 --- a/iosApp/iosApp/Subviews/Residence/PropertyHeaderCard.swift +++ b/iosApp/iosApp/Subviews/Residence/PropertyHeaderCard.swift @@ -7,9 +7,20 @@ struct PropertyHeaderCard: View { var body: some View { VStack(alignment: .leading, spacing: 16) { HStack { - Image(systemName: "house.fill") - .font(.title2) - .foregroundColor(Color.appPrimary) + VStack { + Image("house_outline") + .resizable() + .frame(width: 38, height: 38) + .foregroundColor(Color.appTextOnPrimary) + .background(content: { + RoundedRectangle(cornerRadius: AppRadius.sm) + .fill(LinearGradient(colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) + .frame(width: 38, height: 38) + .shadow(color: Color.appPrimary.opacity(0.3), radius: 6, y: 3) + }) + + Spacer() + } VStack(alignment: .leading, spacing: 4) { Text(residence.name) diff --git a/iosApp/iosApp/Subviews/Residence/ResidenceCard.swift b/iosApp/iosApp/Subviews/Residence/ResidenceCard.swift index c049ae3..7598352 100644 --- a/iosApp/iosApp/Subviews/Residence/ResidenceCard.swift +++ b/iosApp/iosApp/Subviews/Residence/ResidenceCard.swift @@ -3,29 +3,33 @@ import ComposeApp struct ResidenceCard: View { let residence: ResidenceResponse - + var body: some View { VStack(alignment: .leading, spacing: AppSpacing.md) { // Header with property type icon HStack(spacing: AppSpacing.sm) { - ZStack { - RoundedRectangle(cornerRadius: AppRadius.sm) - .fill(LinearGradient(colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) + VStack { + Image("house_outline") + .resizable() .frame(width: 44, height: 44) - .shadow(color: Color.appPrimary.opacity(0.3), radius: 6, y: 3) - - Image(systemName: "house.fill") - .font(.system(size: 20, weight: .semibold)) .foregroundColor(Color.appTextOnPrimary) + .background(content: { + RoundedRectangle(cornerRadius: AppRadius.sm) + .fill(LinearGradient(colors: [Color.appPrimary, Color.appPrimary.opacity(0.8)], startPoint: .topLeading, endPoint: .bottomTrailing)) + .frame(width: 44, height: 44) + .shadow(color: Color.appPrimary.opacity(0.3), radius: 6, y: 3) + }) + .padding([.trailing], AppSpacing.md) + + Spacer() } - + VStack(alignment: .leading, spacing: AppSpacing.xxs) { Text(residence.name) .font(.title3.weight(.semibold)) .fontWeight(.bold) .foregroundColor(Color.appTextPrimary) -// .lineLimit(1) - + if let propertyTypeName = residence.propertyTypeName { Text(propertyTypeName) .font(.caption.weight(.medium)) @@ -34,21 +38,26 @@ struct ResidenceCard: View { .tracking(0.5) } } - + Spacer() - + if residence.isPrimary { - ZStack { - Circle() - .fill(Color.appAccent.opacity(0.2)) - .frame(width: 32, height: 32) + VStack { Image(systemName: "star.fill") .font(.system(size: 14, weight: .bold)) .foregroundColor(Color.appAccent) + .background(content: { + Circle() + .fill(Color.appAccent.opacity(0.2)) + .frame(width: 32, height: 32) + }) + .padding(AppSpacing.md) + + Spacer() } } } - + // Address VStack(alignment: .leading, spacing: AppSpacing.xxs) { if !residence.streetAddress.isEmpty { @@ -61,7 +70,7 @@ struct ResidenceCard: View { .foregroundColor(Color.appTextSecondary) } } - + if !residence.city.isEmpty || !residence.stateProvince.isEmpty { HStack(spacing: AppSpacing.xxs) { Image(systemName: "location.fill") @@ -74,13 +83,13 @@ struct ResidenceCard: View { } } .padding(.vertical, AppSpacing.xs) - + Divider() - + // Fully dynamic task stats from API - show first 3 categories HStack(spacing: AppSpacing.sm) { let displayCategories = Array(residence.taskSummary.categories.prefix(3)) - + ForEach(displayCategories, id: \.name) { category in TaskStatChip( icon: category.icons.ios, diff --git a/iosApp/iosApp/Subviews/Residence/SummaryCard.swift b/iosApp/iosApp/Subviews/Residence/SummaryCard.swift index 2e5c7e1..65bfeae 100644 --- a/iosApp/iosApp/Subviews/Residence/SummaryCard.swift +++ b/iosApp/iosApp/Subviews/Residence/SummaryCard.swift @@ -17,7 +17,7 @@ struct SummaryCard: View { HStack(spacing: 20) { SummaryStatView( - icon: "house.fill", + icon: "house_outline", value: "\(summary.totalResidences)", label: "Properties" ) diff --git a/iosApp/iosApp/Subviews/Residence/SummaryStatView.swift b/iosApp/iosApp/Subviews/Residence/SummaryStatView.swift index f78b5d1..ef9a50c 100644 --- a/iosApp/iosApp/Subviews/Residence/SummaryStatView.swift +++ b/iosApp/iosApp/Subviews/Residence/SummaryStatView.swift @@ -28,7 +28,7 @@ struct SummaryStatView: View { #Preview { HStack(spacing: 20) { SummaryStatView( - icon: "house.fill", + icon: "house_outline", value: "3", label: "Properties" )