mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-11-04 04:04:18 +00:00 
			
		
		
		
	Start to work on create account form
This commit is contained in:
		
							
								
								
									
										205
									
								
								lib/ui/routes/create_account_route.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								lib/ui/routes/create_account_route.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,205 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/utils/input_utils.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/utils/intl_utils.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Create account route
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// @author Pierre HUBERT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CreateAccountRoute extends StatelessWidget {
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return Scaffold(
 | 
				
			||||||
 | 
					      appBar: AppBar(
 | 
				
			||||||
 | 
					        title: Text(tr("Create an account")),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					      body: _CreateAccountRouteBody(),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _CreateAccountRouteBody extends StatefulWidget {
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  __CreateAccountRouteBodyState createState() =>
 | 
				
			||||||
 | 
					      __CreateAccountRouteBodyState();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class __CreateAccountRouteBodyState extends State<_CreateAccountRouteBody> {
 | 
				
			||||||
 | 
					  final _firstNameController = TextEditingController();
 | 
				
			||||||
 | 
					  final _lastNameController = TextEditingController();
 | 
				
			||||||
 | 
					  final _emailController = TextEditingController();
 | 
				
			||||||
 | 
					  final _passwordController = TextEditingController();
 | 
				
			||||||
 | 
					  final _verifyPasswordController = TextEditingController();
 | 
				
			||||||
 | 
					  bool _acceptedTOS = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool _showErrors = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool get _isFirstNameValid => _firstNameController.text.length > 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool get _isLastNameValid => _lastNameController.text.length > 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool get _isEmailValid => validateEmail(_emailController.text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool get _isPasswordValid => _passwordController.text.length > 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool get _isPasswordConfirmationValid =>
 | 
				
			||||||
 | 
					      _passwordController.text == _verifyPasswordController.text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool get _isFormValid =>
 | 
				
			||||||
 | 
					      _isFirstNameValid &&
 | 
				
			||||||
 | 
					      _isLastNameValid &&
 | 
				
			||||||
 | 
					      _isEmailValid &&
 | 
				
			||||||
 | 
					      _isPasswordValid &&
 | 
				
			||||||
 | 
					      _isPasswordConfirmationValid &&
 | 
				
			||||||
 | 
					      _acceptedTOS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return Padding(
 | 
				
			||||||
 | 
					      padding: const EdgeInsets.all(8.0),
 | 
				
			||||||
 | 
					      child: ListView(
 | 
				
			||||||
 | 
					        children: <Widget>[
 | 
				
			||||||
 | 
					          // First name
 | 
				
			||||||
 | 
					          _InputEntry(
 | 
				
			||||||
 | 
					            controller: _firstNameController,
 | 
				
			||||||
 | 
					            label: tr("First name"),
 | 
				
			||||||
 | 
					            onEdited: _updateUI,
 | 
				
			||||||
 | 
					            icon: Icon(Icons.perm_identity),
 | 
				
			||||||
 | 
					            error: _showErrors && !_isFirstNameValid
 | 
				
			||||||
 | 
					                ? tr("Invalid first name!")
 | 
				
			||||||
 | 
					                : null,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // Last name
 | 
				
			||||||
 | 
					          _InputEntry(
 | 
				
			||||||
 | 
					            controller: _lastNameController,
 | 
				
			||||||
 | 
					            label: tr("Last name"),
 | 
				
			||||||
 | 
					            onEdited: _updateUI,
 | 
				
			||||||
 | 
					            icon: Icon(Icons.perm_identity),
 | 
				
			||||||
 | 
					            error: _showErrors && !_isLastNameValid
 | 
				
			||||||
 | 
					                ? tr("Invalid last name!")
 | 
				
			||||||
 | 
					                : null,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // Email address
 | 
				
			||||||
 | 
					          _InputEntry(
 | 
				
			||||||
 | 
					            controller: _emailController,
 | 
				
			||||||
 | 
					            label: tr("Email address"),
 | 
				
			||||||
 | 
					            onEdited: _updateUI,
 | 
				
			||||||
 | 
					            icon: Icon(Icons.email),
 | 
				
			||||||
 | 
					            keyboard: TextInputType.emailAddress,
 | 
				
			||||||
 | 
					            error: _showErrors && !_isEmailValid
 | 
				
			||||||
 | 
					                ? tr("Invalid email address!")
 | 
				
			||||||
 | 
					                : null,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // Password
 | 
				
			||||||
 | 
					          _InputEntry(
 | 
				
			||||||
 | 
					            controller: _passwordController,
 | 
				
			||||||
 | 
					            label: tr("Password"),
 | 
				
			||||||
 | 
					            onEdited: _updateUI,
 | 
				
			||||||
 | 
					            icon: Icon(Icons.lock),
 | 
				
			||||||
 | 
					            isPassword: true,
 | 
				
			||||||
 | 
					            error: _showErrors && !_isPasswordValid
 | 
				
			||||||
 | 
					                ? tr("Invalid password!")
 | 
				
			||||||
 | 
					                : null,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // Verify password
 | 
				
			||||||
 | 
					          _InputEntry(
 | 
				
			||||||
 | 
					            controller: _verifyPasswordController,
 | 
				
			||||||
 | 
					            label: tr("Confirm your password"),
 | 
				
			||||||
 | 
					            onEdited: _updateUI,
 | 
				
			||||||
 | 
					            icon: Icon(Icons.lock_outline),
 | 
				
			||||||
 | 
					            isPassword: true,
 | 
				
			||||||
 | 
					            error: _showErrors && !_isPasswordConfirmationValid
 | 
				
			||||||
 | 
					                ? tr("The password and its confirmation do not match!")
 | 
				
			||||||
 | 
					                : null,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // TOSs
 | 
				
			||||||
 | 
					          CheckboxListTile(
 | 
				
			||||||
 | 
					            title: Text("I have read and accepted the Term Of Service."),
 | 
				
			||||||
 | 
					            value: _acceptedTOS,
 | 
				
			||||||
 | 
					            onChanged: (b) {
 | 
				
			||||||
 | 
					              _acceptedTOS = b;
 | 
				
			||||||
 | 
					              _updateUI();
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            subtitle: _showErrors && !_acceptedTOS
 | 
				
			||||||
 | 
					                ? Text(
 | 
				
			||||||
 | 
					                    tr("You must accept the Term Of Service to continue."),
 | 
				
			||||||
 | 
					                    style: TextStyle(color: Colors.redAccent),
 | 
				
			||||||
 | 
					                  )
 | 
				
			||||||
 | 
					                : null,
 | 
				
			||||||
 | 
					            controlAffinity: ListTileControlAffinity.leading,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // Submit button
 | 
				
			||||||
 | 
					          Center(
 | 
				
			||||||
 | 
					            child: RaisedButton(
 | 
				
			||||||
 | 
					              color: Colors.blue,
 | 
				
			||||||
 | 
					              textColor: Colors.white,
 | 
				
			||||||
 | 
					              onPressed: _submitForm,
 | 
				
			||||||
 | 
					              child: Text("Submit"),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void _updateUI() {
 | 
				
			||||||
 | 
					    setState(() {
 | 
				
			||||||
 | 
					      // Nothing yet
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void _submitForm() {
 | 
				
			||||||
 | 
					    if (!_isFormValid) {
 | 
				
			||||||
 | 
					      _showErrors = true;
 | 
				
			||||||
 | 
					      _updateUI();
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _InputEntry extends StatelessWidget {
 | 
				
			||||||
 | 
					  final TextEditingController controller;
 | 
				
			||||||
 | 
					  final String label;
 | 
				
			||||||
 | 
					  final VoidCallback onEdited;
 | 
				
			||||||
 | 
					  final bool isPassword;
 | 
				
			||||||
 | 
					  final String error;
 | 
				
			||||||
 | 
					  final Widget icon;
 | 
				
			||||||
 | 
					  final TextInputType keyboard;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const _InputEntry({
 | 
				
			||||||
 | 
					    Key key,
 | 
				
			||||||
 | 
					    @required this.controller,
 | 
				
			||||||
 | 
					    @required this.label,
 | 
				
			||||||
 | 
					    @required this.onEdited,
 | 
				
			||||||
 | 
					    this.isPassword = false,
 | 
				
			||||||
 | 
					    this.error,
 | 
				
			||||||
 | 
					    this.icon,
 | 
				
			||||||
 | 
					    this.keyboard,
 | 
				
			||||||
 | 
					  })  : assert(controller != null),
 | 
				
			||||||
 | 
					        assert(label != null),
 | 
				
			||||||
 | 
					        assert(onEdited != null),
 | 
				
			||||||
 | 
					        assert(isPassword != null),
 | 
				
			||||||
 | 
					        super(key: key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return TextField(
 | 
				
			||||||
 | 
					      controller: controller,
 | 
				
			||||||
 | 
					      onChanged: (s) => onEdited(),
 | 
				
			||||||
 | 
					      keyboardType: keyboard,
 | 
				
			||||||
 | 
					      obscureText: isPassword,
 | 
				
			||||||
 | 
					      decoration: InputDecoration(
 | 
				
			||||||
 | 
					        alignLabelWithHint: true,
 | 
				
			||||||
 | 
					        errorText: error,
 | 
				
			||||||
 | 
					        labelText: label,
 | 
				
			||||||
 | 
					        icon: icon,
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
import 'package:comunic/helpers/account_helper.dart';
 | 
					import 'package:comunic/helpers/account_helper.dart';
 | 
				
			||||||
import 'package:comunic/models/authentication_details.dart';
 | 
					import 'package:comunic/models/authentication_details.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/ui/routes/create_account_route.dart';
 | 
				
			||||||
import 'package:comunic/ui/routes/home_route.dart';
 | 
					import 'package:comunic/ui/routes/home_route.dart';
 | 
				
			||||||
import 'package:comunic/utils/input_utils.dart';
 | 
					import 'package:comunic/utils/input_utils.dart';
 | 
				
			||||||
import 'package:comunic/utils/intl_utils.dart';
 | 
					import 'package:comunic/utils/intl_utils.dart';
 | 
				
			||||||
@@ -59,7 +60,12 @@ class _LoginRouteState extends State<LoginRoute> {
 | 
				
			|||||||
      });
 | 
					      });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Build error card
 | 
					  void _openCreateAccountPage() {
 | 
				
			||||||
 | 
					    Navigator.of(context)
 | 
				
			||||||
 | 
					        .push(MaterialPageRoute(builder: (c) => CreateAccountRoute()));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Build error card
 | 
				
			||||||
  Widget _buildErrorCard() {
 | 
					  Widget _buildErrorCard() {
 | 
				
			||||||
    if (_authResult == null) return null;
 | 
					    if (_authResult == null) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -119,7 +125,15 @@ class _LoginRouteState extends State<LoginRoute> {
 | 
				
			|||||||
                      child: Text(tr("Sign in")),
 | 
					                      child: Text(tr("Sign in")),
 | 
				
			||||||
                      onPressed: valid ? () => _submitForm(context) : null,
 | 
					                      onPressed: valid ? () => _submitForm(context) : null,
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
            )
 | 
					            ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            InkWell(
 | 
				
			||||||
 | 
					              child: Text(
 | 
				
			||||||
 | 
					                tr("Create an account"),
 | 
				
			||||||
 | 
					                style: TextStyle(color: Colors.blue),
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
 | 
					              onTap: () => _openCreateAccountPage(),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user