feat: ios mobil arayüz tasarımı
This commit is contained in:
71
ios/Bookibra/Views/Category/CategoryListView.swift
Normal file
71
ios/Bookibra/Views/Category/CategoryListView.swift
Normal file
@@ -0,0 +1,71 @@
|
||||
import SwiftUI
|
||||
import SwiftData
|
||||
|
||||
struct CategoryListView: View {
|
||||
@EnvironmentObject private var router: AppRouter
|
||||
@Query(sort: \LibraryBook.dateAdded, order: .reverse) private var allBooks: [LibraryBook]
|
||||
@ObservedObject var viewModel: CategoryViewModel
|
||||
|
||||
var body: some View {
|
||||
let books = viewModel.books(from: allBooks)
|
||||
|
||||
VStack {
|
||||
HStack {
|
||||
TextField("Search", text: $viewModel.searchText)
|
||||
.textFieldStyle(.roundedBorder)
|
||||
Menu {
|
||||
ForEach(CategoryViewModel.SortOption.allCases, id: \.self) { option in
|
||||
Button(option.rawValue) { viewModel.sortOption = option }
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "arrow.up.arrow.down.circle")
|
||||
.font(.title3)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal)
|
||||
|
||||
ScrollView {
|
||||
LazyVGrid(columns: [GridItem(.adaptive(minimum: 104), spacing: 12)], spacing: 16) {
|
||||
ForEach(books, id: \.localId) { book in
|
||||
let remote = BookRemote(
|
||||
title: book.title,
|
||||
authors: book.authors,
|
||||
publishedYear: book.publishedYear,
|
||||
isbn10: book.isbn10,
|
||||
isbn13: book.isbn13,
|
||||
coverImageUrl: book.coverUrlString.flatMap(URL.init(string:)),
|
||||
language: book.language,
|
||||
description: book.summary,
|
||||
categories: book.categories
|
||||
)
|
||||
|
||||
Button {
|
||||
router.path.append(.detail(remote))
|
||||
} label: {
|
||||
VStack(alignment: .leading, spacing: 6) {
|
||||
AsyncImage(url: remote.coverImageUrl) { phase in
|
||||
if let image = phase.image {
|
||||
image.resizable().scaledToFill()
|
||||
} else {
|
||||
RoundedRectangle(cornerRadius: 10).fill(Color.gray.opacity(0.2))
|
||||
}
|
||||
}
|
||||
.frame(height: 154)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 10))
|
||||
|
||||
Text(book.title)
|
||||
.font(.caption)
|
||||
.lineLimit(2)
|
||||
.foregroundStyle(.primary)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.horizontal)
|
||||
}
|
||||
}
|
||||
.navigationTitle(viewModel.categoryName)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.background(Theme.background.ignoresSafeArea())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user