@@ -18,6 +18,7 @@ import SwiftUI
1818@MainActor
1919public struct SignedInView {
2020 @Environment ( AuthService . self) private var authService
21+ @State private var showDeleteConfirmation = false
2122}
2223
2324extension SignedInView : View {
@@ -63,38 +64,108 @@ extension SignedInView: View {
6364 . buttonStyle ( . borderedProminent)
6465 . accessibilityIdentifier ( " mfa-management-button " )
6566 Button ( action: {
66- Task {
67- try ? await authService. signOut ( )
68- }
67+ showDeleteConfirmation = true
6968 } ) {
70- Text ( authService. string. signOutButtonLabel )
69+ Text ( authService. string. deleteAccountButtonLabel )
7170 . padding ( . vertical, 8 )
7271 . frame ( maxWidth: . infinity)
7372 }
7473 . padding ( [ . top, . bottom] , 8 )
7574 . frame ( maxWidth: . infinity)
7675 . buttonStyle ( . borderedProminent)
77- . accessibilityIdentifier ( " sign-out -button" )
76+ . accessibilityIdentifier ( " delete-account -button" )
7877 Button ( action: {
7978 Task {
80- try ? await authService. deleteUser ( )
79+ try ? await authService. signOut ( )
8180 }
8281 } ) {
83- Text ( authService. string. deleteAccountButtonLabel )
82+ Text ( authService. string. signOutButtonLabel )
8483 . padding ( . vertical, 8 )
8584 . frame ( maxWidth: . infinity)
8685 }
8786 . padding ( [ . top, . bottom] , 8 )
8887 . frame ( maxWidth: . infinity)
8988 . buttonStyle ( . borderedProminent)
89+ . accessibilityIdentifier ( " sign-out-button " )
9090 }
9191 . safeAreaPadding ( )
92+ . sheet ( isPresented: $showDeleteConfirmation) {
93+ DeleteAccountConfirmationSheet (
94+ onConfirm: {
95+ showDeleteConfirmation = false
96+ Task {
97+ try ? await authService. deleteUser ( )
98+ }
99+ } ,
100+ onCancel: {
101+ showDeleteConfirmation = false
102+ }
103+ )
104+ . presentationDetents ( [ . medium] )
105+ }
92106 . sheet ( isPresented: isShowingPasswordPrompt) {
93107 PasswordPromptSheet ( coordinator: authService. passwordPrompt)
94108 }
95109 }
96110}
97111
112+ private struct DeleteAccountConfirmationSheet : View {
113+ @Environment ( AuthService . self) private var authService
114+ let onConfirm : ( ) -> Void
115+ let onCancel : ( ) -> Void
116+
117+ var body : some View {
118+ VStack ( spacing: 24 ) {
119+ VStack ( spacing: 12 ) {
120+ Image ( systemName: " exclamationmark.triangle.fill " )
121+ . font ( . system( size: 60 ) )
122+ . foregroundColor ( . red)
123+
124+ Text ( " Delete Account? " )
125+ . font ( . title)
126+ . fontWeight ( . bold)
127+
128+ Text (
129+ " This action cannot be undone. All your data will be permanently deleted. You may need to reauthenticate to complete this action. "
130+ )
131+ . font ( . body)
132+ . foregroundColor ( . secondary)
133+ . multilineTextAlignment ( . center)
134+ . padding ( . horizontal)
135+ }
136+
137+ VStack ( spacing: 12 ) {
138+ Button {
139+ onConfirm ( )
140+ } label: {
141+ Text ( " Delete Account " )
142+ . padding ( . vertical, 8 )
143+ . frame ( maxWidth: . infinity)
144+ }
145+ . buttonStyle ( . borderedProminent)
146+ . tint ( . red)
147+ . padding ( [ . top, . bottom] , 8 )
148+ . frame ( maxWidth: . infinity)
149+ . accessibilityIdentifier ( " confirm-delete-button " )
150+
151+ Button {
152+ onCancel ( )
153+ } label: {
154+ Text ( " Cancel " )
155+ . padding ( . vertical, 8 )
156+ . frame ( maxWidth: . infinity)
157+ }
158+ . buttonStyle ( . bordered)
159+ . padding ( [ . top, . bottom] , 8 )
160+ . frame ( maxWidth: . infinity)
161+ . accessibilityIdentifier ( " cancel-delete-button " )
162+ }
163+ }
164+ . frame ( maxWidth: . infinity, maxHeight: . infinity, alignment: . top)
165+ . safeAreaPadding ( )
166+ }
167+ }
168+
98169#Preview {
99170 FirebaseOptions . dummyConfigurationForPreview ( )
100171 return SignedInView ( )
0 commit comments