- Remove AppColors struct, migrate to iOS system colors throughout - Redesign ContractorFormSheet to use native SwiftUI Form components - Add color-coded icons to contractor form sections - Improve dark mode contrast for task cards - Add background colors to document detail fields - Fix text alignment issues in ContractorDetailView - Make task completion lists expandable/collapsible by default - Clear app badge on launch and when app becomes active - Update button styling with proper gradients and shadows - Improve form field focus states and accessibility 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
100 lines
3.2 KiB
Swift
100 lines
3.2 KiB
Swift
import SwiftUI
|
|
import ComposeApp
|
|
|
|
struct DocumentCard: View {
|
|
let document: Document
|
|
|
|
var typeColor: Color {
|
|
switch document.documentType {
|
|
case "warranty": return .blue
|
|
case "manual": return .purple
|
|
case "receipt": return .green
|
|
case "inspection": return .orange
|
|
default: return .gray
|
|
}
|
|
}
|
|
|
|
var typeIcon: String {
|
|
switch document.documentType {
|
|
case "photo": return "photo"
|
|
case "warranty", "insurance": return "checkmark.shield"
|
|
case "manual": return "book"
|
|
case "receipt": return "receipt"
|
|
default: return "doc.text"
|
|
}
|
|
}
|
|
|
|
var body: some View {
|
|
HStack(spacing: AppSpacing.md) {
|
|
// Document Icon
|
|
ZStack {
|
|
RoundedRectangle(cornerRadius: 8)
|
|
.fill(typeColor.opacity(0.1))
|
|
.frame(width: 56, height: 56)
|
|
|
|
Image(systemName: typeIcon)
|
|
.font(.system(size: 24))
|
|
.foregroundColor(typeColor)
|
|
}
|
|
|
|
VStack(alignment: .leading, spacing: 4) {
|
|
Text(document.title)
|
|
.font(.title3.weight(.semibold))
|
|
.fontWeight(.bold)
|
|
.foregroundColor(Color(.label))
|
|
.lineLimit(1)
|
|
|
|
if let description = document.description_, !description.isEmpty {
|
|
Text(description)
|
|
.font(.callout)
|
|
.foregroundColor(Color(.secondaryLabel))
|
|
.lineLimit(2)
|
|
}
|
|
|
|
HStack(spacing: 8) {
|
|
Text(getDocTypeDisplayName(document.documentType))
|
|
.font(.caption.weight(.medium))
|
|
.foregroundColor(typeColor)
|
|
.padding(.horizontal, 6)
|
|
.padding(.vertical, 2)
|
|
.background(typeColor.opacity(0.2))
|
|
.cornerRadius(4)
|
|
|
|
if let fileSize = document.fileSize {
|
|
Text(formatFileSize(Int(fileSize)))
|
|
.font(.caption.weight(.medium))
|
|
.foregroundColor(Color(.secondaryLabel))
|
|
}
|
|
}
|
|
}
|
|
|
|
Spacer()
|
|
|
|
Image(systemName: "chevron.right")
|
|
.foregroundColor(Color(.secondaryLabel))
|
|
.font(.system(size: 14))
|
|
}
|
|
.padding(AppSpacing.md)
|
|
.background(Color(.secondarySystemGroupedBackground))
|
|
.cornerRadius(AppRadius.md)
|
|
.shadow(color: Color.black.opacity(0.05), radius: 2, x: 0, y: 1)
|
|
}
|
|
|
|
private func getDocTypeDisplayName(_ type: String) -> String {
|
|
return DocumentType.companion.fromValue(value: type).displayName
|
|
}
|
|
|
|
private func formatFileSize(_ bytes: Int) -> String {
|
|
var size = Double(bytes)
|
|
let units = ["B", "KB", "MB", "GB"]
|
|
var unitIndex = 0
|
|
|
|
while size >= 1024 && unitIndex < units.count - 1 {
|
|
size /= 1024
|
|
unitIndex += 1
|
|
}
|
|
|
|
return String(format: "%.1f %@", size, units[unitIndex])
|
|
}
|
|
}
|