mirror of
https://github.com/Iconica-Development/flutter_registration.git
synced 2025-05-19 05:23:43 +02:00
feat: registration options, translations
This commit is contained in:
parent
7f36ab8eca
commit
6f7ec0b0e6
6 changed files with 216 additions and 162 deletions
|
@ -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(),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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),
|
||||||
|
@ -151,5 +164,4 @@ class _AuthScreenState extends State<AuthScreen> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
51
lib/src/config/registration_options.dart
Normal file
51
lib/src/config/registration_options.dart
Normal 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,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
15
lib/src/config/registration_translations.dart
Normal file
15
lib/src/config/registration_translations.dart
Normal 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;
|
||||||
|
}
|
|
@ -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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue