Files
honeyDueKMP/iosApp/iosApp/Documents/Components/DocumentsTabContent.swift
T
Trey T 09120e9d9d
Android UI Tests / ui-tests (push) Has been cancelled
iOS: unify empty states — one centered, leaf-decorated component
All screen-level empty states now use a single OrganicEmptyScreen that
fills the screen and centers its icon/title/subtitle/action in the dead
middle (both axes), with the three animated FloatingLeaf footer on every
empty screen.

- Add canonical OrganicEmptyScreen (Shared/Components/SharedEmptyStateView)
- Fix ListAsyncContentView: empty/error content used minHeight 60% of the
  screen (placeholder sat in the top portion) → use full height so it
  centers dead-center regardless of headers
- Hide Contractors' filter bar when the list is empty so the placeholder
  stays screen-centered
- Route Properties / Tasks / Contractors / Documents / Warranties empties
  through OrganicEmptyScreen; preserve the Tasks empty's branching
  (no-residences vs add-task vs upgrade-prompt)
- Remove the duplicate/dead empty components

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 22:49:34 -05:00

77 lines
2.5 KiB
Swift

import SwiftUI
import ComposeApp
struct DocumentsTabContent: View {
@ObservedObject var viewModel: DocumentViewModel
@StateObject private var subscriptionCache = SubscriptionCacheWrapper.shared
let searchText: String
var filteredDocuments: [Document] {
if searchText.isEmpty {
return viewModel.documents
}
return viewModel.documents.filter {
$0.title.localizedCaseInsensitiveContains(searchText) ||
($0.description_ ?? "").localizedCaseInsensitiveContains(searchText)
}
}
var body: some View {
ListAsyncContentView(
items: filteredDocuments,
isLoading: viewModel.isLoading,
errorMessage: viewModel.errorMessage,
content: { documents in
DocumentsListContent(documents: documents)
},
emptyContent: {
if !subscriptionCache.shouldShowUpgradePrompt(currentCount: filteredDocuments.count, limitKey: "documents") {
OrganicEmptyScreen(
icon: "doc",
title: L10n.Documents.noDocumentsFound,
subtitle: L10n.Documents.noDocumentsMessage
)
} else {
UpgradeFeatureView(
triggerKey: "view_documents",
icon: "doc.text.fill"
)
}
},
onRefresh: {
viewModel.loadDocuments(forceRefresh: true)
for await loading in viewModel.$isLoading.values {
if !loading { break }
}
},
onRetry: {
viewModel.loadDocuments()
}
)
}
}
// MARK: - Documents List Content
private struct DocumentsListContent: View {
let documents: [Document]
var body: some View {
ScrollView {
LazyVStack(spacing: AppSpacing.sm) {
ForEach(documents, id: \.id) { document in
NavigationLink(destination: DocumentDetailView(documentId: document.id?.int32Value ?? 0)) {
DocumentCard(document: document)
}
.buttonStyle(PlainButtonStyle())
}
}
.padding(AppSpacing.md)
.padding(.bottom, AppSpacing.xxxl)
}
.safeAreaInset(edge: .bottom) {
Color.clear.frame(height: 0)
}
}
}