Files
mayday/Mayday/Views/Notifications/NotificationDetailView.swift
T
copilot-swe-agent[bot] 1eb21c71ce feat: add complete Mayday iOS Xcode project
- Swift 6, SwiftUI, MVVM + async/await architecture
- iOS 17.0 minimum deployment target
- Two targets: Mayday app + MaydayLiveActivity widget extension
- Models: UserResponse, TokenPair, AppNotification, SessionResponse, AlertAttributes
- Services: HTTPClient (actor), AuthService, KeychainService, NotificationsAPIService, PushNotificationService
- ViewModels: AuthViewModel, NotificationsViewModel, SettingsViewModel
- Views: Login/Register/VerifyEmail, NotificationsList/Detail, Settings/ChangePassword/Sessions
- APNs push notifications with UIApplicationDelegate
- ActivityKit Live Activities for Dynamic Island + Lock Screen
- Keychain (Security framework) token storage
- 30-second polling with pagination for notifications
- Xcode project file (project.pbxproj) with correct build phases for both targets

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-13 23:04:35 +00:00

69 lines
2.3 KiB
Swift

import SwiftUI
struct NotificationDetailView: View {
let notification: AppNotification
let viewModel: NotificationsViewModel
var body: some View {
ScrollView {
VStack(alignment: .leading, spacing: 20) {
VStack(alignment: .leading, spacing: 8) {
Text(notification.topic)
.font(.caption)
.foregroundStyle(.secondary)
Text(notification.subject)
.font(.title2.bold())
}
Divider()
VStack(alignment: .leading, spacing: 8) {
Text("Подробности:")
.font(.headline)
Text(notification.body)
.font(.body)
}
if let metadata = notification.metadata, !metadata.isEmpty {
Divider()
VStack(alignment: .leading, spacing: 8) {
Text("Метаданные:")
.font(.headline)
ForEach(metadata.sorted(by: { $0.key < $1.key }), id: \.key) { key, value in
HStack {
Text(key).foregroundStyle(.secondary)
Spacer()
Text(value)
}
.font(.footnote)
}
}
}
Divider()
VStack(alignment: .leading, spacing: 8) {
LabeledContent("Получено") {
Text(notification.createdAt.formatted(date: .abbreviated, time: .shortened))
}
LabeledContent("Статус") {
Text(notification.status.rawValue)
}
LabeledContent("Канал") {
Text(notification.channel.rawValue)
}
}
.font(.footnote)
Spacer()
}
.padding()
}
.navigationTitle("Уведомление")
.navigationBarTitleDisplayMode(.inline)
.task {
await viewModel.markAsRead(notification)
}
}
}