feat: registration options, translations

This commit is contained in:
Stein Milder 2022-09-26 10:35:53 +02:00
parent 7f36ab8eca
commit 6f7ec0b0e6
6 changed files with 216 additions and 162 deletions

View file

@ -16,10 +16,13 @@ class FlutterRegistrationDemo extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return RegistrationScreen( return RegistrationScreen(
registrationOptions: RegistrationOptions(
registrationRepository: ExampleRegistrationRepository(),
registrationSteps: RegistrationOptions.defaultSteps,
afterRegistration: () { afterRegistration: () {
debugPrint('Registered!'); debugPrint('Registered!');
}, },
repository: ExampleRegistrationRepository(), ),
); );
} }
} }

View file

@ -1,5 +1,7 @@
library flutter_registration; library flutter_registration;
export 'src/config/registration_options.dart';
export 'src/config/registration_translations.dart';
export 'src/model/auth_exception.dart'; export 'src/model/auth_exception.dart';
export 'src/model/auth_field.dart'; export 'src/model/auth_field.dart';
export 'src/model/auth_step.dart'; export 'src/model/auth_step.dart';

View file

@ -8,6 +8,8 @@ class AuthScreen extends StatefulWidget {
required this.title, required this.title,
required this.steps, required this.steps,
required this.submitBtnTitle, required this.submitBtnTitle,
required this.nextBtnTitle,
required this.previousBtnTitle,
required this.onFinish, required this.onFinish,
super.key, super.key,
}) : assert(steps.length > 0, 'At least one step is required'); }) : assert(steps.length > 0, 'At least one step is required');
@ -16,6 +18,8 @@ class AuthScreen extends StatefulWidget {
final Function(HashMap<String, String>) onFinish; final Function(HashMap<String, String>) onFinish;
final List<AuthStep> steps; final List<AuthStep> steps;
final String submitBtnTitle; final String submitBtnTitle;
final String nextBtnTitle;
final String previousBtnTitle;
@override @override
State<AuthScreen> createState() => _AuthScreenState(); State<AuthScreen> createState() => _AuthScreenState();
@ -28,8 +32,7 @@ class _AuthScreenState extends State<AuthScreen> {
final _animationCurve = Curves.ease; final _animationCurve = Curves.ease;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) => Scaffold(
return Scaffold(
backgroundColor: Theme.of(context).backgroundColor, backgroundColor: Theme.of(context).backgroundColor,
appBar: AppBar( appBar: AppBar(
title: Text(widget.title), title: Text(widget.title),
@ -44,16 +47,19 @@ class _AuthScreenState extends State<AuthScreen> {
Column( Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
const Spacer(), Flexible(
Padding( child: Center(
child: ListView(
physics: const ClampingScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
vertical: 8.0, vertical: 8.0,
horizontal: 30.0, horizontal: 30.0,
), ),
child: Column(
children: [ children: [
for (AuthField field in step.fields) for (AuthField field in step.fields)
Column( Align(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Padding( Padding(
@ -70,13 +76,19 @@ class _AuthScreenState extends State<AuthScreen> {
), ),
field.build(), field.build(),
], ],
),
) )
], ],
), ),
), ),
const Spacer(), ),
Padding( Padding(
padding: const EdgeInsets.all(30.0), padding: const EdgeInsets.only(
top: 15.0,
bottom: 30.0,
left: 30.0,
right: 30.0,
),
child: Row( child: Row(
mainAxisAlignment: widget.steps.first != step mainAxisAlignment: widget.steps.first != step
? MainAxisAlignment.spaceBetween ? MainAxisAlignment.spaceBetween
@ -94,9 +106,9 @@ class _AuthScreenState extends State<AuthScreen> {
Icons.arrow_back, Icons.arrow_back,
size: 18, size: 18,
), ),
const Padding( Padding(
padding: EdgeInsets.only(left: 4.0), padding: const EdgeInsets.only(left: 4.0),
child: Text('Vorige stap'), child: Text(widget.previousBtnTitle),
), ),
], ],
), ),
@ -117,6 +129,7 @@ class _AuthScreenState extends State<AuthScreen> {
} }
widget.onFinish(values); widget.onFinish(values);
return; return;
} }
@ -130,7 +143,7 @@ class _AuthScreenState extends State<AuthScreen> {
Text( Text(
widget.steps.last == step widget.steps.last == step
? widget.submitBtnTitle ? widget.submitBtnTitle
: 'Volgende stap', : widget.nextBtnTitle,
), ),
const Padding( const Padding(
padding: EdgeInsets.only(left: 4.0), padding: EdgeInsets.only(left: 4.0),
@ -152,4 +165,3 @@ class _AuthScreenState extends State<AuthScreen> {
), ),
); );
} }
}

View file

@ -0,0 +1,51 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_registration/flutter_registration.dart';
class RegistrationOptions {
RegistrationOptions({
required this.registrationRepository,
required this.registrationSteps,
required this.afterRegistration,
this.registrationTranslations = const RegistrationTranslations(),
});
final RegistrationTranslations registrationTranslations;
final List<AuthStep> registrationSteps;
final VoidCallback afterRegistration;
final RegistrationRepository registrationRepository;
static List<AuthStep> get defaultSteps => [
AuthStep(
fields: [
AuthTextField(
name: 'email',
title: 'Wat is je e-mailadres?',
validators: [
(email) => (email == null || email.isEmpty)
? 'Geef uw e-mailadres op'
: null,
(email) =>
RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+")
.hasMatch(email!)
? null
: 'Geef een geldig e-mailadres op',
],
)
],
),
AuthStep(
fields: [
AuthTextField(
name: 'password',
title: 'Kies een wachtwoord',
obscureText: true,
validators: [
(value) => (value == null || value.isEmpty)
? 'Geef een wachtwoord op'
: null,
],
),
],
),
];
}

View file

@ -0,0 +1,15 @@
class RegistrationTranslations {
const RegistrationTranslations({
this.title = 'Registreren',
this.registerBtn = 'Registreren',
this.previousStepBtn = 'Vorige stap',
this.nextStepBtn = 'Volgende stap',
this.closeBtn = 'Sluiten',
});
final String title;
final String registerBtn;
final String previousStepBtn;
final String nextStepBtn;
final String closeBtn;
}

View file

@ -4,35 +4,38 @@ import 'package:flutter_registration/src/auth_screen.dart';
class RegistrationScreen extends StatelessWidget { class RegistrationScreen extends StatelessWidget {
const RegistrationScreen({ const RegistrationScreen({
required this.afterRegistration, required this.registrationOptions,
required this.repository,
this.additionalSteps = const [],
super.key, super.key,
}); });
final VoidCallback afterRegistration; final RegistrationOptions registrationOptions;
final RegistrationRepository repository;
final List<AuthStep> additionalSteps;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var translations = registrationOptions.registrationTranslations;
void showError(String error) => showDialog<String>( void showError(String error) => showDialog<String>(
context: context, context: context,
builder: (BuildContext context) => AlertDialog( builder: (BuildContext context) => AlertDialog(
content: Text(error), content: Text(error),
actions: <Widget>[ actions: <Widget>[
TextButton( TextButton(
onPressed: () => Navigator.pop(context, 'Sluit'), onPressed: () => Navigator.pop(
child: const Text('Sluit'), context,
translations.closeBtn,
),
child: Text(
translations.closeBtn,
),
), ),
], ],
), ),
); );
void register(values) => repository void register(values) => registrationOptions.registrationRepository
.register(values) .register(values)
.then( .then(
(value) => afterRegistration(), (_) => registrationOptions.afterRegistration(),
) )
.catchError( .catchError(
(error) { (error) {
@ -43,44 +46,12 @@ class RegistrationScreen extends StatelessWidget {
); );
return AuthScreen( return AuthScreen(
title: 'Registreren', steps: registrationOptions.registrationSteps,
submitBtnTitle: 'Registreren',
steps: [
AuthStep(
fields: [
AuthTextField(
name: 'email',
title: 'Wat is je e-mailadres?',
validators: [
(email) => (email == null || email.isEmpty)
? 'Geef uw e-mailadres op'
: null,
(email) =>
RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+")
.hasMatch(email!)
? null
: 'Geef een geldig e-mailadres op',
],
)
],
),
AuthStep(
fields: [
AuthTextField(
name: 'password',
title: 'Kies een wachtwoord',
obscureText: true,
validators: [
(value) => (value == null || value.isEmpty)
? 'Geef een wachtwoord op'
: null,
],
),
],
),
...additionalSteps
],
onFinish: register, onFinish: register,
title: translations.title,
submitBtnTitle: translations.registerBtn,
nextBtnTitle: translations.nextStepBtn,
previousBtnTitle: translations.previousStepBtn,
); );
} }
} }