ReadKeep/readeck/UI/Bookmarks/BookmarksView.swift
Ilyas Hallak c8368f0a70 feat: Implement bookmark filtering, enhanced UI, and API integration
- Add BookmarkState enum with unread, favorite, and archived states
- Extend API layer with query parameter filtering for bookmark states
- Update Bookmark domain model to match complete API response schema
- Implement BookmarkListView with card-based UI and preview images
- Add BookmarkListViewModel with state management and error handling
- Enhance BookmarkDetailView with meta information and WebView rendering
- Create comprehensive DTO mapping for all bookmark fields
- Add TabView with state-based bookmark filtering
- Implement date formatting utilities for ISO8601 timestamps
- Add progress indicators and pull-to-refresh functionality
2025-06-11 22:02:44 +02:00

68 lines
2.3 KiB
Swift

import SwiftUI
struct BookmarksView: View {
@State private var viewModel = BookmarksViewModel()
let state: BookmarkState
var body: some View {
NavigationView {
ZStack {
if viewModel.isLoading {
ProgressView()
} else {
List(viewModel.bookmarks, id: \.id) { bookmark in
NavigationLink(destination: BookmarkDetailView(bookmarkId: bookmark.id)) {
BookmarkCardView(bookmark: bookmark)
}
}
.refreshable {
await viewModel.loadBookmarks()
}
.overlay {
if viewModel.bookmarks.isEmpty && !viewModel.isLoading {
ContentUnavailableView(
"Keine Bookmarks",
systemImage: "bookmark",
description: Text("Es wurden noch keine Bookmarks gespeichert.")
)
}
}
}
}
.navigationTitle(state.displayName)
.alert("Fehler", isPresented: .constant(viewModel.errorMessage != nil)) {
Button("OK", role: .cancel) { }
} message: {
Text(viewModel.errorMessage ?? "")
}
.task {
await viewModel.loadBookmarks(state: state)
}
}
}
}
// Unterkomponente für die Darstellung eines einzelnen Bookmarks
private struct BookmarkRow: View {
let bookmark: Bookmark
var body: some View {
NavigationLink(destination: BookmarkDetailView(bookmarkId: bookmark.id)) {
VStack(alignment: .leading, spacing: 4) {
Text(bookmark.title)
.font(.headline)
Text(bookmark.url)
.font(.caption)
.foregroundColor(.secondary)
Text(bookmark.created)
.font(.caption2)
.foregroundColor(.secondary)
}
.padding(.vertical, 4)
}
}
}