Files
Gas-Tank-AR-App/GasTankAR/Views/ProjectListView.swift
Dennis Nemec b8536d4182 Add tank catalog with USDZ models and tank selection
Introduce TankDefinition/TankCatalog loaded from Tanks.json, bundle the
Drachengas USDZ tank models, add tank selection and preview views, and
update the AR experience, editor and project views to use the catalog.
Includes tests for catalog loading and model selection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 19:12:39 +02:00

102 lines
3.3 KiB
Swift

//
// ProjectListView.swift
// GasTankAR
//
// Created by Dennis Nemec on 25.08.26.
//
import SwiftUI
import SwiftData
struct ProjectListView: View {
@Environment(\.modelContext) private var modelContext
@Query(sort: \Project.creationDate, order: .reverse) private var projects: [Project]
@State private var selectedProject: Project?
@State private var isCreatingProject = false
@State private var isShowingSettings = false
var body: some View {
NavigationSplitView {
List(selection: $selectedProject) {
ForEach(projects) { project in
ProjectListItem(project: project)
.tag(project)
}
.onDelete(perform: deleteProjects)
}
.overlay {
if projects.isEmpty {
ContentUnavailableView(
"Keine Projekte",
systemImage: "tray",
description: Text("Tippe auf +, um dein erstes Projekt zu erstellen.")
)
}
}
.navigationTitle(Text("Projekte"))
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button("Einstellungen", systemImage: "gearshape") {
isShowingSettings = true
}
}
}
.sheet(isPresented: $isShowingSettings) {
SettingsView()
}
.overlay(alignment: .bottomTrailing) {
GlassEffectContainer {
Button {
isCreatingProject = true
} label: {
Image(systemName: "plus")
.font(.title2.weight(.semibold))
.frame(width: 56, height: 56)
.contentShape(.circle)
}
.buttonStyle(.plain)
.glassEffect(.regular.interactive(), in: .circle)
}
.padding()
.accessibilityLabel("Projekt erstellen")
}
.sheet(isPresented: $isCreatingProject) {
ProjectCreateView { project in
selectedProject = project
}
}
} detail: {
NavigationStack {
if let selectedProject {
ProjectDetailView(project: selectedProject)
} else {
ContentUnavailableView(
"Kein Projekt ausgewählt",
systemImage: "hand.point.up.left",
description: Text("Wähle links ein Projekt aus, um die Details zu sehen.")
)
}
}
}
}
private func deleteProjects(at offsets: IndexSet) {
for index in offsets {
let project = projects[index]
if project == selectedProject { selectedProject = nil }
modelContext.delete(project)
}
}
}
#Preview("Gefüllt") {
ProjectListView()
.modelContainer(PreviewSupport.container)
}
#Preview("Leer") {
ProjectListView()
.modelContainer(PreviewSupport.makeEmptyContainer())
}