feat(mission): Ajout du composant MissionCard utilisé pour la vue globale à venir

This commit is contained in:
CreepsoOff 2026-06-26 11:04:09 +02:00
parent 31cb949403
commit e16c0bbf41
No known key found for this signature in database

View file

@ -0,0 +1,143 @@
//
// MissionCard.swift
// urbancanvas
//
// Created by Apprenant154 on 25/06/2026.
//
import SwiftUI
struct MissionCard: View {
let numero: Int
let oeuvre: Oeuvre
var onMarquerDecouverte: () -> Void
private var auteurNom: String {
MockData.auteur(for: oeuvre)?.nom ?? "Auteur inconnu"
}
var body: some View {
VStack(alignment: .leading, spacing: 12) {
Color.clear
.frame(maxWidth: .infinity)
.frame(height: 185)
.background {
Image(oeuvre.imageName)
.resizable()
.scaledToFill()
.allowsHitTesting(false)
}
.clipped()
.clipShape(.rect(cornerRadius: 20))
.overlay(alignment: .topLeading) {
Text("\(numero)")
.font(.headline)
.fontWeight(.bold)
.foregroundStyle(.white)
.frame(width: 34, height: 34)
.background(Color.accentColor.gradient)
.clipShape(.circle)
.padding(10)
}
Text(oeuvre.nom)
.font(.title3)
.fontWeight(.bold)
VStack(alignment: .leading, spacing: 2) {
InfoText(titre: "Type", valeur: oeuvre.type.rawValue)
.font(.subheadline)
InfoText(titre: "Auteur", valeur: auteurNom)
.font(.subheadline)
InfoText(titre: "Localisation", valeur: oeuvre.localisation.adresseComplete)
.font(.subheadline)
.lineLimit(2)
.minimumScaleFactor(0.85)
}
HStack(spacing: 8) {
Button {
onMarquerDecouverte()
} label: {
Text(oeuvre.estDecouverte ? "Découverte ✓" : "Marquer comme découverte")
.fontWeight(.semibold)
.lineLimit(1)
.minimumScaleFactor(0.75)
}
.tint(.orangeSecondary)
.buttonStyle(.borderedProminent)
.disabled(oeuvre.estDecouverte)
Spacer()
NavigationLink(value: oeuvre) {
Label("Voir", systemImage: "arrow.forward")
.fontWeight(.semibold)
}
.tint(.accent)
.buttonStyle(.bordered)
}
}
.padding(12)
.frame(maxWidth: .infinity, alignment: .leading)
.background(.background)
.clipShape(RoundedRectangle(cornerRadius: 28))
}
}
#Preview("2") {
let store = MissionStore()
let oeuvre = MockData.oeuvres.first { $0.id == "tigre-et-cigale" }!
NavigationStack {
ScrollView {
MissionCard(
numero: 1,
oeuvre: oeuvre,
onMarquerDecouverte: { store.marquerCommeDecouverte(oeuvre) }
)
.padding()
}
.background(.bgGray)
.navigationDestination(for: Oeuvre.self) { OeuvreDetaille_View(oeuvre: $0) }
}
}
#Preview {
@Previewable @State var oeuvre = MockData.oeuvres[14]
let store = MissionStore()
NavigationStack {
ScrollView {
MissionCard(
numero: 1,
oeuvre: oeuvre,
onMarquerDecouverte: { store.marquerCommeDecouverte(oeuvre) }
)
.padding()
}
.background(.bgGray)
.navigationDestination(for: Oeuvre.self) { oeuvre in
OeuvreDetaille_View(oeuvre: oeuvre)
}
}
}
#Preview("Sans ScrollView") {
@Previewable @State var oeuvre = MockData.oeuvres[2]
let store = MissionStore()
MissionCard(
numero: 1,
oeuvre: oeuvre,
onMarquerDecouverte: { store.marquerCommeDecouverte(oeuvre) }
)
}