@@ -139,7 +139,7 @@ class _LoginPageState extends State<LoginPage> {
139
139
),
140
140
enabledBorder: _createUnderlineInputBorder (),
141
141
icon: Icon (
142
- CupertinoIcons .person ,
142
+ CupertinoIcons .mail ,
143
143
color: Colors .white,
144
144
),
145
145
),
@@ -206,7 +206,12 @@ class _LoginPageState extends State<LoginPage> {
206
206
),
207
207
InkWell (
208
208
onTap: () {
209
- // TODO: buat fitur register
209
+ Navigator .push (
210
+ context,
211
+ MaterialPageRoute (
212
+ builder: (context) => RegisterPage (),
213
+ ),
214
+ );
210
215
},
211
216
child: Text (
212
217
'Join Now' ,
@@ -286,7 +291,6 @@ class _LoginPageState extends State<LoginPage> {
286
291
(_) => false ,
287
292
);
288
293
} else {
289
- await userCredential.user! .sendEmailVerification ();
290
294
_showSnackBar (context, 'Please verify your email' , widthScreen);
291
295
}
292
296
} on FirebaseAuthException catch (error) {
@@ -334,6 +338,217 @@ class _LoginPageState extends State<LoginPage> {
334
338
}
335
339
}
336
340
341
+ class RegisterPage extends StatefulWidget {
342
+ @override
343
+ _RegisterPageState createState () => _RegisterPageState ();
344
+ }
345
+
346
+ class _RegisterPageState extends State <RegisterPage > {
347
+ final formState = GlobalKey <FormState >();
348
+ final controllerEmail = TextEditingController ();
349
+ final controllerPassword = TextEditingController ();
350
+ final firebaseAuth = FirebaseAuth .instance;
351
+ final focusNodeLabelSignUp = FocusNode ();
352
+
353
+ var widthScreen = 0.0 ;
354
+ var isVisiblePassword = false ;
355
+ var isLoading = false ;
356
+
357
+ @override
358
+ Widget build (BuildContext context) {
359
+ final mediaQueryData = MediaQuery .of (context);
360
+ widthScreen = mediaQueryData.size.width;
361
+ return Scaffold (
362
+ body: Stack (
363
+ children: [
364
+ _buildWidgetImageBackground (),
365
+ _buildWidgetOverlayImageBackground (),
366
+ _buildWidgetContent (),
367
+ ],
368
+ ),
369
+ );
370
+ }
371
+
372
+ Widget _buildWidgetContent () {
373
+ return Center (
374
+ child: Container (
375
+ padding: const EdgeInsets .symmetric (horizontal: 16 ),
376
+ width: widthScreen > _mobileExtraLarge ? _mobileExtraLarge : double .infinity,
377
+ child: Column (
378
+ mainAxisAlignment: MainAxisAlignment .center,
379
+ children: [
380
+ _buildWidgetTitleApp (context),
381
+ SizedBox (height: 48 ),
382
+ _buildWidgetFormRegister (),
383
+ ],
384
+ )),
385
+ );
386
+ }
387
+
388
+ Widget _buildWidgetFormRegister () {
389
+ return IgnorePointer (
390
+ ignoring: isLoading,
391
+ child: Form (
392
+ key: formState,
393
+ child: Column (
394
+ crossAxisAlignment: CrossAxisAlignment .center,
395
+ children: [
396
+ Text (
397
+ 'Create Account' ,
398
+ style: Theme .of (context).textTheme.headline6? .copyWith (
399
+ color: Colors .white,
400
+ ),
401
+ ),
402
+ SizedBox (height: 16 ),
403
+ TextFormField (
404
+ controller: controllerEmail,
405
+ decoration: InputDecoration (
406
+ hintText: 'Email' ,
407
+ hintStyle: TextStyle (
408
+ color: Colors .grey[500 ],
409
+ ),
410
+ enabledBorder: _createUnderlineInputBorder (),
411
+ icon: Icon (
412
+ CupertinoIcons .mail,
413
+ color: Colors .white,
414
+ ),
415
+ ),
416
+ style: TextStyle (
417
+ color: Colors .white,
418
+ ),
419
+ keyboardType: TextInputType .emailAddress,
420
+ validator: emailValidator,
421
+ textInputAction: TextInputAction .next,
422
+ ),
423
+ SizedBox (height: 16 ),
424
+ TextFormField (
425
+ controller: controllerPassword,
426
+ decoration: InputDecoration (
427
+ hintText: 'Password' ,
428
+ hintStyle: TextStyle (
429
+ color: Colors .grey[500 ],
430
+ ),
431
+ enabledBorder: _createUnderlineInputBorder (),
432
+ icon: Icon (
433
+ CupertinoIcons .lock,
434
+ color: Colors .white,
435
+ ),
436
+ suffixIcon: InkWell (
437
+ onTap: () => setState (() => isVisiblePassword = ! isVisiblePassword),
438
+ child: Icon (
439
+ isVisiblePassword ? CupertinoIcons .eye : CupertinoIcons .eye_slash,
440
+ color: Colors .grey[500 ],
441
+ size: 20 ,
442
+ ),
443
+ ),
444
+ suffixIconConstraints: BoxConstraints (
445
+ minWidth: 20 ,
446
+ minHeight: 20 ,
447
+ ),
448
+ ),
449
+ style: TextStyle (
450
+ color: Colors .white,
451
+ ),
452
+ obscureText: ! isVisiblePassword,
453
+ obscuringCharacter: '•' ,
454
+ validator: (value) {
455
+ return value == null || value.isEmpty ? 'Enter a password' : null ;
456
+ },
457
+ textInputAction: TextInputAction .go,
458
+ onFieldSubmitted: (value) {
459
+ _doRegisterByEmailAndPassword ();
460
+ },
461
+ ),
462
+ SizedBox (height: 24 ),
463
+ _buildWidgetButtonSignUp (),
464
+ SizedBox (height: 24 ),
465
+ TextButton (
466
+ onPressed: () => Navigator .pop (context),
467
+ child: Text ('Back to signin' ),
468
+ ),
469
+ ],
470
+ ),
471
+ ),
472
+ );
473
+ }
474
+
475
+ Widget _buildWidgetButtonSignUp () {
476
+ Widget ? widgetLoading;
477
+ if (isLoading) {
478
+ if (kIsWeb) {
479
+ widgetLoading = SizedBox (
480
+ width: 20 ,
481
+ height: 20 ,
482
+ child: CircularProgressIndicator (
483
+ valueColor: AlwaysStoppedAnimation <Color >(
484
+ Colors .white,
485
+ ),
486
+ strokeWidth: 2 ,
487
+ ),
488
+ );
489
+ } else {
490
+ widgetLoading = Platform .isIOS || Platform .isMacOS
491
+ ? CupertinoActivityIndicator ()
492
+ : SizedBox (
493
+ width: 20 ,
494
+ height: 20 ,
495
+ child: CircularProgressIndicator (
496
+ valueColor: AlwaysStoppedAnimation <Color >(
497
+ Colors .white,
498
+ ),
499
+ strokeWidth: 2 ,
500
+ ),
501
+ );
502
+ }
503
+ }
504
+ final padding = _setPaddingButton ();
505
+ return ElevatedButton (
506
+ onPressed: () {
507
+ _doRegisterByEmailAndPassword ();
508
+ },
509
+ child: widgetLoading ?? Text ('SIGN UP' ),
510
+ style: ElevatedButton .styleFrom (
511
+ padding: padding,
512
+ ),
513
+ );
514
+ }
515
+
516
+ void _doRegisterByEmailAndPassword () async {
517
+ if (formState.currentState! .validate ()) {
518
+ focusNodeLabelSignUp.requestFocus ();
519
+ try {
520
+ setState (() => isLoading = true );
521
+ final email = controllerEmail.text.trim ();
522
+ final password = controllerPassword.text.trim ();
523
+ final userCredential = await firebaseAuth.createUserWithEmailAndPassword (
524
+ email: email,
525
+ password: password,
526
+ );
527
+ userCredential.user! .sendEmailVerification ();
528
+ setState (() => isLoading = false );
529
+ _showSnackBar (
530
+ context,
531
+ 'We have sent a link verification to your email.' ,
532
+ widthScreen,
533
+ );
534
+ Navigator .pop (context);
535
+ } on FirebaseAuthException catch (error) {
536
+ final errorCode = error.code;
537
+ var errorMessage = '' ;
538
+ if (errorCode == 'weak-password' ) {
539
+ errorMessage = 'The password provided is too weak.' ;
540
+ } else if (errorCode == 'email-already-in-use' ) {
541
+ errorMessage = 'The account already exists for that email.' ;
542
+ } else {
543
+ errorMessage = '$error ' ;
544
+ }
545
+ _showSnackBar (context, errorMessage, widthScreen);
546
+ setState (() => isLoading = false );
547
+ }
548
+ }
549
+ }
550
+ }
551
+
337
552
class HomePage extends StatelessWidget {
338
553
@override
339
554
Widget build (BuildContext context) {
0 commit comments