Created
March 20, 2019 15:20
-
-
Save albertusdev/ba7ba967b37a58e97810b1806767b2b4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'dart:io'; | |
import 'package:flutter/material.dart'; | |
import 'package:learn_fazz/app_config.dart'; | |
import 'package:learn_fazz/models/login_result.dart'; | |
import 'package:learn_fazz/pages/dashboard_page.dart'; | |
import 'package:learn_fazz/repositories/auth_repository.dart'; | |
import 'package:learn_fazz/widgets/image_picker_bottom_sheet.dart'; | |
import '../assets/learn_fazz_icons.dart'; | |
class RegisterFormPage extends StatefulWidget { | |
static String tag = '/register-form-page'; | |
static String kNoImageErrorMessage = | |
'Please choose image first to be able to proceed.'; | |
@override | |
_RegisterFormPageState createState() => _RegisterFormPageState(); | |
} | |
class _RegisterFormPageState extends State<RegisterFormPage> { | |
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); | |
final GlobalKey<FormFieldState<String>> _passKey = | |
GlobalKey<FormFieldState<String>>(); | |
final Color borderColor = Colors.black.withOpacity(0.4); | |
bool passwordVisible = true; | |
bool confirmPasswordVisible = true; | |
bool _isSubmitting = false; | |
String _name; | |
String _email; | |
String _identificationNumber; | |
String _password; | |
String _passwordConfirmation; | |
String _role; | |
File _imageFile; | |
@override | |
Widget build(BuildContext context) { | |
final Widget logo = _imageFile == null | |
? Container( | |
child: CircleAvatar( | |
radius: 72.0, | |
backgroundColor: Colors.blue, | |
foregroundColor: Colors.white, | |
child: const Icon(LearnFazz.camera, size: 50.0), | |
), | |
padding: const EdgeInsets.all(2.0), // border width | |
decoration: const BoxDecoration( | |
color: Colors.white, // border color | |
shape: BoxShape.circle, | |
), | |
) | |
: CircleAvatar( | |
radius: 72.0, | |
child: ClipOval(child: Image.file(_imageFile)), | |
); | |
final Widget addPhotoLabel = InkWell( | |
child: const Text( | |
'Add Photo', | |
key: Key('addPhotoLabel'), | |
style: TextStyle( | |
fontWeight: FontWeight.bold, | |
fontSize: 18.0, | |
decoration: TextDecoration.underline, | |
color: Colors.white), | |
textAlign: TextAlign.center, | |
), | |
onTap: () async { | |
final File _choosenImage = await showImagePickerBottomSheet(context); | |
setState(() => _imageFile = _choosenImage); | |
}, | |
); | |
final TextFormField name = TextFormField( | |
autofocus: true, | |
validator: (String value) { | |
if (value.isEmpty) { | |
return 'Name cannot be empty'; | |
} | |
}, | |
onSaved: (String val) => _name = val, | |
style: const TextStyle(color: Colors.black, fontSize: 16.0), | |
decoration: InputDecoration( | |
fillColor: Colors.white, | |
filled: true, | |
hintText: 'Name', | |
contentPadding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), | |
border: OutlineInputBorder( | |
borderRadius: BorderRadius.circular(32.0), | |
), | |
enabledBorder: OutlineInputBorder( | |
borderRadius: BorderRadius.circular(32.0), | |
borderSide: BorderSide(width: 1.5, color: borderColor), | |
), | |
prefixIcon: const Icon(LearnFazz.person_outline), | |
), | |
); | |
final TextFormField email = TextFormField( | |
keyboardType: TextInputType.emailAddress, | |
validator: (String value) { | |
if (value.isEmpty) { | |
return 'Email cannot be empty'; | |
} else if (value.isNotEmpty && !value.contains('@gmail.')) { | |
return 'Invalid email address'; | |
} | |
}, | |
onSaved: (String val) => _email = val, | |
style: const TextStyle(color: Colors.black, fontSize: 16.0), | |
decoration: InputDecoration( | |
fillColor: Colors.white, | |
filled: true, | |
hintText: 'Email', | |
contentPadding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), | |
border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)), | |
enabledBorder: OutlineInputBorder( | |
borderRadius: BorderRadius.circular(32.0), | |
borderSide: BorderSide(width: 1.5, color: borderColor), | |
), | |
prefixIcon: const Icon(LearnFazz.mail), | |
), | |
); | |
final TextFormField idNumber = TextFormField( | |
keyboardType: TextInputType.number, | |
validator: (String value) { | |
if (value.isEmpty) { | |
return 'Identification number cannot be empty'; | |
} | |
}, | |
onSaved: (String identificationNumber) => | |
_identificationNumber = identificationNumber, | |
style: const TextStyle(color: Colors.black, fontSize: 16.0), | |
decoration: InputDecoration( | |
fillColor: Colors.white, | |
filled: true, | |
hintText: 'Identification Number', | |
contentPadding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), | |
border: OutlineInputBorder( | |
borderRadius: BorderRadius.circular(32.0), | |
), | |
enabledBorder: OutlineInputBorder( | |
borderRadius: BorderRadius.circular(32.0), | |
borderSide: BorderSide(width: 1.5, color: borderColor), | |
), | |
prefixIcon: const Icon(LearnFazz.id_card), | |
), | |
); | |
final TextFormField password = TextFormField( | |
validator: (String value) { | |
if (value.isEmpty) { | |
return 'Password cannot be empty'; | |
} else if (value.length < 8) { | |
return 'Password should\'ve at least 8 characters'; | |
} | |
}, | |
onSaved: (String password) => _password = password, | |
style: const TextStyle(color: Colors.black, fontSize: 16.0), | |
obscureText: passwordVisible, | |
key: _passKey, | |
decoration: InputDecoration( | |
fillColor: Colors.white, | |
filled: true, | |
hintText: 'Password', | |
contentPadding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), | |
border: OutlineInputBorder( | |
borderRadius: BorderRadius.circular(32.0), | |
), | |
enabledBorder: OutlineInputBorder( | |
borderRadius: BorderRadius.circular(32.0), | |
borderSide: BorderSide(width: 1.5, color: borderColor), | |
), | |
prefixIcon: const Icon(LearnFazz.lock), | |
suffixIcon: IconButton( | |
icon: Icon(passwordVisible ? LearnFazz.eye : Icons.visibility_off), | |
onPressed: () { | |
setState(() { | |
passwordVisible | |
? passwordVisible = false | |
: passwordVisible = true; | |
}); | |
}), | |
), | |
); | |
final TextFormField confirmPassword = TextFormField( | |
validator: (String value) { | |
final String password = _passKey.currentState.value; | |
return (value == password) ? null : 'Password doesn\'t match'; | |
}, | |
onSaved: (String passwordConfirmation) => | |
_passwordConfirmation = passwordConfirmation, | |
style: const TextStyle(color: Colors.black, fontSize: 16.0), | |
obscureText: confirmPasswordVisible, | |
decoration: InputDecoration( | |
fillColor: Colors.white, | |
filled: true, | |
hintText: 'Confirm Password', | |
contentPadding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), | |
border: OutlineInputBorder( | |
borderRadius: BorderRadius.circular(32.0), | |
), | |
enabledBorder: OutlineInputBorder( | |
borderRadius: BorderRadius.circular(32.0), | |
borderSide: BorderSide(width: 1.5, color: borderColor), | |
), | |
prefixIcon: const Icon(LearnFazz.lock), | |
suffixIcon: IconButton( | |
icon: Icon( | |
confirmPasswordVisible ? LearnFazz.eye : Icons.visibility_off), | |
onPressed: () { | |
setState(() { | |
confirmPasswordVisible | |
? confirmPasswordVisible = false | |
: confirmPasswordVisible = true; | |
}); | |
}, | |
), | |
), | |
); | |
final Widget bottomNavigationBar = | |
_isSubmitting ? LinearProgressIndicator() : null; | |
return Scaffold( | |
body: Builder( | |
builder: (BuildContext context) => Container( | |
decoration: const BoxDecoration( | |
image: DecorationImage( | |
image: AssetImage( | |
'lib/assets/images/blue-white-pattern-background.png'), | |
fit: BoxFit.cover, | |
)), | |
child: Form( | |
key: _formKey, | |
child: ListView( | |
padding: const EdgeInsets.only( | |
top: 100.0, left: 45.0, right: 45.0, bottom: 40.0), | |
children: <Widget>[ | |
logo, | |
const SizedBox(height: 10.0), | |
addPhotoLabel, | |
const SizedBox(height: 30.0), | |
name, | |
const SizedBox(height: 8.0), | |
email, | |
const SizedBox(height: 8.0), | |
idNumber, | |
const SizedBox(height: 8.0), | |
password, | |
const SizedBox(height: 8.0), | |
confirmPassword, | |
const SizedBox(height: 30.0), | |
InkWell( | |
key: const Key('registerButton'), | |
onTap: () => _validateThenPostToBackend(context), | |
child: Container( | |
height: 50.0, | |
decoration: BoxDecoration( | |
color: _isSubmitting | |
? Colors.grey | |
: const Color(0xFF3A8FF3), | |
borderRadius: BorderRadius.circular(30.0), | |
), | |
child: const Center( | |
child: Text( | |
'Register', | |
style: TextStyle(fontSize: 18.0, color: Colors.white), | |
), | |
), | |
), | |
), | |
], | |
), | |
)), | |
), | |
bottomNavigationBar: bottomNavigationBar, | |
); | |
} | |
Future<void> _validateThenPostToBackend(BuildContext context) async { | |
if (_isSubmitting) { | |
return; | |
} | |
if (_formKey.currentState.validate()) { | |
setState(() => _isSubmitting = true); | |
_formKey.currentState.save(); | |
try { | |
if (_imageFile == null) { | |
throw RegisterFormPage.kNoImageErrorMessage; | |
} | |
final AuthRepository authRepository = | |
AppConfig.of(context).authRepository; | |
final LoginResult response = await authRepository.register( | |
name: _name, | |
email: _email, | |
identificationNumber: _identificationNumber, | |
password: _password, | |
passwordConfirmation: _passwordConfirmation, | |
role: _role, | |
photo: _imageFile, | |
); | |
Navigator.of(context).push<dynamic>(MaterialPageRoute<dynamic>( | |
builder: (BuildContext context) => DashboardPage(user: response.user), | |
)); | |
} catch (e) { | |
Scaffold.of(context).showSnackBar(SnackBar( | |
content: Text(e.toString()), duration: const Duration(seconds: 5))); | |
} | |
setState(() => _isSubmitting = false); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment