From 844cb6822aa79c26a18de2cf893726d69e316916 Mon Sep 17 00:00:00 2001 From: Tiku Gaelle Date: Thu, 9 Mar 2023 14:34:48 +0100 Subject: [PATCH 1/4] feat: Contact us page --- assets/fpb-assets/email_success.png | Bin 0 -> 5557 bytes lib/contact_us/contact_us_page.dart | 2 + lib/contact_us/domain/form_validation.dart | 23 +++ lib/contact_us/view/contact_us_page.dart | 179 ++++++++++++++++++ .../view/contact_us_success_page.dart | 82 ++++++++ .../view/widgets/message_textfield.dart | 43 +++++ .../presentation/widget/my_textformfield.dart | 28 +-- lib/l10n/arb/app_en.arb | 32 ++++ lib/l10n/arb/app_fr.arb | 32 ++++ 9 files changed, 408 insertions(+), 13 deletions(-) create mode 100644 assets/fpb-assets/email_success.png create mode 100644 lib/contact_us/contact_us_page.dart create mode 100644 lib/contact_us/domain/form_validation.dart create mode 100644 lib/contact_us/view/contact_us_page.dart create mode 100644 lib/contact_us/view/contact_us_success_page.dart create mode 100644 lib/contact_us/view/widgets/message_textfield.dart diff --git a/assets/fpb-assets/email_success.png b/assets/fpb-assets/email_success.png new file mode 100644 index 0000000000000000000000000000000000000000..d174864878c641d2d985e51aa6b2710c0d636373 GIT binary patch literal 5557 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 Ds#?T- literal 0 HcmV?d00001 diff --git a/lib/contact_us/contact_us_page.dart b/lib/contact_us/contact_us_page.dart new file mode 100644 index 0000000..874b367 --- /dev/null +++ b/lib/contact_us/contact_us_page.dart @@ -0,0 +1,2 @@ +export 'view/contact_us_page.dart'; +export 'view/contact_us_success_page.dart'; diff --git a/lib/contact_us/domain/form_validation.dart b/lib/contact_us/domain/form_validation.dart new file mode 100644 index 0000000..478da96 --- /dev/null +++ b/lib/contact_us/domain/form_validation.dart @@ -0,0 +1,23 @@ +extension extString on String { + bool get isValidEmail { + final emailRegExp = RegExp(r"^[a-zA-Z0-9.]+@[a-zA-Z0-9]+\.[a-zA-Z]+"); + return emailRegExp.hasMatch(this); + } + + bool get isValidName { + final nameRegExp = + new RegExp(r"^\s*([A-Za-z]{1,}([\.,] |[-']| ))+[A-Za-z]+\.?\s*$"); + return nameRegExp.hasMatch(this); + } + + bool get isValidMessage { + final messageRegExp = + RegExp(r"^\s*([A-Za-z]{1,}([\.,] |[-']| ))+[A-Za-z]+\.?\s*$"); + return messageRegExp.hasMatch(this); + } + + bool get isNotNull { + // ignore: unnecessary_null_comparison + return this != null; + } +} diff --git a/lib/contact_us/view/contact_us_page.dart b/lib/contact_us/view/contact_us_page.dart new file mode 100644 index 0000000..7c65ad9 --- /dev/null +++ b/lib/contact_us/view/contact_us_page.dart @@ -0,0 +1,179 @@ +// ignore_for_file: body_might_complete_normally_nullable + +import 'package:flutter/material.dart'; +import 'package:fpb/assets/fpb_svg.dart'; +import 'package:fpb/contact_us/contact_us_page.dart'; +import 'package:fpb/core/presentation/extension/extensions.dart'; +import 'package:fpb/core/presentation/widget/my_button.dart'; +import 'package:fpb/core/presentation/widget/my_textformfield.dart'; +import 'package:fpb/l10n/l10n.dart'; +import 'package:fpb/sign_in/view/sign_in_page.dart'; +import '../domain/form_validation.dart'; + +class ContactUsPage extends StatefulWidget { + const ContactUsPage({super.key}); + + @override + State createState() => _ContactUsPageState(); +} + +class _ContactUsPageState extends State { + final _formKey = GlobalKey(); + + @override + Widget build(BuildContext context) { + final l10n = context.l10n; + final theme = Theme.of(context); + //final style = theme.textTheme; + + return LayoutBuilder( + builder: (context, box) { + return Scaffold( + resizeToAvoidBottomInset: false, + body: Stack(children: [ + BubblesTopBackGround( + cts: box, + svgName: SvgNames.authBackground, + ), + Align( + alignment: Alignment.bottomCenter, + child: Container( + height: box.maxHeight * .75, + width: box.maxWidth, + decoration: BoxDecoration( + color: theme.colorScheme.background, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + ), + child: Padding( + padding: EdgeInsets.only( + top: box.maxHeight * .025, + left: box.maxHeight * .025, + right: box.maxHeight * .025, + bottom: box.maxHeight * .005), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + PageTitle( + title: l10n.contactUsTitle, + box: box, + ), + SizedBox( + height: 0.015 * box.maxHeight, + ), + SingleChildScrollView( + child: Flexible( + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + children: [ + FpbTextFormField( + label: l10n.contactUsNameTextFieldLabel, + hint: l10n.contactUsNameTextFieldHintText, + box: box, + validator: (val) { + if (!(val!.isNotEmpty) && + !(val.isValidName)) { + return l10n.contactUsNameErrorText; + } + }, + ), + FpbTextFormField( + label: l10n.signInEmailTextFieldLabel, + hint: l10n.signInEmailTextFieldHintText, + box: box, + validator: (val) { + if (!(val!.isNotEmpty) && + !(val.isValidEmail)) { + return l10n.contactUsEmailErrorText; + } + }, + ), + messageTextField( + theme: theme, + box: box, + validator: (val) { + if (!(val!.isNotEmpty) && + !(val.isValidEmail)) { + return 'Enter Text'; + } + }, + ), + ], + ), + ), + ), + ), + SizedBox( + height: box.maxHeight * .05, + ), + FpbButton( + label: l10n.contactUsSubmitBtnLabel, + onTap: () { + if (_formKey.currentState!.validate()) { + Navigator.of(context).push( + // ignore: inference_failure_on_instance_creation + MaterialPageRoute( + builder: (context) => ContactUsSuccessPage( + box: box, + ), + ), + ); + } + }, + ) + ]), + ), + ), + ) + ])); + }, + ); + } +} + +class messageTextField extends StatelessWidget { + const messageTextField( + {super.key, + required this.theme, + required this.box, + required this.validator}); + + final ThemeData theme; + final BoxConstraints box; + final String? Function(String?)? validator; + + @override + Widget build(BuildContext context) { + final l10n = context.l10n; + final theme = Theme.of(context); + final style = theme.textTheme; + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + l10n.contactUsMessageTextFieldLabel, + style: style.titleSmall, + ), + TextFormField( + validator: validator, + maxLines: 5, + decoration: InputDecoration( + hintText: l10n.contactUsMessageTextFieldHintText, + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(box.maxHeight * .025), + borderSide: BorderSide( + color: theme.colorScheme.onSurface, + ), + ), + ), + ).card(padding: EdgeInsets.symmetric(vertical: box.maxHeight * .007)), + ], + ); + } +} diff --git a/lib/contact_us/view/contact_us_success_page.dart b/lib/contact_us/view/contact_us_success_page.dart new file mode 100644 index 0000000..6cc19a1 --- /dev/null +++ b/lib/contact_us/view/contact_us_success_page.dart @@ -0,0 +1,82 @@ +import 'package:flutter/material.dart'; +import 'package:fpb/assets/fpb_svg.dart'; +import 'package:fpb/core/presentation/widget/my_button.dart'; +import 'package:fpb/sign_in/view/sign_in_page.dart'; + +class ContactUsSuccessPage extends StatelessWidget { + const ContactUsSuccessPage({super.key, required this.box}); + + final BoxConstraints box; + @override + Widget build(BuildContext context) { + //final l10n = context.l10n; + final theme = Theme.of(context); + final style = theme.textTheme; + //final colors = theme.colorScheme; + + return Scaffold( + resizeToAvoidBottomInset: false, + body: Stack(children: [ + BubblesTopBackGround( + cts: box, + svgName: SvgNames.authBackground, + ), + Align( + alignment: Alignment.bottomCenter, + child: Container( + height: box.maxHeight * .75, + width: box.maxWidth, + decoration: BoxDecoration( + color: theme.colorScheme.background, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + ), + child: Padding( + padding: EdgeInsets.only( + top: box.maxHeight * .025, + left: box.maxHeight * .025, + right: box.maxHeight * .025, + bottom: box.maxHeight * .005), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + height: box.maxHeight * .1, + ), + Image.asset( + 'assets/fpb-assets/email_success.png', + width: box.maxWidth * .3, + height: 0.15 * box.maxHeight, + ), + SizedBox( + height: box.maxHeight * .0001, + ), + Text( + 'Thank you for contacting us!!', + maxLines: 2, + style: style.titleLarge, + ), + SizedBox( + height: box.maxHeight * .025, + ), + Text( + 'We\'ve received your message. We read every message and typically respond within 48hrs if a reply is required.', + maxLines: 3, + style: style.titleMedium), + SizedBox( + height: box.maxHeight * .2, + ), + FpbButton( + label: 'Go Back', + onTap: () {}, + ) + ], + ), + ), + )) + ]), + ); + } +} diff --git a/lib/contact_us/view/widgets/message_textfield.dart b/lib/contact_us/view/widgets/message_textfield.dart new file mode 100644 index 0000000..e5d8330 --- /dev/null +++ b/lib/contact_us/view/widgets/message_textfield.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; +import 'package:fpb/core/presentation/extension/extensions.dart'; + +class messageTextField extends StatelessWidget { + const messageTextField( + {super.key, + required this.theme, + required this.box, + required this.validator}); + + final ThemeData theme; + final BoxConstraints box; + final String? Function(String?)? validator; + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + final style = theme.textTheme; + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Message', + style: style.titleSmall, + ), + TextFormField( + validator: validator, + maxLines: 5, + decoration: InputDecoration( + hintText: 'leave a message...', + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(box.maxHeight * .025), + borderSide: BorderSide( + color: theme.colorScheme.onSurface, + ), + ), + ), + ).card(padding: EdgeInsets.symmetric(vertical: box.maxHeight * .007)), + ], + ); + } +} diff --git a/lib/core/presentation/widget/my_textformfield.dart b/lib/core/presentation/widget/my_textformfield.dart index 672ef6a..bf87c4d 100644 --- a/lib/core/presentation/widget/my_textformfield.dart +++ b/lib/core/presentation/widget/my_textformfield.dart @@ -3,19 +3,19 @@ import 'package:fpb/assets/fpb_icons/fpb_icons_icons.dart'; import 'package:fpb/core/presentation/extension/extensions.dart'; class FpbTextFormField extends StatefulWidget { - const FpbTextFormField({ - super.key, - required this.label, - required this.hint, - this.textController, - this.node, - this.isEmail = false, - this.isPassword = false, - this.onChanged, - this.errorText, - this.showLabelText = true, - required this.box, - }); + const FpbTextFormField( + {super.key, + required this.label, + required this.hint, + this.textController, + this.node, + this.isEmail = false, + this.isPassword = false, + this.onChanged, + this.errorText, + this.showLabelText = true, + required this.box, + this.validator}); final String label; final String hint; @@ -27,6 +27,7 @@ class FpbTextFormField extends StatefulWidget { final String? errorText; final BoxConstraints box; final bool showLabelText; + final String? Function(String?)? validator; @override State createState() => _FpbTextFormFieldState(); @@ -57,6 +58,7 @@ class _FpbTextFormFieldState extends State { ) : SizedBox(), TextFormField( + validator: widget.validator, controller: widget.textController, focusNode: widget.node, keyboardType: widget.isEmail diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index ffa5f38..bc23ae4 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -231,5 +231,37 @@ "signUpAlreadyAMemberText": "Already a member?", "@signUpAlreadyAMemberText": { "description": "This is the text displayed on the sign up screen after the social media icon buttons" + }, + "contactUsTitle": "Contact us", + "@contactUsTitle": { + "description": "This is the title of the contact us page" + }, + "contactUsNameTextFieldLabel": "Name", + "@contactUsNameTextFieldLabel": { + "description": "This is the label of the Name textformfield of the contact us page" + }, + "contactUsNameTextFieldHintText": "Enter your name", + "@contactUsNameTextFieldHintText": { + "description": "This is the hint text of the Name textformfield of the contact us page" + }, + "contactUsMessageTextFieldLabel": "Message", + "@contactUsMessageTextFieldLabel": { + "description": "This is the label of the message textformfield of the contact us page" + }, + "contactUsMessageTextFieldHintText": "leave a message...", + "@contactUsMessageTextFieldHintText": { + "description": "This is the hint text of the message textformfield of the contact us page" + }, + "contactUsSubmitBtnLabel": "Submit", + "@contactUsSubmitBtnLabel": { + "description": "This is the label of the submit button of the contact us page" + }, + "contactUsNameErrorText": "Please enter your name", + "@contactUsNameErrorText": { + "description": "This is the error text displayed when validation for the name textform field, of the contact us page fails" + }, + "contactUsEmailErrorText": "Please enter your email", + "@contactUsEmailErrorText": { + "description": "This is the error text displayed when validation for the email textform field, of the contact us page fails" } } diff --git a/lib/l10n/arb/app_fr.arb b/lib/l10n/arb/app_fr.arb index 2b52341..597288a 100644 --- a/lib/l10n/arb/app_fr.arb +++ b/lib/l10n/arb/app_fr.arb @@ -235,5 +235,37 @@ "signUpAlreadyAMemberText": "Déjà membre?", "@signUpAlreadyAMemberText": { "description": "Il s'agit du texte affiché sur l'écran d'inscription après les boutons d'icône de médias sociaux." + }, + "contactUsTitle": "Contactez nous", + "@contactUsTitle": { + "description": "C'est le titre de la page de contact" + }, + "contactUsNameTextFieldLabel": "Nom", + "@contactUsNameTextFieldLabel": { + "description": "Il s'agit de l'étiquette du champ de texte Nom de la page Contactez-nous." + }, + "contactUsNameTextFieldHintText": "Entrez votre nom", + "@contactUsNameTextFieldHintText": { + "description": "Il s'agit du texte de l'indice du champ de texte Nom de la page Contactez-nous." + }, + "contactUsMessageTextFieldLabel": "Message", + "@contactUsMessageTextFieldLabel": { + "description": "Il s'agit de l'étiquette du champ de texte du message de la page nous contacter" + }, + "contactUsMessageTextFieldHintText": "laisser un message...", + "@contactUsMessageTextFieldHintText": { + "description": "Il s'agit du texte de l'indice du message textformfield de la page nous contacter" + }, + "contactUsSubmitBtnLabel": "Envoyer", + "@contactUsSubmitBtnLabel": { + "description": "Il s'agit de l'étiquette du bouton d'envoi de la page nous contacter" + }, + "contactUsNameErrorText": "Veuillez entrer votre nom", + "@contactUsNameErrorText": { + "description": "Il s'agit du texte d'erreur affiché lorsque la validation du champ de formulaire Nom de la page Contactez-nous échoue." + }, + "contactUsEmailErrorText": "Veuillez entrer votre adresse e-mail", + "@contactUsEmailErrorText": { + "description": "Il s'agit du texte d'erreur affiché en cas d'échec de la validation du champ de texte email de la page contactez-nous" } } From 8bd47af7037a796e6dbca0ea5fc64c5df89f184b Mon Sep 17 00:00:00 2001 From: Tiku Gaelle Date: Tue, 14 Mar 2023 05:56:07 +0100 Subject: [PATCH 2/4] fix: updated contact us page with complete form validation --- assets/fpb-assets/Cross.svg | 4 + lib/assets/fpb_svg.dart | 1 + lib/contact_us/domain/form_validation.dart | 10 +- lib/contact_us/view/contact_us_page.dart | 114 ++++++++---------- .../view/contact_us_success_page.dart | 38 +++--- .../view/widgets/contact_us_success_btn.dart | 47 ++++++++ .../widgets/contact_us_success_image.dart | 19 +++ .../widgets/contact_us_success_texts.dart | 32 +++++ .../view/widgets/message_textfield.dart | 33 +++-- .../presentation/extension/extensions.dart | 48 ++++++-- .../presentation/widget/my_textformfield.dart | 18 ++- lib/l10n/arb/app_en.arb | 16 +++ lib/l10n/arb/app_fr.arb | 16 +++ 13 files changed, 280 insertions(+), 116 deletions(-) create mode 100644 assets/fpb-assets/Cross.svg create mode 100644 lib/contact_us/view/widgets/contact_us_success_btn.dart create mode 100644 lib/contact_us/view/widgets/contact_us_success_image.dart create mode 100644 lib/contact_us/view/widgets/contact_us_success_texts.dart diff --git a/assets/fpb-assets/Cross.svg b/assets/fpb-assets/Cross.svg new file mode 100644 index 0000000..ed1813e --- /dev/null +++ b/assets/fpb-assets/Cross.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lib/assets/fpb_svg.dart b/lib/assets/fpb_svg.dart index 8f613aa..d4238a2 100644 --- a/lib/assets/fpb_svg.dart +++ b/lib/assets/fpb_svg.dart @@ -14,4 +14,5 @@ class SvgNames { static String google = '${path}google.svg'; static String facebook = '${path}facebook.svg'; static String twitter = '${path}twitter.svg'; + static String error = '${path}Cross.svg'; } diff --git a/lib/contact_us/domain/form_validation.dart b/lib/contact_us/domain/form_validation.dart index 478da96..158477b 100644 --- a/lib/contact_us/domain/form_validation.dart +++ b/lib/contact_us/domain/form_validation.dart @@ -10,11 +10,11 @@ extension extString on String { return nameRegExp.hasMatch(this); } - bool get isValidMessage { - final messageRegExp = - RegExp(r"^\s*([A-Za-z]{1,}([\.,] |[-']| ))+[A-Za-z]+\.?\s*$"); - return messageRegExp.hasMatch(this); - } + // bool get isValidMessage { + // final messageRegExp = + // RegExp(r"^\s*([A-Za-z]{1,}([\.,] |[-']| ))+[A-Za-z]+\.?\s*$"); + // return messageRegExp.hasMatch(this); + // } bool get isNotNull { // ignore: unnecessary_null_comparison diff --git a/lib/contact_us/view/contact_us_page.dart b/lib/contact_us/view/contact_us_page.dart index 7c65ad9..5962b97 100644 --- a/lib/contact_us/view/contact_us_page.dart +++ b/lib/contact_us/view/contact_us_page.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:fpb/assets/fpb_svg.dart'; import 'package:fpb/contact_us/contact_us_page.dart'; -import 'package:fpb/core/presentation/extension/extensions.dart'; +import 'package:fpb/contact_us/view/widgets/message_textfield.dart'; import 'package:fpb/core/presentation/widget/my_button.dart'; import 'package:fpb/core/presentation/widget/my_textformfield.dart'; import 'package:fpb/l10n/l10n.dart'; @@ -19,6 +19,11 @@ class ContactUsPage extends StatefulWidget { class _ContactUsPageState extends State { final _formKey = GlobalKey(); + final nameController = TextEditingController(); + final emailController = TextEditingController(); + String errorText = ''; + //IconData errorIcon; + double errorContainerHeight = 0.0; @override Widget build(BuildContext context) { @@ -29,7 +34,7 @@ class _ContactUsPageState extends State { return LayoutBuilder( builder: (context, box) { return Scaffold( - resizeToAvoidBottomInset: false, + resizeToAvoidBottomInset: true, body: Stack(children: [ BubblesTopBackGround( cts: box, @@ -63,8 +68,8 @@ class _ContactUsPageState extends State { SizedBox( height: 0.015 * box.maxHeight, ), - SingleChildScrollView( - child: Flexible( + Flexible( + child: SingleChildScrollView( child: Form( key: _formKey, child: Column( @@ -72,23 +77,37 @@ class _ContactUsPageState extends State { mainAxisSize: MainAxisSize.min, children: [ FpbTextFormField( + onChanged: (value) { + setState(() {}); + }, + textController: nameController, label: l10n.contactUsNameTextFieldLabel, hint: l10n.contactUsNameTextFieldHintText, box: box, validator: (val) { - if (!(val!.isNotEmpty) && - !(val.isValidName)) { + if (val!.isEmpty) { + return null; + } else if (val.isValidName) { + return null; + } else { return l10n.contactUsNameErrorText; } }, ), FpbTextFormField( + onChanged: (value) { + setState(() {}); + }, + textController: emailController, label: l10n.signInEmailTextFieldLabel, hint: l10n.signInEmailTextFieldHintText, box: box, validator: (val) { - if (!(val!.isNotEmpty) && - !(val.isValidEmail)) { + if (val!.isEmpty) { + return null; + } else if (val.isValidEmail) { + return null; + } else { return l10n.contactUsEmailErrorText; } }, @@ -97,9 +116,14 @@ class _ContactUsPageState extends State { theme: theme, box: box, validator: (val) { - if (!(val!.isNotEmpty) && - !(val.isValidEmail)) { - return 'Enter Text'; + if (val!.isEmpty) { + return null; + } else if (val.length > 30 && + val.length < 500) { + return null; + } else { + return l10n + .contactUsMessageTextFieldErrorText; } }, ), @@ -112,20 +136,20 @@ class _ContactUsPageState extends State { height: box.maxHeight * .05, ), FpbButton( - label: l10n.contactUsSubmitBtnLabel, - onTap: () { - if (_formKey.currentState!.validate()) { - Navigator.of(context).push( - // ignore: inference_failure_on_instance_creation - MaterialPageRoute( - builder: (context) => ContactUsSuccessPage( - box: box, + label: l10n.contactUsSubmitBtnLabel, + onTap: () { + if (_formKey.currentState!.validate()) { + Navigator.of(context).push( + // ignore: inference_failure_on_instance_creation + MaterialPageRoute( + builder: (context) => + ContactUsSuccessPage( + box: box, + ), ), - ), - ); - } - }, - ) + ); + } else {} + }) ]), ), ), @@ -135,45 +159,3 @@ class _ContactUsPageState extends State { ); } } - -class messageTextField extends StatelessWidget { - const messageTextField( - {super.key, - required this.theme, - required this.box, - required this.validator}); - - final ThemeData theme; - final BoxConstraints box; - final String? Function(String?)? validator; - - @override - Widget build(BuildContext context) { - final l10n = context.l10n; - final theme = Theme.of(context); - final style = theme.textTheme; - - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - l10n.contactUsMessageTextFieldLabel, - style: style.titleSmall, - ), - TextFormField( - validator: validator, - maxLines: 5, - decoration: InputDecoration( - hintText: l10n.contactUsMessageTextFieldHintText, - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(box.maxHeight * .025), - borderSide: BorderSide( - color: theme.colorScheme.onSurface, - ), - ), - ), - ).card(padding: EdgeInsets.symmetric(vertical: box.maxHeight * .007)), - ], - ); - } -} diff --git a/lib/contact_us/view/contact_us_success_page.dart b/lib/contact_us/view/contact_us_success_page.dart index 6cc19a1..cd91fb7 100644 --- a/lib/contact_us/view/contact_us_success_page.dart +++ b/lib/contact_us/view/contact_us_success_page.dart @@ -1,6 +1,9 @@ import 'package:flutter/material.dart'; import 'package:fpb/assets/fpb_svg.dart'; -import 'package:fpb/core/presentation/widget/my_button.dart'; +import 'package:fpb/contact_us/view/widgets/contact_us_success_btn.dart'; +import 'package:fpb/contact_us/view/widgets/contact_us_success_image.dart'; +import 'package:fpb/contact_us/view/widgets/contact_us_success_texts.dart'; +import 'package:fpb/l10n/l10n.dart'; import 'package:fpb/sign_in/view/sign_in_page.dart'; class ContactUsSuccessPage extends StatelessWidget { @@ -9,7 +12,7 @@ class ContactUsSuccessPage extends StatelessWidget { final BoxConstraints box; @override Widget build(BuildContext context) { - //final l10n = context.l10n; + final l10n = context.l10n; final theme = Theme.of(context); final style = theme.textTheme; //final colors = theme.colorScheme; @@ -45,32 +48,21 @@ class ContactUsSuccessPage extends StatelessWidget { SizedBox( height: box.maxHeight * .1, ), - Image.asset( - 'assets/fpb-assets/email_success.png', - width: box.maxWidth * .3, - height: 0.15 * box.maxHeight, - ), + ContactUsSuccessImageWidget(box: box), SizedBox( height: box.maxHeight * .0001, ), - Text( - 'Thank you for contacting us!!', - maxLines: 2, - style: style.titleLarge, - ), - SizedBox( - height: box.maxHeight * .025, - ), - Text( - 'We\'ve received your message. We read every message and typically respond within 48hrs if a reply is required.', - maxLines: 3, - style: style.titleMedium), + ContactUsSuccessTexts(l10n: l10n, style: style, box: box), SizedBox( - height: box.maxHeight * .2, + height: box.maxHeight * .15, ), - FpbButton( - label: 'Go Back', - onTap: () {}, + ContactUsSuccessBtn( + style: style, + box: box, + backgroundColor: theme.colorScheme.background, + borderColor: theme.colorScheme.secondary, + text: l10n.contactUsSuccessBtnText, + textColor: theme.colorScheme.secondary, ) ], ), diff --git a/lib/contact_us/view/widgets/contact_us_success_btn.dart b/lib/contact_us/view/widgets/contact_us_success_btn.dart new file mode 100644 index 0000000..3c5b3a1 --- /dev/null +++ b/lib/contact_us/view/widgets/contact_us_success_btn.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; + +class ContactUsSuccessBtn extends StatelessWidget { + const ContactUsSuccessBtn( + {super.key, + required this.style, + required this.box, + required this.backgroundColor, + required this.borderColor, + required this.text, + required this.textColor}); + + final TextTheme style; + final BoxConstraints box; + final Color textColor; + final Color backgroundColor; + final String text; + final Color borderColor; + + @override + Widget build(BuildContext context) { + return Container( + height: box.maxHeight * .06, + width: box.maxWidth, + child: ElevatedButton( + style: ButtonStyle( + foregroundColor: MaterialStateProperty.all(textColor), + elevation: MaterialStateProperty.all(0), + textStyle: MaterialStateProperty.all(style.titleMedium), + backgroundColor: MaterialStateProperty.all( + backgroundColor, + ), + shape: MaterialStateProperty.all(RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + box.maxHeight * .015, + ))), + side: MaterialStateProperty.all(BorderSide( + color: borderColor, + ))), + onPressed: () {}, + child: Text( + text, + ), + ), + ); + } +} diff --git a/lib/contact_us/view/widgets/contact_us_success_image.dart b/lib/contact_us/view/widgets/contact_us_success_image.dart new file mode 100644 index 0000000..03e1d55 --- /dev/null +++ b/lib/contact_us/view/widgets/contact_us_success_image.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; + +class ContactUsSuccessImageWidget extends StatelessWidget { + const ContactUsSuccessImageWidget({ + super.key, + required this.box, + }); + + final BoxConstraints box; + + @override + Widget build(BuildContext context) { + return Image.asset( + 'assets/fpb-assets/email_success.png', + width: box.maxWidth * .3, + height: 0.15 * box.maxHeight, + ); + } +} diff --git a/lib/contact_us/view/widgets/contact_us_success_texts.dart b/lib/contact_us/view/widgets/contact_us_success_texts.dart new file mode 100644 index 0000000..412afc9 --- /dev/null +++ b/lib/contact_us/view/widgets/contact_us_success_texts.dart @@ -0,0 +1,32 @@ +import 'package:flutter/material.dart'; +import 'package:fpb/l10n/l10n.dart'; + +class ContactUsSuccessTexts extends StatelessWidget { + const ContactUsSuccessTexts({ + super.key, + required this.l10n, + required this.style, + required this.box, + }); + + final AppLocalizations l10n; + final TextTheme style; + final BoxConstraints box; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Text( + l10n.contactUsSuccessTitle, + maxLines: 2, + style: style.titleLarge, + ), + SizedBox( + height: box.maxHeight * .025, + ), + Text(l10n.contactUsSuccessText, maxLines: 3, style: style.titleMedium), + ], + ); + } +} diff --git a/lib/contact_us/view/widgets/message_textfield.dart b/lib/contact_us/view/widgets/message_textfield.dart index e5d8330..f1fa5c8 100644 --- a/lib/contact_us/view/widgets/message_textfield.dart +++ b/lib/contact_us/view/widgets/message_textfield.dart @@ -1,7 +1,8 @@ import 'package:flutter/material.dart'; +import 'package:fpb/l10n/l10n.dart'; import 'package:fpb/core/presentation/extension/extensions.dart'; -class messageTextField extends StatelessWidget { +class messageTextField extends StatefulWidget { const messageTextField( {super.key, required this.theme, @@ -12,8 +13,16 @@ class messageTextField extends StatelessWidget { final BoxConstraints box; final String? Function(String?)? validator; + @override + State createState() => _messageTextFieldState(); +} + +class _messageTextFieldState extends State { + final messageController = TextEditingController(); + @override Widget build(BuildContext context) { + final l10n = context.l10n; final theme = Theme.of(context); final style = theme.textTheme; @@ -21,22 +30,32 @@ class messageTextField extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - 'Message', + l10n.contactUsMessageTextFieldLabel, style: style.titleSmall, ), TextFormField( - validator: validator, - maxLines: 5, + onChanged: (value) { + setState(() {}); + }, + maxLength: 500, + controller: messageController, + //validator: widget.validator, + maxLines: 3, decoration: InputDecoration( - hintText: 'leave a message...', + hintText: l10n.contactUsMessageTextFieldHintText, + errorStyle: TextStyle( + color: theme.colorScheme.secondaryContainer, + ), focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(box.maxHeight * .025), + borderRadius: BorderRadius.circular(widget.box.maxHeight * .025), borderSide: BorderSide( color: theme.colorScheme.onSurface, ), ), ), - ).card(padding: EdgeInsets.symmetric(vertical: box.maxHeight * .007)), + ).validatorWidget(widget.validator?.call(messageController.text)).card( + padding: + EdgeInsets.symmetric(vertical: widget.box.maxHeight * .007)), ], ); } diff --git a/lib/core/presentation/extension/extensions.dart b/lib/core/presentation/extension/extensions.dart index 3b60dd9..43e9ca0 100644 --- a/lib/core/presentation/extension/extensions.dart +++ b/lib/core/presentation/extension/extensions.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:fpb/assets/fpb_svg.dart'; extension SvgPictureXX on SvgPicture { SvgPicture fpbsvg(String name) { @@ -14,15 +15,44 @@ mixin SvgPictureX { } extension ContainerX on Widget { - AnimatedContainer card( - {double? radius, - Color? color, - double? height, - EdgeInsets? padding, - EdgeInsets? margin, - Duration? animation, - double? width, - double? radiusTop}) { + Widget validatorWidget(String? errorMessage) { + return Column( + children: [ + this, + SizedBox( + height: 5, + ), + if (errorMessage != null) + Row( + children: [ + SvgPicture.asset(SvgNames.error), + SizedBox( + width: 5, + ), + Text( + errorMessage, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w400, + color: const Color(0xffDF602F), + ), + ) + ], + ) + ], + ); + } + + AnimatedContainer card({ + double? radius, + Color? color, + double? height, + EdgeInsets? padding, + EdgeInsets? margin, + Duration? animation, + double? width, + double? radiusTop, + }) { return AnimatedContainer( duration: animation ?? Duration(milliseconds: 300), height: height, diff --git a/lib/core/presentation/widget/my_textformfield.dart b/lib/core/presentation/widget/my_textformfield.dart index bf87c4d..ece5fd2 100644 --- a/lib/core/presentation/widget/my_textformfield.dart +++ b/lib/core/presentation/widget/my_textformfield.dart @@ -71,6 +71,9 @@ class _FpbTextFormFieldState extends State { style: textTheme .titleSmall, //bodyMedium //.copyWith(color: colors.onSurface), decoration: InputDecoration( + errorStyle: TextStyle( + color: theme.colorScheme.secondaryContainer, + ), errorText: widget.errorText, suffixIcon: !widget.isPassword ? null @@ -113,12 +116,15 @@ class _FpbTextFormFieldState extends State { ), hintText: widget.hint, ), - ).card( - height: widget.box.maxHeight * 0.11, - padding: EdgeInsets.symmetric( - vertical: widget.box.maxHeight * 0.007, - ), - ), + ) + .validatorWidget( + widget.validator?.call(widget.textController?.text)) + .card( + height: widget.box.maxHeight * 0.12, + padding: EdgeInsets.symmetric( + vertical: widget.box.maxHeight * 0.007, + ), + ), ], ); } diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index bc23ae4..2a04e7e 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -263,5 +263,21 @@ "contactUsEmailErrorText": "Please enter your email", "@contactUsEmailErrorText": { "description": "This is the error text displayed when validation for the email textform field, of the contact us page fails" + }, + "contactUsMessageTextFieldErrorText": "Text must be atleast 30 characters", + "@contactUsMessageTextFieldErrorText": { + "description": "This is the error text displayed when validation of the message textformfield, of the contact us page fails" + }, + "contactUsSuccessTitle": "Thank you for contacting us!!", + "@contactUsSuccessTitle": { + "description": "This is the title text displayed on the contact us success page" + }, + "contactUsSuccessText": "We've received your message. We read every message and typically respond within 48 hours if a reply is required", + "@contactUsSuccessText": { + "description": "This is the text displayed on the contact us success page" + }, + "contactUsSuccessBtnText": "Go Back", + "@contactUsSuccessBtnText": { + "description": "This is the label of the button displayed on the contact us success page" } } diff --git a/lib/l10n/arb/app_fr.arb b/lib/l10n/arb/app_fr.arb index 597288a..1d54cd6 100644 --- a/lib/l10n/arb/app_fr.arb +++ b/lib/l10n/arb/app_fr.arb @@ -267,5 +267,21 @@ "contactUsEmailErrorText": "Veuillez entrer votre adresse e-mail", "@contactUsEmailErrorText": { "description": "Il s'agit du texte d'erreur affiché en cas d'échec de la validation du champ de texte email de la page contactez-nous" + }, + "contactUsMessageTextFieldErrorText": "Le texte doit contenir au moins 30 caractères", + "@contactUsMessageTextFieldErrorText": { + "description": "Il s'agit du texte d'erreur affiché en cas d'échec de la validation du champ textformfield de la page Contactez-nous." + }, + "contactUsSuccessTitle": "Merci de nous contacter !!", + "@contactUsSuccessTitle": { + "description": "Il s'agit du texte du titre affiché sur la page de succès Contactez-nous" + }, + "contactUsSuccessText": "Nous avons reçu votre message. Nous lisons tous les messages et nous répondons généralement dans les 48 heures si une réponse est nécessaire", + "@contactUsSuccessText": { + "description": "C'est le texte qui s'affiche sur la page de succès contactez-nous" + }, + "contactUsSuccessBtnText": "Retourner", + "@contactUsSuccessBtnText": { + "description": "Il s'agit de l'étiquette du bouton affiché sur la page de succès Contactez-nous" } } From e250efd19a08f05cecd60485351624147ab801f3 Mon Sep 17 00:00:00 2001 From: Tiku Gaelle Date: Tue, 14 Mar 2023 18:37:17 +0100 Subject: [PATCH 3/4] fix: updated contact us page with form validation logic --- lib/contact_us/view/contact_us_page.dart | 16 +++++++++---- .../view/contact_us_success_page.dart | 5 +++- .../widgets/contact_us_success_texts.dart | 7 +++++- .../view/widgets/message_textfield.dart | 23 +++++++++++-------- .../presentation/widget/my_textformfield.dart | 22 +++++++++--------- .../shared/helpers/extensions.dart} | 6 ----- 6 files changed, 45 insertions(+), 34 deletions(-) rename lib/{contact_us/domain/form_validation.dart => core/shared/helpers/extensions.dart} (70%) diff --git a/lib/contact_us/view/contact_us_page.dart b/lib/contact_us/view/contact_us_page.dart index 5962b97..68857fa 100644 --- a/lib/contact_us/view/contact_us_page.dart +++ b/lib/contact_us/view/contact_us_page.dart @@ -6,9 +6,9 @@ import 'package:fpb/contact_us/contact_us_page.dart'; import 'package:fpb/contact_us/view/widgets/message_textfield.dart'; import 'package:fpb/core/presentation/widget/my_button.dart'; import 'package:fpb/core/presentation/widget/my_textformfield.dart'; +import 'package:fpb/core/shared/helpers/extensions.dart'; import 'package:fpb/l10n/l10n.dart'; import 'package:fpb/sign_in/view/sign_in_page.dart'; -import '../domain/form_validation.dart'; class ContactUsPage extends StatefulWidget { const ContactUsPage({super.key}); @@ -86,7 +86,7 @@ class _ContactUsPageState extends State { box: box, validator: (val) { if (val!.isEmpty) { - return null; + return 'Field is required'; } else if (val.isValidName) { return null; } else { @@ -94,6 +94,9 @@ class _ContactUsPageState extends State { } }, ), + SizedBox( + height: box.maxHeight * .03, + ), FpbTextFormField( onChanged: (value) { setState(() {}); @@ -104,7 +107,7 @@ class _ContactUsPageState extends State { box: box, validator: (val) { if (val!.isEmpty) { - return null; + return 'Field is required'; } else if (val.isValidEmail) { return null; } else { @@ -112,12 +115,15 @@ class _ContactUsPageState extends State { } }, ), - messageTextField( + SizedBox( + height: box.maxHeight * .03, + ), + MessageTextField( theme: theme, box: box, validator: (val) { if (val!.isEmpty) { - return null; + return 'Field is required'; } else if (val.length > 30 && val.length < 500) { return null; diff --git a/lib/contact_us/view/contact_us_success_page.dart b/lib/contact_us/view/contact_us_success_page.dart index cd91fb7..fffa83c 100644 --- a/lib/contact_us/view/contact_us_success_page.dart +++ b/lib/contact_us/view/contact_us_success_page.dart @@ -44,6 +44,7 @@ class ContactUsSuccessPage extends StatelessWidget { bottom: box.maxHeight * .005), child: Column( crossAxisAlignment: CrossAxisAlignment.center, + children: [ SizedBox( height: box.maxHeight * .1, @@ -52,7 +53,9 @@ class ContactUsSuccessPage extends StatelessWidget { SizedBox( height: box.maxHeight * .0001, ), - ContactUsSuccessTexts(l10n: l10n, style: style, box: box), + ContactUsSuccessTexts( + + l10n: l10n, style: style, box: box), SizedBox( height: box.maxHeight * .15, ), diff --git a/lib/contact_us/view/widgets/contact_us_success_texts.dart b/lib/contact_us/view/widgets/contact_us_success_texts.dart index 412afc9..c64935c 100644 --- a/lib/contact_us/view/widgets/contact_us_success_texts.dart +++ b/lib/contact_us/view/widgets/contact_us_success_texts.dart @@ -20,12 +20,17 @@ class ContactUsSuccessTexts extends StatelessWidget { Text( l10n.contactUsSuccessTitle, maxLines: 2, + textAlign: TextAlign.center, style: style.titleLarge, ), SizedBox( height: box.maxHeight * .025, ), - Text(l10n.contactUsSuccessText, maxLines: 3, style: style.titleMedium), + Text( + l10n.contactUsSuccessText, + maxLines: 3, + textAlign: TextAlign.center, + style: style.titleMedium), ], ); } diff --git a/lib/contact_us/view/widgets/message_textfield.dart b/lib/contact_us/view/widgets/message_textfield.dart index f1fa5c8..0ad0ea6 100644 --- a/lib/contact_us/view/widgets/message_textfield.dart +++ b/lib/contact_us/view/widgets/message_textfield.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:fpb/l10n/l10n.dart'; import 'package:fpb/core/presentation/extension/extensions.dart'; -class messageTextField extends StatefulWidget { - const messageTextField( +class MessageTextField extends StatefulWidget { + const MessageTextField( {super.key, required this.theme, required this.box, @@ -14,10 +14,10 @@ class messageTextField extends StatefulWidget { final String? Function(String?)? validator; @override - State createState() => _messageTextFieldState(); + State createState() => _MessageTextFieldState(); } -class _messageTextFieldState extends State { +class _MessageTextFieldState extends State { final messageController = TextEditingController(); @override @@ -34,18 +34,18 @@ class _messageTextFieldState extends State { style: style.titleSmall, ), TextFormField( + autovalidateMode: AutovalidateMode.always, onChanged: (value) { setState(() {}); }, maxLength: 500, controller: messageController, - //validator: widget.validator, + validator: (value) => widget.validator?.call(value) != null ? "" : null, maxLines: 3, decoration: InputDecoration( hintText: l10n.contactUsMessageTextFieldHintText, - errorStyle: TextStyle( - color: theme.colorScheme.secondaryContainer, - ), + //errorText: '', + errorStyle: const TextStyle(height: 0), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(widget.box.maxHeight * .025), borderSide: BorderSide( @@ -53,9 +53,12 @@ class _messageTextFieldState extends State { ), ), ), - ).validatorWidget(widget.validator?.call(messageController.text)).card( + ).card( padding: - EdgeInsets.symmetric(vertical: widget.box.maxHeight * .007)), + EdgeInsets.symmetric(vertical: widget.box.maxHeight * .007)). + validatorWidget( + //messageController.text.isEmpty ? null : + widget.validator?.call(messageController.text)), ], ); } diff --git a/lib/core/presentation/widget/my_textformfield.dart b/lib/core/presentation/widget/my_textformfield.dart index ece5fd2..cfd0983 100644 --- a/lib/core/presentation/widget/my_textformfield.dart +++ b/lib/core/presentation/widget/my_textformfield.dart @@ -58,7 +58,8 @@ class _FpbTextFormFieldState extends State { ) : SizedBox(), TextFormField( - validator: widget.validator, + autovalidateMode: AutovalidateMode.always, + validator: (value) => widget.validator?.call(value) != null ? "" : null, controller: widget.textController, focusNode: widget.node, keyboardType: widget.isEmail @@ -71,10 +72,8 @@ class _FpbTextFormFieldState extends State { style: textTheme .titleSmall, //bodyMedium //.copyWith(color: colors.onSurface), decoration: InputDecoration( - errorStyle: TextStyle( - color: theme.colorScheme.secondaryContainer, - ), - errorText: widget.errorText, + errorStyle: const TextStyle(height: 0), + //errorText: widget.errorText, suffixIcon: !widget.isPassword ? null : hidePassword! @@ -117,14 +116,15 @@ class _FpbTextFormFieldState extends State { hintText: widget.hint, ), ) - .validatorWidget( - widget.validator?.call(widget.textController?.text)) .card( - height: widget.box.maxHeight * 0.12, + //height: widget.box.maxHeight * 0.14, padding: EdgeInsets.symmetric( - vertical: widget.box.maxHeight * 0.007, - ), - ), + vertical: widget.box.maxHeight * 0.009, + )).validatorWidget( + //widget.textController != null && widget.textController!.text.isEmpty ? null : + widget.validator?.call( + widget.textController?.text)), + ], ); } diff --git a/lib/contact_us/domain/form_validation.dart b/lib/core/shared/helpers/extensions.dart similarity index 70% rename from lib/contact_us/domain/form_validation.dart rename to lib/core/shared/helpers/extensions.dart index 158477b..88c66a2 100644 --- a/lib/contact_us/domain/form_validation.dart +++ b/lib/core/shared/helpers/extensions.dart @@ -10,12 +10,6 @@ extension extString on String { return nameRegExp.hasMatch(this); } - // bool get isValidMessage { - // final messageRegExp = - // RegExp(r"^\s*([A-Za-z]{1,}([\.,] |[-']| ))+[A-Za-z]+\.?\s*$"); - // return messageRegExp.hasMatch(this); - // } - bool get isNotNull { // ignore: unnecessary_null_comparison return this != null; From 302464537125de24ba23c97373e6b4c341ce8d76 Mon Sep 17 00:00:00 2001 From: Tiku Gaelle Date: Thu, 16 Mar 2023 15:57:54 +0100 Subject: [PATCH 4/4] refactor: code refactor and added routes --- lib/contact_us/contact_us_page.dart | 2 - lib/contact_us/contact_us_screen.dart | 2 + ...ct_us_page.dart => contact_us_screen.dart} | 22 +-- .../view/contact_us_success_page.dart | 77 --------- .../view/contact_us_success_screen.dart | 79 +++++++++ lib/router/app_route.dart | 11 +- lib/router/app_route.gr.dart | 161 +++++++++++------- 7 files changed, 202 insertions(+), 152 deletions(-) delete mode 100644 lib/contact_us/contact_us_page.dart create mode 100644 lib/contact_us/contact_us_screen.dart rename lib/contact_us/view/{contact_us_page.dart => contact_us_screen.dart} (90%) delete mode 100644 lib/contact_us/view/contact_us_success_page.dart create mode 100644 lib/contact_us/view/contact_us_success_screen.dart diff --git a/lib/contact_us/contact_us_page.dart b/lib/contact_us/contact_us_page.dart deleted file mode 100644 index 874b367..0000000 --- a/lib/contact_us/contact_us_page.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'view/contact_us_page.dart'; -export 'view/contact_us_success_page.dart'; diff --git a/lib/contact_us/contact_us_screen.dart b/lib/contact_us/contact_us_screen.dart new file mode 100644 index 0000000..8726516 --- /dev/null +++ b/lib/contact_us/contact_us_screen.dart @@ -0,0 +1,2 @@ +export 'view/contact_us_screen.dart'; +export 'view/contact_us_success_screen.dart'; diff --git a/lib/contact_us/view/contact_us_page.dart b/lib/contact_us/view/contact_us_screen.dart similarity index 90% rename from lib/contact_us/view/contact_us_page.dart rename to lib/contact_us/view/contact_us_screen.dart index 43bec0e..00598b5 100644 --- a/lib/contact_us/view/contact_us_page.dart +++ b/lib/contact_us/view/contact_us_screen.dart @@ -1,23 +1,25 @@ // ignore_for_file: body_might_complete_normally_nullable +import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:fpb/assets/fpb_svg.dart'; -import 'package:fpb/contact_us/contact_us_page.dart'; +import 'package:fpb/contact_us/contact_us_screen.dart'; import 'package:fpb/contact_us/view/widgets/message_textfield.dart'; import 'package:fpb/core/presentation/widget/fpb_button.dart'; import 'package:fpb/core/presentation/widget/fpb_text_form_field.dart'; import 'package:fpb/core/shared/helpers/extensions.dart'; import 'package:fpb/l10n/l10n.dart'; +import 'package:fpb/router/app_route.gr.dart'; import 'package:fpb/sign_in/view/sign_in_page.dart'; -class ContactUsPage extends StatefulWidget { - const ContactUsPage({super.key}); +class ContactUsScreen extends StatefulWidget { + const ContactUsScreen({super.key}); @override - State createState() => _ContactUsPageState(); + State createState() => _ContactUsScreenState(); } -class _ContactUsPageState extends State { +class _ContactUsScreenState extends State { final _formKey = GlobalKey(); final nameController = TextEditingController(); final emailController = TextEditingController(); @@ -145,14 +147,8 @@ class _ContactUsPageState extends State { label: l10n.contactUsSubmitBtnLabel, onTap: () { if (_formKey.currentState!.validate()) { - Navigator.of(context).push( - // ignore: inference_failure_on_instance_creation - MaterialPageRoute( - builder: (context) => - ContactUsSuccessPage( - box: box, - ), - ), + context.router.push( + ContactUsSuccessRoute() ); } else {} }) diff --git a/lib/contact_us/view/contact_us_success_page.dart b/lib/contact_us/view/contact_us_success_page.dart deleted file mode 100644 index fffa83c..0000000 --- a/lib/contact_us/view/contact_us_success_page.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:fpb/assets/fpb_svg.dart'; -import 'package:fpb/contact_us/view/widgets/contact_us_success_btn.dart'; -import 'package:fpb/contact_us/view/widgets/contact_us_success_image.dart'; -import 'package:fpb/contact_us/view/widgets/contact_us_success_texts.dart'; -import 'package:fpb/l10n/l10n.dart'; -import 'package:fpb/sign_in/view/sign_in_page.dart'; - -class ContactUsSuccessPage extends StatelessWidget { - const ContactUsSuccessPage({super.key, required this.box}); - - final BoxConstraints box; - @override - Widget build(BuildContext context) { - final l10n = context.l10n; - final theme = Theme.of(context); - final style = theme.textTheme; - //final colors = theme.colorScheme; - - return Scaffold( - resizeToAvoidBottomInset: false, - body: Stack(children: [ - BubblesTopBackGround( - cts: box, - svgName: SvgNames.authBackground, - ), - Align( - alignment: Alignment.bottomCenter, - child: Container( - height: box.maxHeight * .75, - width: box.maxWidth, - decoration: BoxDecoration( - color: theme.colorScheme.background, - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(20), - topRight: Radius.circular(20), - ), - ), - child: Padding( - padding: EdgeInsets.only( - top: box.maxHeight * .025, - left: box.maxHeight * .025, - right: box.maxHeight * .025, - bottom: box.maxHeight * .005), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - - children: [ - SizedBox( - height: box.maxHeight * .1, - ), - ContactUsSuccessImageWidget(box: box), - SizedBox( - height: box.maxHeight * .0001, - ), - ContactUsSuccessTexts( - - l10n: l10n, style: style, box: box), - SizedBox( - height: box.maxHeight * .15, - ), - ContactUsSuccessBtn( - style: style, - box: box, - backgroundColor: theme.colorScheme.background, - borderColor: theme.colorScheme.secondary, - text: l10n.contactUsSuccessBtnText, - textColor: theme.colorScheme.secondary, - ) - ], - ), - ), - )) - ]), - ); - } -} diff --git a/lib/contact_us/view/contact_us_success_screen.dart b/lib/contact_us/view/contact_us_success_screen.dart new file mode 100644 index 0000000..cc94e7d --- /dev/null +++ b/lib/contact_us/view/contact_us_success_screen.dart @@ -0,0 +1,79 @@ +import 'package:flutter/material.dart'; +import 'package:fpb/assets/fpb_svg.dart'; +import 'package:fpb/contact_us/view/widgets/contact_us_success_btn.dart'; +import 'package:fpb/contact_us/view/widgets/contact_us_success_image.dart'; +import 'package:fpb/contact_us/view/widgets/contact_us_success_texts.dart'; +import 'package:fpb/l10n/l10n.dart'; +import 'package:fpb/sign_in/view/sign_in_page.dart'; + +class ContactUsSuccessScreen extends StatelessWidget { + const ContactUsSuccessScreen({super.key, }); + + @override + Widget build(BuildContext context) { + final l10n = context.l10n; + final theme = Theme.of(context); + final style = theme.textTheme; + //final colors = theme.colorScheme; + + return LayoutBuilder( + builder: (context, box){ + return Scaffold( + resizeToAvoidBottomInset: false, + body: Stack(children: [ + BubblesTopBackGround( + cts: box, + svgName: SvgNames.authBackground, + ), + Align( + alignment: Alignment.bottomCenter, + child: Container( + height: box.maxHeight * .75, + width: box.maxWidth, + decoration: BoxDecoration( + color: theme.colorScheme.background, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + ), + child: Padding( + padding: EdgeInsets.only( + top: box.maxHeight * .025, + left: box.maxHeight * .025, + right: box.maxHeight * .025, + bottom: box.maxHeight * .005), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + + children: [ + SizedBox( + height: box.maxHeight * .1, + ), + ContactUsSuccessImageWidget(box: box), + SizedBox( + height: box.maxHeight * .0001, + ), + ContactUsSuccessTexts( + + l10n: l10n, style: style, box: box), + SizedBox( + height: box.maxHeight * .15, + ), + ContactUsSuccessBtn( + style: style, + box: box, + backgroundColor: theme.colorScheme.background, + borderColor: theme.colorScheme.secondary, + text: l10n.contactUsSuccessBtnText, + textColor: theme.colorScheme.secondary, + ) + ], + ), + ), + )) + ]), + ); + }); + } +} diff --git a/lib/router/app_route.dart b/lib/router/app_route.dart index 810d489..0437617 100644 --- a/lib/router/app_route.dart +++ b/lib/router/app_route.dart @@ -1,5 +1,6 @@ import 'package:auto_route/annotations.dart'; -import 'package:fpb/contact_us/view/contact_us_page.dart'; +import 'package:fpb/contact_us/contact_us_page.dart'; +import 'package:fpb/contact_us/view/contact_us_screen.dart'; import 'package:fpb/email_confirmation/email_confirmation.dart'; import 'package:fpb/home/view/home_screen.dart'; import 'package:fpb/latest_activities/view/latest_activities_screen.dart'; @@ -15,7 +16,7 @@ import 'package:fpb/sign_up/view/signup_page.dart'; @MaterialAutoRouter( replaceInRouteName: 'Screen,Route', routes: [ - AutoRoute(page: ContactUsPage, initial: true), + AutoRoute(page: SplashScreen, initial: true), AutoRoute(page: SignInScreen), AutoRoute(page: PhoneNumberConfirmationScreen), AutoRoute(page: EmailConfirmationScreen), @@ -39,6 +40,12 @@ import 'package:fpb/sign_up/view/signup_page.dart'; page: QrCodeScreen, ), AutoRoute(page: OnboardingScreen), + AutoRoute( + page: ContactUsScreen, + ), + AutoRoute( + page: ContactUsSuccessScreen, + ) ], ) class $AppRoute {} diff --git a/lib/router/app_route.gr.dart b/lib/router/app_route.gr.dart index 8e8c3e2..7a5a657 100644 --- a/lib/router/app_route.gr.dart +++ b/lib/router/app_route.gr.dart @@ -11,68 +11,69 @@ // ignore_for_file: type=lint // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:auto_route/auto_route.dart' as _i12; -import 'package:flutter/material.dart' as _i13; +import 'package:auto_route/auto_route.dart' as _i13; +import 'package:flutter/material.dart' as _i14; -import '../contact_us/view/contact_us_page.dart' as _i1; -import '../core/domain/user.dart' as _i14; +import '../contact_us/contact_us_page.dart' as _i11; +import '../core/domain/user.dart' as _i15; import '../email_confirmation/email_confirmation.dart' as _i4; import '../home/view/home_screen.dart' as _i7; import '../latest_activities/view/latest_activities_screen.dart' as _i8; import '../onboarding/view/onboarding_screens.dart' as _i10; +import '../onboarding/view/splash_screen.dart' as _i1; import '../phone_number_confirmation/view/phone_number_confirmation.dart' as _i3; -import '../profile/view/profile_page.dart' as _i11; +import '../profile/view/profile_page.dart' as _i12; import '../qr_code_screen/view/qr_code_screen.dart' as _i9; import '../savings/save_money_with_bucket/save_money_with_bucket.dart' as _i6; import '../sign_in/view/sign_in_page.dart' as _i2; import '../sign_up/view/signup_page.dart' as _i5; -class AppRoute extends _i12.RootStackRouter { - AppRoute([_i13.GlobalKey<_i13.NavigatorState>? navigatorKey]) +class AppRoute extends _i13.RootStackRouter { + AppRoute([_i14.GlobalKey<_i14.NavigatorState>? navigatorKey]) : super(navigatorKey); @override - final Map pagesMap = { - ContactUsPage.name: (routeData) { - return _i12.MaterialPageX( + final Map pagesMap = { + SplashRoute.name: (routeData) { + return _i13.MaterialPageX( routeData: routeData, - child: const _i1.ContactUsPage(), + child: const _i1.SplashScreen(), ); }, SignInRoute.name: (routeData) { - return _i12.MaterialPageX( + return _i13.MaterialPageX( routeData: routeData, child: const _i2.SignInScreen(), ); }, PhoneNumberConfirmationRoute.name: (routeData) { - return _i12.MaterialPageX( + return _i13.MaterialPageX( routeData: routeData, child: const _i3.PhoneNumberConfirmationScreen(), ); }, EmailConfirmationRoute.name: (routeData) { - return _i12.MaterialPageX( + return _i13.MaterialPageX( routeData: routeData, child: const _i4.EmailConfirmationScreen(), ); }, SignUpRoute.name: (routeData) { - return _i12.MaterialPageX( + return _i13.MaterialPageX( routeData: routeData, child: const _i5.SignUpScreen(), ); }, SaveMoneyRoute.name: (routeData) { - return _i12.MaterialPageX( + return _i13.MaterialPageX( routeData: routeData, child: const _i6.SaveMoneyScreen(), ); }, HomeRouter.name: (routeData) { final args = routeData.argsAs(); - return _i12.MaterialPageX( + return _i13.MaterialPageX( routeData: routeData, child: _i7.HomeScreen( key: args.key, @@ -81,13 +82,13 @@ class AppRoute extends _i12.RootStackRouter { ); }, LatestActivitiesPage.name: (routeData) { - return _i12.MaterialPageX( + return _i13.MaterialPageX( routeData: routeData, child: const _i8.LatestActivitiesPage(), ); }, QrCodeRoute.name: (routeData) { - return _i12.MaterialPageX( + return _i13.MaterialPageX( routeData: routeData, child: const _i9.QrCodeScreen(), ); @@ -95,7 +96,7 @@ class AppRoute extends _i12.RootStackRouter { OnboardingRoute.name: (routeData) { final args = routeData.argsAs( orElse: () => const OnboardingRouteArgs()); - return _i12.MaterialPageX( + return _i13.MaterialPageX( routeData: routeData, child: _i10.OnboardingScreen( onGetStartedPressed: args.onGetStartedPressed, @@ -103,81 +104,101 @@ class AppRoute extends _i12.RootStackRouter { ), ); }, + ContactUsRoute.name: (routeData) { + return _i13.MaterialPageX( + routeData: routeData, + child: const _i11.ContactUsScreen(), + ); + }, + ContactUsSuccessRoute.name: (routeData) { + return _i13.MaterialPageX( + routeData: routeData, + child: const _i11.ContactUsSuccessScreen(), + ); + }, ProfileRoute.name: (routeData) { - return _i12.MaterialPageX( + return _i13.MaterialPageX( routeData: routeData, - child: const _i11.ProfileScreen(), + child: const _i12.ProfileScreen(), ); }, }; @override - List<_i12.RouteConfig> get routes => [ - _i12.RouteConfig( - ContactUsPage.name, + List<_i13.RouteConfig> get routes => [ + _i13.RouteConfig( + SplashRoute.name, path: '/', ), - _i12.RouteConfig( + _i13.RouteConfig( SignInRoute.name, path: '/sign-in-screen', ), - _i12.RouteConfig( + _i13.RouteConfig( PhoneNumberConfirmationRoute.name, path: '/phone-number-confirmation-screen', ), - _i12.RouteConfig( + _i13.RouteConfig( EmailConfirmationRoute.name, path: '/email-confirmation-screen', ), - _i12.RouteConfig( + _i13.RouteConfig( SignUpRoute.name, path: '/sign-up-screen', ), - _i12.RouteConfig( + _i13.RouteConfig( SaveMoneyRoute.name, path: '/save-money-screen', ), - _i12.RouteConfig( + _i13.RouteConfig( HomeRouter.name, path: '/home-screen', children: [ - _i12.RouteConfig( + _i13.RouteConfig( ProfileRoute.name, path: 'profile', parent: HomeRouter.name, ) ], ), - _i12.RouteConfig( + _i13.RouteConfig( LatestActivitiesPage.name, path: 'latestActivities', ), - _i12.RouteConfig( + _i13.RouteConfig( QrCodeRoute.name, path: '/qr-code-screen', ), - _i12.RouteConfig( + _i13.RouteConfig( OnboardingRoute.name, path: '/onboarding-screen', ), + _i13.RouteConfig( + ContactUsRoute.name, + path: '/contact-us-screen', + ), + _i13.RouteConfig( + ContactUsSuccessRoute.name, + path: '/contact-us-success-screen', + ), ]; } /// generated route for -/// [_i1.ContactUsPage] -class ContactUsPage extends _i12.PageRouteInfo { - const ContactUsPage() +/// [_i1.SplashScreen] +class SplashRoute extends _i13.PageRouteInfo { + const SplashRoute() : super( - ContactUsPage.name, + SplashRoute.name, path: '/', ); - static const String name = 'ContactUsPage'; + static const String name = 'SplashRoute'; } /// generated route for /// [_i2.SignInScreen] -class SignInRoute extends _i12.PageRouteInfo { +class SignInRoute extends _i13.PageRouteInfo { const SignInRoute() : super( SignInRoute.name, @@ -189,7 +210,7 @@ class SignInRoute extends _i12.PageRouteInfo { /// generated route for /// [_i3.PhoneNumberConfirmationScreen] -class PhoneNumberConfirmationRoute extends _i12.PageRouteInfo { +class PhoneNumberConfirmationRoute extends _i13.PageRouteInfo { const PhoneNumberConfirmationRoute() : super( PhoneNumberConfirmationRoute.name, @@ -201,7 +222,7 @@ class PhoneNumberConfirmationRoute extends _i12.PageRouteInfo { /// generated route for /// [_i4.EmailConfirmationScreen] -class EmailConfirmationRoute extends _i12.PageRouteInfo { +class EmailConfirmationRoute extends _i13.PageRouteInfo { const EmailConfirmationRoute() : super( EmailConfirmationRoute.name, @@ -213,7 +234,7 @@ class EmailConfirmationRoute extends _i12.PageRouteInfo { /// generated route for /// [_i5.SignUpScreen] -class SignUpRoute extends _i12.PageRouteInfo { +class SignUpRoute extends _i13.PageRouteInfo { const SignUpRoute() : super( SignUpRoute.name, @@ -225,7 +246,7 @@ class SignUpRoute extends _i12.PageRouteInfo { /// generated route for /// [_i6.SaveMoneyScreen] -class SaveMoneyRoute extends _i12.PageRouteInfo { +class SaveMoneyRoute extends _i13.PageRouteInfo { const SaveMoneyRoute() : super( SaveMoneyRoute.name, @@ -237,11 +258,11 @@ class SaveMoneyRoute extends _i12.PageRouteInfo { /// generated route for /// [_i7.HomeScreen] -class HomeRouter extends _i12.PageRouteInfo { +class HomeRouter extends _i13.PageRouteInfo { HomeRouter({ - _i13.Key? key, - required _i14.User user, - List<_i12.PageRouteInfo>? children, + _i14.Key? key, + required _i15.User user, + List<_i13.PageRouteInfo>? children, }) : super( HomeRouter.name, path: '/home-screen', @@ -261,9 +282,9 @@ class HomeRouterArgs { required this.user, }); - final _i13.Key? key; + final _i14.Key? key; - final _i14.User user; + final _i15.User user; @override String toString() { @@ -273,7 +294,7 @@ class HomeRouterArgs { /// generated route for /// [_i8.LatestActivitiesPage] -class LatestActivitiesPage extends _i12.PageRouteInfo { +class LatestActivitiesPage extends _i13.PageRouteInfo { const LatestActivitiesPage() : super( LatestActivitiesPage.name, @@ -285,7 +306,7 @@ class LatestActivitiesPage extends _i12.PageRouteInfo { /// generated route for /// [_i9.QrCodeScreen] -class QrCodeRoute extends _i12.PageRouteInfo { +class QrCodeRoute extends _i13.PageRouteInfo { const QrCodeRoute() : super( QrCodeRoute.name, @@ -297,10 +318,10 @@ class QrCodeRoute extends _i12.PageRouteInfo { /// generated route for /// [_i10.OnboardingScreen] -class OnboardingRoute extends _i12.PageRouteInfo { +class OnboardingRoute extends _i13.PageRouteInfo { OnboardingRoute({ void Function()? onGetStartedPressed, - _i13.Key? key, + _i14.Key? key, }) : super( OnboardingRoute.name, path: '/onboarding-screen', @@ -321,7 +342,7 @@ class OnboardingRouteArgs { final void Function()? onGetStartedPressed; - final _i13.Key? key; + final _i14.Key? key; @override String toString() { @@ -330,8 +351,32 @@ class OnboardingRouteArgs { } /// generated route for -/// [_i11.ProfileScreen] -class ProfileRoute extends _i12.PageRouteInfo { +/// [_i11.ContactUsScreen] +class ContactUsRoute extends _i13.PageRouteInfo { + const ContactUsRoute() + : super( + ContactUsRoute.name, + path: '/contact-us-screen', + ); + + static const String name = 'ContactUsRoute'; +} + +/// generated route for +/// [_i11.ContactUsSuccessScreen] +class ContactUsSuccessRoute extends _i13.PageRouteInfo { + const ContactUsSuccessRoute() + : super( + ContactUsSuccessRoute.name, + path: '/contact-us-success-screen', + ); + + static const String name = 'ContactUsSuccessRoute'; +} + +/// generated route for +/// [_i12.ProfileScreen] +class ProfileRoute extends _i13.PageRouteInfo { const ProfileRoute() : super( ProfileRoute.name,