- P0: Add default param to protocol list(params:) for compile fix - P1: Fix onDelete async closure, implement deletion logic - P2: Remove redundant objectWillChange.send() (Published handles it) - P2: Make RelativeDateTimeFormatter static singleton (per-row perf) - P3: Replace deprecated NavigationView with NavigationStack
94 lines
3.0 KiB
Swift
94 lines
3.0 KiB
Swift
import SwiftUI
|
|
|
|
struct NotificationRowView: View {
|
|
let notification: NotificationItem
|
|
|
|
var body: some View {
|
|
HStack(spacing: 12) {
|
|
// Notification icon
|
|
Image(systemName: notification.type.icon)
|
|
.font(.system(size: 24))
|
|
.foregroundColor(notification.type.color)
|
|
.accessibilityLabel(notification.type.rawValue)
|
|
|
|
// Notification content
|
|
VStack(alignment: .leading, spacing: 4) {
|
|
Text(notification.title)
|
|
.font(.headline)
|
|
.foregroundColor(.primary)
|
|
|
|
Text(notification.message)
|
|
.font(.subheadline)
|
|
.foregroundColor(.secondary)
|
|
.lineLimit(2)
|
|
}
|
|
|
|
Spacer()
|
|
|
|
// Timestamp and read indicator
|
|
VStack(alignment: .trailing, spacing: 4) {
|
|
if !notification.isRead {
|
|
Image(systemName: "circle.fill")
|
|
.font(.system(size: 8))
|
|
.foregroundColor(.blue)
|
|
}
|
|
|
|
Text(formatTimestamp(notification.createdAt))
|
|
.font(.caption)
|
|
.foregroundColor(.secondary)
|
|
}
|
|
}
|
|
.padding(.vertical, 8)
|
|
.contentShape(Rectangle())
|
|
}
|
|
|
|
private func formatTimestamp(_ date: Date) -> String {
|
|
Self.formatter.localizedString(for: date, relativeTo: Date())
|
|
}
|
|
|
|
private static let formatter: RelativeDateTimeFormatter = {
|
|
let formatter = RelativeDateTimeFormatter()
|
|
formatter.unitsStyle = .abbreviated
|
|
return formatter
|
|
}()
|
|
}
|
|
|
|
#Preview {
|
|
List {
|
|
NotificationRowView(
|
|
notification: NotificationItem(
|
|
id: "1",
|
|
type: .loanApproved,
|
|
title: "Loan Approved",
|
|
message: "Your loan application for $500 has been approved by Sarah Johnson.",
|
|
createdAt: Date().addingTimeInterval(-3600),
|
|
isRead: false
|
|
)
|
|
)
|
|
|
|
NotificationRowView(
|
|
notification: NotificationItem(
|
|
id: "2",
|
|
type: .paymentDue,
|
|
title: "Payment Due Soon",
|
|
message: "Your payment of $150 is due in 3 days.",
|
|
createdAt: Date().addingTimeInterval(-86400 * 2),
|
|
isRead: true
|
|
)
|
|
)
|
|
|
|
NotificationRowView(
|
|
notification: NotificationItem(
|
|
id: "3",
|
|
type: .paymentReceived,
|
|
title: "Payment Received",
|
|
message: "You received a payment of $75 from Michael Chen.",
|
|
createdAt: Date().addingTimeInterval(-86400 * 5),
|
|
isRead: false
|
|
)
|
|
)
|
|
}
|
|
.listStyle(.insetGrouped)
|
|
.previewDisplayName("Notification Row Preview")
|
|
}
|