@@ -133,177 +133,180 @@ class _SupaEmailAuthState extends State<SupaEmailAuth> {
133
133
@override
134
134
Widget build (BuildContext context) {
135
135
final localization = widget.localization;
136
- return Form (
137
- key: _formKey,
138
- child: Column (
139
- crossAxisAlignment: CrossAxisAlignment .stretch,
140
- children: [
141
- TextFormField (
142
- keyboardType: TextInputType .emailAddress,
143
- autofillHints: const [AutofillHints .email],
144
- validator: (value) {
145
- if (value == null ||
146
- value.isEmpty ||
147
- ! EmailValidator .validate (_emailController.text)) {
148
- return localization.validEmailError;
149
- }
150
- return null ;
151
- },
152
- decoration: InputDecoration (
153
- prefixIcon: const Icon (Icons .email),
154
- label: Text (localization.enterEmail),
155
- ),
156
- controller: _emailController,
157
- ),
158
- if (! _forgotPassword) ...[
159
- spacer (16 ),
136
+ return AutofillGroup (
137
+ child: Form (
138
+ key: _formKey,
139
+ child: Column (
140
+ crossAxisAlignment: CrossAxisAlignment .stretch,
141
+ children: [
160
142
TextFormField (
161
- autofillHints: _isSigningIn
162
- ? [AutofillHints .password]
163
- : [AutofillHints .newPassword],
143
+ keyboardType: TextInputType .emailAddress,
144
+ autofillHints: const [AutofillHints .email],
164
145
validator: (value) {
165
- if (value == null || value.isEmpty || value.length < 6 ) {
166
- return localization.passwordLengthError;
146
+ if (value == null ||
147
+ value.isEmpty ||
148
+ ! EmailValidator .validate (_emailController.text)) {
149
+ return localization.validEmailError;
167
150
}
168
151
return null ;
169
152
},
170
153
decoration: InputDecoration (
171
- prefixIcon: const Icon (Icons .lock ),
172
- label: Text (localization.enterPassword ),
154
+ prefixIcon: const Icon (Icons .email ),
155
+ label: Text (localization.enterEmail ),
173
156
),
174
- obscureText: true ,
175
- controller: _passwordController,
157
+ controller: _emailController,
176
158
),
177
- spacer (16 ),
178
- if (widget.metadataFields != null && ! _isSigningIn)
179
- ...widget.metadataFields!
180
- .map ((metadataField) => [
181
- TextFormField (
182
- controller: _metadataControllers[metadataField],
183
- decoration: InputDecoration (
184
- label: Text (metadataField.label),
185
- prefixIcon: metadataField.prefixIcon,
159
+ if (! _forgotPassword) ...[
160
+ spacer (16 ),
161
+ TextFormField (
162
+ autofillHints: _isSigningIn
163
+ ? [AutofillHints .password]
164
+ : [AutofillHints .newPassword],
165
+ validator: (value) {
166
+ if (value == null || value.isEmpty || value.length < 6 ) {
167
+ return localization.passwordLengthError;
168
+ }
169
+ return null ;
170
+ },
171
+ decoration: InputDecoration (
172
+ prefixIcon: const Icon (Icons .lock),
173
+ label: Text (localization.enterPassword),
174
+ ),
175
+ obscureText: true ,
176
+ controller: _passwordController,
177
+ ),
178
+ spacer (16 ),
179
+ if (widget.metadataFields != null && ! _isSigningIn)
180
+ ...widget.metadataFields!
181
+ .map ((metadataField) => [
182
+ TextFormField (
183
+ controller: _metadataControllers[metadataField],
184
+ decoration: InputDecoration (
185
+ label: Text (metadataField.label),
186
+ prefixIcon: metadataField.prefixIcon,
187
+ ),
188
+ validator: metadataField.validator,
186
189
),
187
- validator: metadataField.validator,
190
+ spacer (16 ),
191
+ ])
192
+ .expand ((element) => element),
193
+ ElevatedButton (
194
+ child: (_isLoading)
195
+ ? SizedBox (
196
+ height: 16 ,
197
+ width: 16 ,
198
+ child: CircularProgressIndicator (
199
+ color: Theme .of (context).colorScheme.onPrimary,
200
+ strokeWidth: 1.5 ,
188
201
),
189
- spacer (16 ),
190
- ])
191
- .expand ((element) => element),
192
- ElevatedButton (
193
- child: (_isLoading)
194
- ? SizedBox (
195
- height: 16 ,
196
- width: 16 ,
197
- child: CircularProgressIndicator (
198
- color: Theme .of (context).colorScheme.onPrimary,
199
- strokeWidth: 1.5 ,
200
- ),
201
- )
202
- : Text (
203
- _isSigningIn ? localization.signIn : localization.signUp),
204
- onPressed: () async {
205
- if (! _formKey.currentState! .validate ()) {
206
- return ;
207
- }
208
- setState (() {
209
- _isLoading = true ;
210
- });
211
- try {
212
- if (_isSigningIn) {
213
- final response = await supabase.auth.signInWithPassword (
214
- email: _emailController.text.trim (),
215
- password: _passwordController.text.trim (),
216
- );
217
- widget.onSignInComplete.call (response);
218
- } else {
219
- final response = await supabase.auth.signUp (
220
- email: _emailController.text.trim (),
221
- password: _passwordController.text.trim (),
222
- emailRedirectTo: widget.redirectTo,
223
- data: _resolveData (),
224
- );
225
- widget.onSignUpComplete.call (response);
226
- }
227
- } on AuthException catch (error) {
228
- if (widget.onError == null && context.mounted) {
229
- context.showErrorSnackBar (error.message);
230
- } else {
231
- widget.onError? .call (error);
232
- }
233
- } catch (error) {
234
- if (widget.onError == null && context.mounted) {
235
- context.showErrorSnackBar (
236
- '${localization .unexpectedError }: $error ' );
237
- } else {
238
- widget.onError? .call (error);
202
+ )
203
+ : Text (_isSigningIn
204
+ ? localization.signIn
205
+ : localization.signUp),
206
+ onPressed: () async {
207
+ if (! _formKey.currentState! .validate ()) {
208
+ return ;
239
209
}
240
- }
241
- if (mounted) {
242
210
setState (() {
243
- _isLoading = false ;
211
+ _isLoading = true ;
244
212
});
245
- }
246
- },
247
- ),
248
- spacer (16 ),
249
- if (_isSigningIn) ...[
213
+ try {
214
+ if (_isSigningIn) {
215
+ final response = await supabase.auth.signInWithPassword (
216
+ email: _emailController.text.trim (),
217
+ password: _passwordController.text.trim (),
218
+ );
219
+ widget.onSignInComplete.call (response);
220
+ } else {
221
+ final response = await supabase.auth.signUp (
222
+ email: _emailController.text.trim (),
223
+ password: _passwordController.text.trim (),
224
+ emailRedirectTo: widget.redirectTo,
225
+ data: _resolveData (),
226
+ );
227
+ widget.onSignUpComplete.call (response);
228
+ }
229
+ } on AuthException catch (error) {
230
+ if (widget.onError == null && context.mounted) {
231
+ context.showErrorSnackBar (error.message);
232
+ } else {
233
+ widget.onError? .call (error);
234
+ }
235
+ } catch (error) {
236
+ if (widget.onError == null && context.mounted) {
237
+ context.showErrorSnackBar (
238
+ '${localization .unexpectedError }: $error ' );
239
+ } else {
240
+ widget.onError? .call (error);
241
+ }
242
+ }
243
+ if (mounted) {
244
+ setState (() {
245
+ _isLoading = false ;
246
+ });
247
+ }
248
+ },
249
+ ),
250
+ spacer (16 ),
251
+ if (_isSigningIn) ...[
252
+ TextButton (
253
+ onPressed: () {
254
+ setState (() {
255
+ _forgotPassword = true ;
256
+ });
257
+ },
258
+ child: Text (localization.forgotPassword),
259
+ ),
260
+ ],
250
261
TextButton (
262
+ key: const ValueKey ('toggleSignInButton' ),
251
263
onPressed: () {
252
264
setState (() {
253
- _forgotPassword = true ;
265
+ _forgotPassword = false ;
266
+ _isSigningIn = ! _isSigningIn;
254
267
});
255
268
},
256
- child: Text (localization.forgotPassword),
269
+ child: Text (_isSigningIn
270
+ ? localization.dontHaveAccount
271
+ : localization.haveAccount),
257
272
),
258
273
],
259
- TextButton (
260
- key: const ValueKey ('toggleSignInButton' ),
261
- onPressed: () {
262
- setState (() {
263
- _forgotPassword = false ;
264
- _isSigningIn = ! _isSigningIn;
265
- });
266
- },
267
- child: Text (_isSigningIn
268
- ? localization.dontHaveAccount
269
- : localization.haveAccount),
270
- ),
271
- ],
272
- if (_isSigningIn && _forgotPassword) ...[
273
- spacer (16 ),
274
- ElevatedButton (
275
- onPressed: () async {
276
- try {
277
- if (! _formKey.currentState! .validate ()) {
278
- return ;
274
+ if (_isSigningIn && _forgotPassword) ...[
275
+ spacer (16 ),
276
+ ElevatedButton (
277
+ onPressed: () async {
278
+ try {
279
+ if (! _formKey.currentState! .validate ()) {
280
+ return ;
281
+ }
282
+ setState (() {
283
+ _isLoading = true ;
284
+ });
285
+
286
+ final email = _emailController.text.trim ();
287
+ await supabase.auth.resetPasswordForEmail (email);
288
+ widget.onPasswordResetEmailSent? .call ();
289
+ } on AuthException catch (error) {
290
+ widget.onError? .call (error);
291
+ } catch (error) {
292
+ widget.onError? .call (error);
279
293
}
294
+ },
295
+ child: Text (localization.sendPasswordReset),
296
+ ),
297
+ spacer (16 ),
298
+ TextButton (
299
+ onPressed: () {
280
300
setState (() {
281
- _isLoading = true ;
301
+ _forgotPassword = false ;
282
302
});
283
-
284
- final email = _emailController.text.trim ();
285
- await supabase.auth.resetPasswordForEmail (email);
286
- widget.onPasswordResetEmailSent? .call ();
287
- } on AuthException catch (error) {
288
- widget.onError? .call (error);
289
- } catch (error) {
290
- widget.onError? .call (error);
291
- }
292
- },
293
- child: Text (localization.sendPasswordReset),
294
- ),
303
+ },
304
+ child: Text (localization.backToSignIn),
305
+ ),
306
+ ],
295
307
spacer (16 ),
296
- TextButton (
297
- onPressed: () {
298
- setState (() {
299
- _forgotPassword = false ;
300
- });
301
- },
302
- child: Text (localization.backToSignIn),
303
- ),
304
308
],
305
- spacer (16 ),
306
- ],
309
+ ),
307
310
),
308
311
);
309
312
}
0 commit comments