Frontend first draft

This commit is contained in:
Arseni
2025-11-13 15:06:15 +03:00
parent e47f343afb
commit ddb54ddfdc
504 changed files with 25498 additions and 1 deletions

View File

@@ -0,0 +1,16 @@
import 'package:flutter/material.dart';
class SignUpBackButton extends StatelessWidget {
const SignUpBackButton({super.key});
@override
Widget build(BuildContext context) => Row(
children: [
IconButton(
onPressed: Navigator.of(context).pop,
icon: const Icon(Icons.arrow_back),
),
],
);
}

View File

@@ -0,0 +1,62 @@
import 'package:flutter/material.dart';
import 'package:pweb/pages/signup/buttons.dart';
import 'package:pweb/pages/signup/form/controllers.dart';
import 'package:pweb/pages/signup/form/feilds.dart';
import 'package:pweb/widgets/constrained_form.dart';
class SignUpFormContent extends StatelessWidget {
final GlobalKey<FormState> formKey;
final SignUpFormControllers controllers;
final bool autoValidateMode;
final VoidCallback onSignUp;
final VoidCallback onLogin;
const SignUpFormContent({
required this.formKey,
required this.controllers,
required this.autoValidateMode,
required this.onSignUp,
required this.onLogin,
super.key,
});
@override
Widget build(BuildContext context) => Align(
alignment: Alignment.center,
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 500, maxHeight: 700),
child: Card(
child: SingleChildScrollView(
child: Column(
children: [
Row(
children: [
IconButton(
onPressed: Navigator.of(context).pop,
icon: Icon(Icons.arrow_back),
),
],
),
ConstrainedForm(
formKey: formKey,
autovalidateMode: autoValidateMode
? AutovalidateMode.onUserInteraction
: AutovalidateMode.disabled,
children: [
SignUpFormFields(controllers: controllers),
SignUpButtonsRow(
onLogin: onLogin,
signUp: onSignUp,
isEnabled: true,
),
],
),
],
),
),
),
),
);
}

View File

@@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
class SignUpFormControllers {
final TextEditingController companyName = TextEditingController();
final TextEditingController description = TextEditingController();
final TextEditingController firstName = TextEditingController();
final TextEditingController lastName = TextEditingController();
final TextEditingController email = TextEditingController();
final TextEditingController password = TextEditingController();
final TextEditingController passwordConfirm = TextEditingController();
void dispose() {
companyName.dispose();
description.dispose();
firstName.dispose();
lastName.dispose();
email.dispose();
password.dispose();
passwordConfirm.dispose();
}
}

View File

@@ -0,0 +1,24 @@
import 'package:flutter/material.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
class DescriptionField extends StatelessWidget {
final TextEditingController controller;
const DescriptionField({super.key, required this.controller});
@override
Widget build(BuildContext context) {
return TextFormField(
controller: controller,
decoration: InputDecoration(
labelText: '${AppLocalizations.of(context)!.companyDescription} (${AppLocalizations.of(context)!.optional})',
hintText: AppLocalizations.of(context)!.companyDescriptionHint,
),
maxLines: 3,
maxLength: 500,
);
}
}

View File

@@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
//TODO check with /widgets/username.dart
class EmailField extends StatelessWidget {
final TextEditingController controller;
const EmailField({super.key, required this.controller});
static final _emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
@override
Widget build(BuildContext context) {
return TextFormField(
controller: controller,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: AppLocalizations.of(context)!.username,
hintText: AppLocalizations.of(context)!.usernameHint,
),
validator: (value) {
if (value == null || !_emailRegex.hasMatch(value)) {
return AppLocalizations.of(context)!.usernameErrorInvalid;
}
return null;
},
);
}
}

View File

@@ -0,0 +1,70 @@
import 'package:flutter/material.dart';
import 'package:pweb/pages/signup/form/controllers.dart';
import 'package:pweb/pages/signup/form/description.dart';
import 'package:pweb/pages/signup/form/email.dart';
import 'package:pweb/pages/signup/header.dart';
import 'package:pweb/widgets/password/hint/short.dart';
import 'package:pweb/widgets/password/password.dart';
import 'package:pweb/widgets/password/verify.dart';
import 'package:pweb/widgets/text_field.dart';
import 'package:pweb/widgets/vspacer.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
class SignUpFormFields extends StatelessWidget {
final SignUpFormControllers controllers;
const SignUpFormFields({
required this.controllers,
super.key,
});
@override
Widget build(BuildContext context) => Column(
children: [
const SignUpHeader(),
const VSpacer(),
NotEmptyTextFormField(
controller: controllers.companyName,
labelText: AppLocalizations.of(context)!.companyName,
readOnly: false,
error: AppLocalizations.of(context)!.companynameRequired,
),
const VSpacer(),
DescriptionField(
controller: controllers.description,
),
const VSpacer(),
NotEmptyTextFormField(
controller: controllers.firstName,
labelText: AppLocalizations.of(context)!.lastName,
readOnly: false,
error: AppLocalizations.of(context)!.enterLastName,
),
const VSpacer(),
NotEmptyTextFormField(
controller: controllers.lastName,
labelText: AppLocalizations.of(context)!.firstName,
readOnly: false,
error: AppLocalizations.of(context)!.enterFirstName,
),
const VSpacer(),
EmailField(controller: controllers.email),
const VSpacer(),
defaulRulesPasswordField(
context,
controller: controllers.password,
validationRuleBuilder: (rules, value) =>
shortValidation(context, rules, value),
),
const VSpacer(multiplier: 2.0),
VerifyPasswordField(
controller: controllers.passwordConfirm,
externalPasswordController: controllers.password,
),
const VSpacer(multiplier: 2.0),
],
);
}

View File

@@ -0,0 +1,11 @@
import 'package:flutter/material.dart';
import 'package:pweb/pages/signup/form/state.dart';
class SignUpForm extends StatefulWidget {
const SignUpForm({super.key});
@override
State<SignUpForm> createState() => SignUpFormState();
}

View File

@@ -0,0 +1,94 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:pshared/provider/pfe/provider.dart';
import 'package:pweb/app/router/pages.dart';
import 'package:pweb/pages/signup/form/content.dart';
import 'package:pweb/pages/signup/form/controllers.dart';
import 'package:pweb/pages/signup/form/form.dart';
import 'package:pweb/widgets/error/snackbar.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
class SignUpFormState extends State<SignUpForm> {
late final SignUpFormControllers controllers;
final _formKey = GlobalKey<FormState>();
bool _autoValidateMode = false;
@override
void initState() {
super.initState();
controllers = SignUpFormControllers();
}
Future<String?> signUp(
BuildContext context,
VoidCallback onSignUp,
void Function(Object e) onError,
) async {
final pfeProvider = Provider.of<PfeProvider>(context, listen: false);
setState(() {
_autoValidateMode = true;
});
if (!(_formKey.currentState?.validate() ?? false)) {
return null;
}
try {
// final account = await pfeProvider.signUp(
// companyName: controllers.companyName.text.trim(),
// description: controllers.description.text.trim().isEmpty
// ? null
// : controllers.description.text.trim(),
// firstName: controllers.firstName.text.trim(),
// lastName: controllers.lastName.text.trim(),
// email: controllers.email.text.trim(),
// password: controllers.password.text,
// );
onSignUp();
return 'ok';
} catch (e) {
onError(pfeProvider.error ?? e);
}
return null;
}
void handleSignUp() => signUp(
context,
() {
context.goNamed(
Pages.sfactor.name,
queryParameters: {'from': 'signup'},
);
},
(e) => postNotifyUserOfErrorX(
context: context,
errorSituation: AppLocalizations.of(context)!.errorSignUp,
exception: e,
),
);
void handleLogin() => navigate(context, Pages.login);
@override
void dispose() {
controllers.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) => SignUpFormContent(
formKey: _formKey,
controllers: controllers,
autoValidateMode: _autoValidateMode,
onSignUp: handleSignUp,
onLogin: handleLogin,
);
}