wordeck-native/Sources/Features/Editor/CSVImportFormSections.swift
Till JS edc60056ea icon: Icon-Composer-App-Icon + macOS-Build grün
- AppIcon.icon (Icon Composer, blaues W) als App-Icon integriert.
  In project.yml als Target-Source mit type:file → XcodeGen erkennt
  .icon nativ als wrapper.icon. Alter forest-grüner Platzhalter
  (AppIcon.appiconset) entfernt. actool baut Icon für iOS + macOS.
- macOS-Build repariert (war pre-existing rot seit β-3/β-5/β-6):
  iOS-only SwiftUI-Modifier mit #if os(iOS) gegated
  (textInputAutocapitalization, keyboardType, navigationBarDrawer,
  tabViewBottomAccessory, .buttonStyle(.glass)); .topBarTrailing →
  cross-platform .primaryAction; .bottomBar-Toolbar gekapselt;
  iOS-only Extensions mit platformFilter:iOS an den embed-Deps.
- Verifiziert: iOS-Sim + macOS BUILD SUCCEEDED.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 17:52:12 +02:00

80 lines
2.5 KiB
Swift

import SwiftUI
/// CSV-Import-Form für den `.csv`-Sub-Modus in `DeckEditorView`. Zeigt
/// File-Picker-Button, Deck-Namens-Feld und eine Preview-Liste der
/// erkannten Karten.
///
/// State (Datei-Picker-Bool, geparste Rows, Deck-Name) lebt im Parent
/// dieser View arbeitet nur über `@Binding`.
struct CSVImportFormSections: View {
@Binding var rows: [CSVRow]
@Binding var deckName: String
@Binding var showImporter: Bool
var body: some View {
Section {
Button {
showImporter = true
} label: {
Label(rows.isEmpty ? "CSV-Datei wählen" : "Andere Datei wählen", systemImage: "doc.text")
}
} header: {
Text("Datei")
} footer: {
Text("Format pro Zeile: vorne,hinten,typ. Typ-Spalte optional (Default basic).")
}
if !rows.isEmpty {
Section("Deck-Name") {
TextField("Deck-Name", text: $deckName)
#if os(iOS)
.textInputAutocapitalization(.sentences)
#endif
}
Section {
preview
} header: {
Text("Vorschau (\(rows.count) Karten)")
}
}
}
@ViewBuilder
private var preview: some View {
let visible = rows.prefix(8)
ForEach(Array(visible.enumerated()), id: \.offset) { _, row in
VStack(alignment: .leading, spacing: 4) {
Text(row.front)
.font(.subheadline)
.lineLimit(2)
.foregroundStyle(WordeckTheme.foreground)
Text(row.back)
.font(.caption)
.lineLimit(2)
.foregroundStyle(WordeckTheme.mutedForeground)
if row.type != .basic {
Text(typeLabel(row.type))
.font(.caption2)
.foregroundStyle(WordeckTheme.primary)
}
}
.padding(.vertical, 2)
}
if rows.count > visible.count {
Text("… und \(rows.count - visible.count) weitere")
.font(.caption)
.foregroundStyle(WordeckTheme.mutedForeground)
}
}
private func typeLabel(_ type: CardType) -> String {
switch type {
case .basic: "Einfach"
case .basicReverse: "Beidseitig"
case .cloze: "Lückentext"
case .typing: "Eintippen"
case .multipleChoice: "Multiple Choice"
}
}
}