- Create NotificationsView.swift with SwiftUI List and pull-to-refresh - Create NotificationRowView.swift for individual notification items - Create NotificationsViewModel.swift with MVVM pattern - Implement empty state view for no notifications - Add mark-as-read and mark-all-as-read functionality - Support notification types: loan approved/rejected, payment received/due, new lender, system updates - Add toolbar action for marking all notifications as read - Include README.md with architecture documentation and integration guide Next: Connect tRPC notifications router for data fetching
90 lines
2.9 KiB
Swift
90 lines
2.9 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 {
|
|
let formatter = RelativeDateTimeFormatter()
|
|
formatter.unitsStyle = .abbreviated
|
|
return formatter.localizedString(for: date, relativeTo: Date())
|
|
}
|
|
}
|
|
|
|
#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")
|
|
}
|