Fix #34: Abo-Badges selbst-versteckend + IchView-Bereinigung

- ProBadge und MaxBadge verstecken sich intern via StoreManager (eiserne Regel: nie extern mit !isPro/!isMax wrappen)
- AddMomentView und TodayView: MaxBadge nicht mehr bei isMax anzeigen
- ThemePickerView: Inline-PRO-Text durch ProBadge() ersetzt
- IchView: Geschlecht aus Leseansicht entfernt, Picker im Bearbeitungsformular erhalten
- Geschlecht-Picker: Duplikat "Keine Angabe" entfernt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-23 12:20:05 +02:00
parent bf1b49697b
commit 801095d9b9
6 changed files with 38 additions and 29 deletions
+1 -3
View File
@@ -542,9 +542,7 @@ struct AddMomentView: View {
Text("Gesprächsthemen vorschlagen")
.font(.system(size: 14, weight: .medium))
Spacer()
if store.isMax {
MaxBadge()
} else if canUseAI {
if !store.isMax && canUseAI {
Text("\(AIAnalysisService.shared.freeQueriesRemaining) gratis")
.font(.system(size: 10, weight: .bold))
.foregroundStyle(theme.contentTertiary)
+5 -6
View File
@@ -169,14 +169,10 @@ struct IchView: View {
private var infoSection: some View {
VStack(alignment: .leading, spacing: 10) {
// Über mich
let hasUeberMich = !profileStore.gender.isEmpty || !profileStore.location.isEmpty || !profileStore.socialStyle.isEmpty
let hasUeberMich = !profileStore.location.isEmpty || !profileStore.socialStyle.isEmpty
if hasUeberMich {
SectionHeader(title: "Über mich", icon: "person")
VStack(spacing: 0) {
if !profileStore.gender.isEmpty {
infoRow(label: "Geschlecht", value: profileStore.gender)
if !profileStore.location.isEmpty || !profileStore.socialStyle.isEmpty { RowDivider() }
}
if !profileStore.location.isEmpty {
infoRow(label: "Wohnort", value: profileStore.location)
if !profileStore.socialStyle.isEmpty { RowDivider() }
@@ -288,6 +284,7 @@ struct IchEditView: View {
@State private var name: String
@State private var hasBirthday: Bool
@State private var birthday: Date
@State private var gender: String
@State private var occupation: String
@State private var location: String
@@ -508,9 +505,11 @@ struct IchEditView: View {
return name.isEmpty ? "?" : String(name.prefix(2)).uppercased()
}
// MARK: - Gender Picker
private let genderOptions = ["Männlich", "Weiblich", "Divers", "Keine Angabe"]
private let genderOptions = ["Männlich", "Weiblich", "Divers"]
private var genderPickerRow: some View {
HStack(spacing: 12) {
-2
View File
@@ -237,11 +237,9 @@ struct PersonDetailView: View {
Image(systemName: "sparkles")
.font(.system(size: 18))
.foregroundStyle(theme.accent)
if !storeManager.isMax {
MaxBadge()
}
}
}
.padding(.top, 4)
}
}
+22
View File
@@ -258,12 +258,33 @@ struct TagBadge: View {
}
}
// MARK: - Pro Badge
struct ProBadge: View {
@Environment(\.nahbarTheme) var theme
@StateObject private var store = StoreManager.shared
var body: some View {
if !store.isPro {
Text("PRO")
.font(.system(size: 10, weight: .bold))
.foregroundStyle(theme.accent)
.padding(.horizontal, 7)
.padding(.vertical, 3)
.background(theme.accent.opacity(0.10))
.clipShape(Capsule())
}
}
}
// MARK: - Max Badge
struct MaxBadge: View {
@Environment(\.nahbarTheme) var theme
@StateObject private var store = StoreManager.shared
var body: some View {
if !store.isMax {
Text("MAX")
.font(.system(size: 10, weight: .bold))
.foregroundStyle(theme.accent)
@@ -272,6 +293,7 @@ struct MaxBadge: View {
.background(theme.accent.opacity(0.10))
.clipShape(Capsule())
}
}
}
// MARK: - Section Header
+1 -7
View File
@@ -132,13 +132,7 @@ struct ThemePickerView: View {
Spacer()
if id.isPremium && !isActive {
Text("PRO")
.font(.system(size: 10, weight: .bold))
.foregroundStyle(theme.accent)
.padding(.horizontal, 7)
.padding(.vertical, 3)
.background(theme.accent.opacity(0.10))
.clipShape(Capsule())
ProBadge()
}
if isActive {
+1 -3
View File
@@ -524,9 +524,7 @@ struct GiftSuggestionRow: View {
Text("Geschenkidee vorschlagen")
.font(.system(size: 13))
Spacer()
if store.isMax {
MaxBadge()
} else if canUseAI {
if !store.isMax && canUseAI {
Text("\(AIAnalysisService.shared.freeQueriesRemaining) gratis")
.font(.system(size: 10, weight: .bold))
.foregroundStyle(theme.contentTertiary)