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/assets/fpb-assets/email_success.png b/assets/fpb-assets/email_success.png
new file mode 100644
index 0000000..d174864
Binary files /dev/null and b/assets/fpb-assets/email_success.png differ
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/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_screen.dart b/lib/contact_us/view/contact_us_screen.dart
new file mode 100644
index 0000000..00598b5
--- /dev/null
+++ b/lib/contact_us/view/contact_us_screen.dart
@@ -0,0 +1,163 @@
+// 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_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 ContactUsScreen extends StatefulWidget {
+ const ContactUsScreen({super.key});
+
+ @override
+ State createState() => _ContactUsScreenState();
+}
+
+class _ContactUsScreenState extends State {
+ final _formKey = GlobalKey();
+ final nameController = TextEditingController();
+ final emailController = TextEditingController();
+ String errorText = '';
+ //IconData errorIcon;
+ double errorContainerHeight = 0.0;
+
+ @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: true,
+ 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,
+ ),
+ Flexible(
+ child: SingleChildScrollView(
+ child: Form(
+ key: _formKey,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.end,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ FpbTextFormField(
+ onChanged: (value) {
+ setState(() {});
+ },
+ textController: nameController,
+ label: l10n.contactUsNameTextFieldLabel,
+ hint: l10n.contactUsNameTextFieldHintText,
+ box: box,
+ validator: (val) {
+ if (val!.isEmpty) {
+ return 'Field is required';
+ } else if (val.isValidName) {
+ return null;
+ } else {
+ return l10n.contactUsNameErrorText;
+ }
+ },
+ ),
+ SizedBox(
+ height: box.maxHeight * .03,
+ ),
+ FpbTextFormField(
+ onChanged: (value) {
+ setState(() {});
+ },
+ textController: emailController,
+ label: l10n.signInEmailTextFieldLabel,
+ hint: l10n.signInEmailTextFieldHintText,
+ box: box,
+ validator: (val) {
+ if (val!.isEmpty) {
+ return 'Field is required';
+ } else if (val.isValidEmail) {
+ return null;
+ } else {
+ return l10n.contactUsEmailErrorText;
+ }
+ },
+ ),
+ SizedBox(
+ height: box.maxHeight * .03,
+ ),
+ MessageTextField(
+ theme: theme,
+ box: box,
+ validator: (val) {
+ if (val!.isEmpty) {
+ return 'Field is required';
+ } else if (val.length > 30 &&
+ val.length < 500) {
+ return null;
+ } else {
+ return l10n
+ .contactUsMessageTextFieldErrorText;
+ }
+ },
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ SizedBox(
+ height: box.maxHeight * .05,
+ ),
+ FpbButton(
+ label: l10n.contactUsSubmitBtnLabel,
+ onTap: () {
+ if (_formKey.currentState!.validate()) {
+ context.router.push(
+ ContactUsSuccessRoute()
+ );
+ } else {}
+ })
+ ]),
+ ),
+ ),
+ )
+ ]));
+ },
+ );
+ }
+}
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/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..c64935c
--- /dev/null
+++ b/lib/contact_us/view/widgets/contact_us_success_texts.dart
@@ -0,0 +1,37 @@
+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,
+ textAlign: TextAlign.center,
+ style: style.titleLarge,
+ ),
+ SizedBox(
+ height: box.maxHeight * .025,
+ ),
+ 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
new file mode 100644
index 0000000..0ad0ea6
--- /dev/null
+++ b/lib/contact_us/view/widgets/message_textfield.dart
@@ -0,0 +1,65 @@
+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(
+ {super.key,
+ required this.theme,
+ required this.box,
+ required this.validator});
+
+ final ThemeData theme;
+ 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;
+
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ l10n.contactUsMessageTextFieldLabel,
+ style: style.titleSmall,
+ ),
+ TextFormField(
+ autovalidateMode: AutovalidateMode.always,
+ onChanged: (value) {
+ setState(() {});
+ },
+ maxLength: 500,
+ controller: messageController,
+ validator: (value) => widget.validator?.call(value) != null ? "" : null,
+ maxLines: 3,
+ decoration: InputDecoration(
+ hintText: l10n.contactUsMessageTextFieldHintText,
+ //errorText: '',
+ errorStyle: const TextStyle(height: 0),
+ focusedBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(widget.box.maxHeight * .025),
+ borderSide: BorderSide(
+ color: theme.colorScheme.onSurface,
+ ),
+ ),
+ ),
+ ).card(
+ padding:
+ EdgeInsets.symmetric(vertical: widget.box.maxHeight * .007)).
+ validatorWidget(
+ //messageController.text.isEmpty ? null :
+ widget.validator?.call(messageController.text)),
+ ],
+ );
+ }
+}
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/fpb_text_form_field.dart b/lib/core/presentation/widget/fpb_text_form_field.dart
index 672ef6a..cfd0983 100644
--- a/lib/core/presentation/widget/fpb_text_form_field.dart
+++ b/lib/core/presentation/widget/fpb_text_form_field.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,8 @@ class _FpbTextFormFieldState extends State {
)
: SizedBox(),
TextFormField(
+ autovalidateMode: AutovalidateMode.always,
+ validator: (value) => widget.validator?.call(value) != null ? "" : null,
controller: widget.textController,
focusNode: widget.node,
keyboardType: widget.isEmail
@@ -69,7 +72,8 @@ class _FpbTextFormFieldState extends State {
style: textTheme
.titleSmall, //bodyMedium //.copyWith(color: colors.onSurface),
decoration: InputDecoration(
- errorText: widget.errorText,
+ errorStyle: const TextStyle(height: 0),
+ //errorText: widget.errorText,
suffixIcon: !widget.isPassword
? null
: hidePassword!
@@ -111,12 +115,16 @@ class _FpbTextFormFieldState extends State {
),
hintText: widget.hint,
),
- ).card(
- height: widget.box.maxHeight * 0.11,
- padding: EdgeInsets.symmetric(
- vertical: widget.box.maxHeight * 0.007,
- ),
- ),
+ )
+ .card(
+ //height: widget.box.maxHeight * 0.14,
+ padding: EdgeInsets.symmetric(
+ 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/core/shared/helpers/extensions.dart b/lib/core/shared/helpers/extensions.dart
index 71efb31..40445d2 100644
--- a/lib/core/shared/helpers/extensions.dart
+++ b/lib/core/shared/helpers/extensions.dart
@@ -1,5 +1,22 @@
import 'package:flutter/material.dart';
+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 isNotNull {
+ // ignore: unnecessary_null_comparison
+ return this != null;
+
+ }}
/// Padding for screens
extension PaddingX on Widget {
Widget paddingDefault(BoxConstraints box) {
diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb
index 1ec51e7..abc46ed 100644
--- a/lib/l10n/arb/app_en.arb
+++ b/lib/l10n/arb/app_en.arb
@@ -232,6 +232,54 @@
"@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"
+ },
+ "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"
+ },
"termsOfUseTitle": "Terms and Conditions",
"@termsOfUseTitle": {
"description": "This is the title displayed on the terms of use screen"
diff --git a/lib/l10n/arb/app_fr.arb b/lib/l10n/arb/app_fr.arb
index 8359a06..304da11 100644
--- a/lib/l10n/arb/app_fr.arb
+++ b/lib/l10n/arb/app_fr.arb
@@ -232,6 +232,54 @@
"@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"
+ },
+ "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"
+ },
"termsOfUseTitle": "Termes et Conditions",
"@termsOfUseTitle": {
"description": "C'est le titre affiché sur l'écran des conditions d'utilisation"
diff --git a/lib/router/app_route.dart b/lib/router/app_route.dart
index 7f7ba41..0437617 100644
--- a/lib/router/app_route.dart
+++ b/lib/router/app_route.dart
@@ -1,4 +1,6 @@
import 'package:auto_route/annotations.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';
@@ -38,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 9d58a39..7a5a657 100644
--- a/lib/router/app_route.gr.dart
+++ b/lib/router/app_route.gr.dart
@@ -11,10 +11,11 @@
// 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 '../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;
@@ -22,57 +23,57 @@ 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 = {
+ final Map pagesMap = {
SplashRoute.name: (routeData) {
- return _i12.MaterialPageX(
+ return _i13.MaterialPageX(
routeData: routeData,
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,69 +104,89 @@ 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(
+ 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.SplashScreen]
-class SplashRoute extends _i12.PageRouteInfo {
+class SplashRoute extends _i13.PageRouteInfo {
const SplashRoute()
: super(
SplashRoute.name,
@@ -177,7 +198,7 @@ class SplashRoute extends _i12.PageRouteInfo {
/// 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,