feat(auth): Guest-Mode + Login-optionale Surface

RootView ohne Hard-Login-Gate — TabBar zeigt sich immer, beim Start
wechselt App bei .signedOut automatisch in den anonymen .guest-Modus
(mana-swift-core v1.2.0). Auth-Sheets (Login, SignUp, Forgot, Reset)
hängen jetzt als ManaAuthGate-Modifier am Root.

AccountView zeigt im Guest-Modus eine eigene CTA-Surface („Anmelden /
Konto erstellen" + Hinweis was Login bringt). signOut nutzt
keepGuestMode: true → App bleibt nach Logout anonym nutzbar, Marketplace
und lokale Daten gehen nicht verloren.

DeckListView: Empty-State im Guest-Mode mit Login-CTA + Marketplace-
Hinweis. Toolbar-„+"-Button via authGate.require gewrappt — Tap aus
dem Guest-Modus öffnet erst das Sign-In-Sheet, danach den Editor.

DeckListStore.refresh() skippt im Guest-Mode (kein 401-Spam). Cache
wird so wie er ist gerendert (heute leer, später Marketplace-Klone).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-05-14 01:23:30 +02:00
parent da6679770b
commit 8ca7bd3636
5 changed files with 276 additions and 160 deletions

View file

@ -1,3 +1,4 @@
import ManaAuthUI
import ManaCore
import SwiftData
import SwiftUI
@ -6,6 +7,7 @@ import SwiftUI
struct CardsNativeApp: App {
let container: ModelContainer
@State private var auth: AuthClient
@State private var authGate: ManaAuthGate
private let mediaCache: MediaCache
init() {
@ -17,6 +19,7 @@ struct CardsNativeApp: App {
let auth = AuthClient(config: AppConfig.manaAppConfig)
auth.bootstrap()
_auth = State(initialValue: auth)
_authGate = State(initialValue: ManaAuthGate(auth: auth))
mediaCache = MediaCache(api: CardsAPI(auth: auth))
Log.app.info("Cardecky starting — auth status: \(String(describing: auth.status), privacy: .public)")
}
@ -25,6 +28,7 @@ struct CardsNativeApp: App {
WindowGroup {
RootView()
.environment(auth)
.environment(authGate)
.environment(\.mediaCache, mediaCache)
.tint(CardsTheme.primary)
}