Explorar o código

config sign up

appflowy %!s(int64=3) %!d(string=hai) anos
pai
achega
85e3e07cbf

+ 0 - 0
app_flowy/assets/images/small_logo.svg → app_flowy/assets/images/flowy_logo.svg


+ 2 - 3
app_flowy/lib/user/application/sign_in/sign_in_bloc.dart → app_flowy/lib/user/application/sign_in_bloc.dart

@@ -2,7 +2,6 @@ import 'package:app_flowy/user/domain/i_auth.dart';
 import 'package:dartz/dartz.dart';
 import 'package:dartz/dartz.dart';
 import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
 import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
-// ignore: import_of_legacy_library_into_null_safe
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
 
 part 'sign_in_bloc.freezed.dart';
 part 'sign_in_bloc.freezed.dart';
@@ -35,8 +34,8 @@ class SignInBloc extends Bloc<SignInEvent, SignInState> {
 
 
     final result = await authImpl.signIn(state.email, state.password);
     final result = await authImpl.signIn(state.email, state.password);
     yield result.fold(
     yield result.fold(
-      (UserProfile) => state.copyWith(
-          isSubmitting: false, successOrFail: some(left(UserProfile))),
+      (userProfile) => state.copyWith(
+          isSubmitting: false, successOrFail: some(left(userProfile))),
       (error) => stateFromCode(error),
       (error) => stateFromCode(error),
     );
     );
   }
   }

+ 0 - 0
app_flowy/lib/user/application/sign_in/sign_in_bloc.freezed.dart → app_flowy/lib/user/application/sign_in_bloc.freezed.dart


+ 0 - 0
app_flowy/lib/user/application/sign_up/sign_up_bloc.dart


+ 87 - 0
app_flowy/lib/user/application/sign_up_bloc.dart

@@ -0,0 +1,87 @@
+import 'package:app_flowy/user/domain/i_auth.dart';
+import 'package:dartz/dartz.dart';
+import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
+import 'package:freezed_annotation/freezed_annotation.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+part 'sign_up_bloc.freezed.dart';
+
+class SignUpBloc extends Bloc<SignUpEvent, SignUpState> {
+  final IAuth authImpl;
+  SignUpBloc(this.authImpl) : super(SignUpState.initial());
+
+  @override
+  Stream<SignUpState> mapEventToState(
+    SignUpEvent event,
+  ) async* {
+    yield* event.map(
+      signUpWithUserEmailAndPassword: (e) async* {
+        yield* _performActionOnSignUp(
+          state,
+        );
+      },
+      emailChanged: (EmailChanged value) async* {
+        yield state.copyWith(email: value.email, successOrFail: none());
+      },
+      passwordChanged: (PasswordChanged value) async* {
+        yield state.copyWith(password: value.password, successOrFail: none());
+      },
+    );
+  }
+
+  Stream<SignUpState> _performActionOnSignUp(SignUpState state) async* {
+    yield state.copyWith(isSubmitting: true);
+
+    final result = await authImpl.signIn(state.email, state.password);
+    yield result.fold(
+      (userProfile) => state.copyWith(
+          isSubmitting: false, successOrFail: some(left(userProfile))),
+      (error) => stateFromCode(error),
+    );
+  }
+
+  SignUpState stateFromCode(UserError error) {
+    switch (error.code) {
+      case ErrorCode.EmailFormatInvalid:
+        return state.copyWith(
+            isSubmitting: false,
+            emailError: some(error.msg),
+            passwordError: none());
+      case ErrorCode.PasswordFormatInvalid:
+        return state.copyWith(
+            isSubmitting: false,
+            passwordError: some(error.msg),
+            emailError: none());
+      default:
+        return state.copyWith(
+            isSubmitting: false, successOrFail: some(right(error)));
+    }
+  }
+}
+
+@freezed
+abstract class SignUpEvent with _$SignUpEvent {
+  const factory SignUpEvent.signUpWithUserEmailAndPassword() =
+      SignUpWithUserEmailAndPassword;
+  const factory SignUpEvent.emailChanged(String email) = EmailChanged;
+  const factory SignUpEvent.passwordChanged(String password) = PasswordChanged;
+}
+
+@freezed
+abstract class SignUpState with _$SignUpState {
+  const factory SignUpState({
+    String? email,
+    String? password,
+    required bool isSubmitting,
+    required Option<String> passwordError,
+    required Option<String> emailError,
+    required Option<Either<UserProfile, UserError>> successOrFail,
+  }) = _SignUpState;
+
+  factory SignUpState.initial() => SignUpState(
+        isSubmitting: false,
+        passwordError: none(),
+        emailError: none(),
+        successOrFail: none(),
+      );
+}

+ 691 - 0
app_flowy/lib/user/application/sign_up_bloc.freezed.dart

@@ -0,0 +1,691 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
+
+part of 'sign_up_bloc.dart';
+
+// **************************************************************************
+// FreezedGenerator
+// **************************************************************************
+
+T _$identity<T>(T value) => value;
+
+final _privateConstructorUsedError = UnsupportedError(
+    'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
+
+/// @nodoc
+class _$SignUpEventTearOff {
+  const _$SignUpEventTearOff();
+
+  SignUpWithUserEmailAndPassword signUpWithUserEmailAndPassword() {
+    return const SignUpWithUserEmailAndPassword();
+  }
+
+  EmailChanged emailChanged(String email) {
+    return EmailChanged(
+      email,
+    );
+  }
+
+  PasswordChanged passwordChanged(String password) {
+    return PasswordChanged(
+      password,
+    );
+  }
+}
+
+/// @nodoc
+const $SignUpEvent = _$SignUpEventTearOff();
+
+/// @nodoc
+mixin _$SignUpEvent {
+  @optionalTypeArgs
+  TResult when<TResult extends Object?>({
+    required TResult Function() signUpWithUserEmailAndPassword,
+    required TResult Function(String email) emailChanged,
+    required TResult Function(String password) passwordChanged,
+  }) =>
+      throw _privateConstructorUsedError;
+  @optionalTypeArgs
+  TResult maybeWhen<TResult extends Object?>({
+    TResult Function()? signUpWithUserEmailAndPassword,
+    TResult Function(String email)? emailChanged,
+    TResult Function(String password)? passwordChanged,
+    required TResult orElse(),
+  }) =>
+      throw _privateConstructorUsedError;
+  @optionalTypeArgs
+  TResult map<TResult extends Object?>({
+    required TResult Function(SignUpWithUserEmailAndPassword value)
+        signUpWithUserEmailAndPassword,
+    required TResult Function(EmailChanged value) emailChanged,
+    required TResult Function(PasswordChanged value) passwordChanged,
+  }) =>
+      throw _privateConstructorUsedError;
+  @optionalTypeArgs
+  TResult maybeMap<TResult extends Object?>({
+    TResult Function(SignUpWithUserEmailAndPassword value)?
+        signUpWithUserEmailAndPassword,
+    TResult Function(EmailChanged value)? emailChanged,
+    TResult Function(PasswordChanged value)? passwordChanged,
+    required TResult orElse(),
+  }) =>
+      throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $SignUpEventCopyWith<$Res> {
+  factory $SignUpEventCopyWith(
+          SignUpEvent value, $Res Function(SignUpEvent) then) =
+      _$SignUpEventCopyWithImpl<$Res>;
+}
+
+/// @nodoc
+class _$SignUpEventCopyWithImpl<$Res> implements $SignUpEventCopyWith<$Res> {
+  _$SignUpEventCopyWithImpl(this._value, this._then);
+
+  final SignUpEvent _value;
+  // ignore: unused_field
+  final $Res Function(SignUpEvent) _then;
+}
+
+/// @nodoc
+abstract class $SignUpWithUserEmailAndPasswordCopyWith<$Res> {
+  factory $SignUpWithUserEmailAndPasswordCopyWith(
+          SignUpWithUserEmailAndPassword value,
+          $Res Function(SignUpWithUserEmailAndPassword) then) =
+      _$SignUpWithUserEmailAndPasswordCopyWithImpl<$Res>;
+}
+
+/// @nodoc
+class _$SignUpWithUserEmailAndPasswordCopyWithImpl<$Res>
+    extends _$SignUpEventCopyWithImpl<$Res>
+    implements $SignUpWithUserEmailAndPasswordCopyWith<$Res> {
+  _$SignUpWithUserEmailAndPasswordCopyWithImpl(
+      SignUpWithUserEmailAndPassword _value,
+      $Res Function(SignUpWithUserEmailAndPassword) _then)
+      : super(_value, (v) => _then(v as SignUpWithUserEmailAndPassword));
+
+  @override
+  SignUpWithUserEmailAndPassword get _value =>
+      super._value as SignUpWithUserEmailAndPassword;
+}
+
+/// @nodoc
+
+class _$SignUpWithUserEmailAndPassword
+    implements SignUpWithUserEmailAndPassword {
+  const _$SignUpWithUserEmailAndPassword();
+
+  @override
+  String toString() {
+    return 'SignUpEvent.signUpWithUserEmailAndPassword()';
+  }
+
+  @override
+  bool operator ==(dynamic other) {
+    return identical(this, other) || (other is SignUpWithUserEmailAndPassword);
+  }
+
+  @override
+  int get hashCode => runtimeType.hashCode;
+
+  @override
+  @optionalTypeArgs
+  TResult when<TResult extends Object?>({
+    required TResult Function() signUpWithUserEmailAndPassword,
+    required TResult Function(String email) emailChanged,
+    required TResult Function(String password) passwordChanged,
+  }) {
+    return signUpWithUserEmailAndPassword();
+  }
+
+  @override
+  @optionalTypeArgs
+  TResult maybeWhen<TResult extends Object?>({
+    TResult Function()? signUpWithUserEmailAndPassword,
+    TResult Function(String email)? emailChanged,
+    TResult Function(String password)? passwordChanged,
+    required TResult orElse(),
+  }) {
+    if (signUpWithUserEmailAndPassword != null) {
+      return signUpWithUserEmailAndPassword();
+    }
+    return orElse();
+  }
+
+  @override
+  @optionalTypeArgs
+  TResult map<TResult extends Object?>({
+    required TResult Function(SignUpWithUserEmailAndPassword value)
+        signUpWithUserEmailAndPassword,
+    required TResult Function(EmailChanged value) emailChanged,
+    required TResult Function(PasswordChanged value) passwordChanged,
+  }) {
+    return signUpWithUserEmailAndPassword(this);
+  }
+
+  @override
+  @optionalTypeArgs
+  TResult maybeMap<TResult extends Object?>({
+    TResult Function(SignUpWithUserEmailAndPassword value)?
+        signUpWithUserEmailAndPassword,
+    TResult Function(EmailChanged value)? emailChanged,
+    TResult Function(PasswordChanged value)? passwordChanged,
+    required TResult orElse(),
+  }) {
+    if (signUpWithUserEmailAndPassword != null) {
+      return signUpWithUserEmailAndPassword(this);
+    }
+    return orElse();
+  }
+}
+
+abstract class SignUpWithUserEmailAndPassword implements SignUpEvent {
+  const factory SignUpWithUserEmailAndPassword() =
+      _$SignUpWithUserEmailAndPassword;
+}
+
+/// @nodoc
+abstract class $EmailChangedCopyWith<$Res> {
+  factory $EmailChangedCopyWith(
+          EmailChanged value, $Res Function(EmailChanged) then) =
+      _$EmailChangedCopyWithImpl<$Res>;
+  $Res call({String email});
+}
+
+/// @nodoc
+class _$EmailChangedCopyWithImpl<$Res> extends _$SignUpEventCopyWithImpl<$Res>
+    implements $EmailChangedCopyWith<$Res> {
+  _$EmailChangedCopyWithImpl(
+      EmailChanged _value, $Res Function(EmailChanged) _then)
+      : super(_value, (v) => _then(v as EmailChanged));
+
+  @override
+  EmailChanged get _value => super._value as EmailChanged;
+
+  @override
+  $Res call({
+    Object? email = freezed,
+  }) {
+    return _then(EmailChanged(
+      email == freezed
+          ? _value.email
+          : email // ignore: cast_nullable_to_non_nullable
+              as String,
+    ));
+  }
+}
+
+/// @nodoc
+
+class _$EmailChanged implements EmailChanged {
+  const _$EmailChanged(this.email);
+
+  @override
+  final String email;
+
+  @override
+  String toString() {
+    return 'SignUpEvent.emailChanged(email: $email)';
+  }
+
+  @override
+  bool operator ==(dynamic other) {
+    return identical(this, other) ||
+        (other is EmailChanged &&
+            (identical(other.email, email) ||
+                const DeepCollectionEquality().equals(other.email, email)));
+  }
+
+  @override
+  int get hashCode =>
+      runtimeType.hashCode ^ const DeepCollectionEquality().hash(email);
+
+  @JsonKey(ignore: true)
+  @override
+  $EmailChangedCopyWith<EmailChanged> get copyWith =>
+      _$EmailChangedCopyWithImpl<EmailChanged>(this, _$identity);
+
+  @override
+  @optionalTypeArgs
+  TResult when<TResult extends Object?>({
+    required TResult Function() signUpWithUserEmailAndPassword,
+    required TResult Function(String email) emailChanged,
+    required TResult Function(String password) passwordChanged,
+  }) {
+    return emailChanged(email);
+  }
+
+  @override
+  @optionalTypeArgs
+  TResult maybeWhen<TResult extends Object?>({
+    TResult Function()? signUpWithUserEmailAndPassword,
+    TResult Function(String email)? emailChanged,
+    TResult Function(String password)? passwordChanged,
+    required TResult orElse(),
+  }) {
+    if (emailChanged != null) {
+      return emailChanged(email);
+    }
+    return orElse();
+  }
+
+  @override
+  @optionalTypeArgs
+  TResult map<TResult extends Object?>({
+    required TResult Function(SignUpWithUserEmailAndPassword value)
+        signUpWithUserEmailAndPassword,
+    required TResult Function(EmailChanged value) emailChanged,
+    required TResult Function(PasswordChanged value) passwordChanged,
+  }) {
+    return emailChanged(this);
+  }
+
+  @override
+  @optionalTypeArgs
+  TResult maybeMap<TResult extends Object?>({
+    TResult Function(SignUpWithUserEmailAndPassword value)?
+        signUpWithUserEmailAndPassword,
+    TResult Function(EmailChanged value)? emailChanged,
+    TResult Function(PasswordChanged value)? passwordChanged,
+    required TResult orElse(),
+  }) {
+    if (emailChanged != null) {
+      return emailChanged(this);
+    }
+    return orElse();
+  }
+}
+
+abstract class EmailChanged implements SignUpEvent {
+  const factory EmailChanged(String email) = _$EmailChanged;
+
+  String get email => throw _privateConstructorUsedError;
+  @JsonKey(ignore: true)
+  $EmailChangedCopyWith<EmailChanged> get copyWith =>
+      throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $PasswordChangedCopyWith<$Res> {
+  factory $PasswordChangedCopyWith(
+          PasswordChanged value, $Res Function(PasswordChanged) then) =
+      _$PasswordChangedCopyWithImpl<$Res>;
+  $Res call({String password});
+}
+
+/// @nodoc
+class _$PasswordChangedCopyWithImpl<$Res>
+    extends _$SignUpEventCopyWithImpl<$Res>
+    implements $PasswordChangedCopyWith<$Res> {
+  _$PasswordChangedCopyWithImpl(
+      PasswordChanged _value, $Res Function(PasswordChanged) _then)
+      : super(_value, (v) => _then(v as PasswordChanged));
+
+  @override
+  PasswordChanged get _value => super._value as PasswordChanged;
+
+  @override
+  $Res call({
+    Object? password = freezed,
+  }) {
+    return _then(PasswordChanged(
+      password == freezed
+          ? _value.password
+          : password // ignore: cast_nullable_to_non_nullable
+              as String,
+    ));
+  }
+}
+
+/// @nodoc
+
+class _$PasswordChanged implements PasswordChanged {
+  const _$PasswordChanged(this.password);
+
+  @override
+  final String password;
+
+  @override
+  String toString() {
+    return 'SignUpEvent.passwordChanged(password: $password)';
+  }
+
+  @override
+  bool operator ==(dynamic other) {
+    return identical(this, other) ||
+        (other is PasswordChanged &&
+            (identical(other.password, password) ||
+                const DeepCollectionEquality()
+                    .equals(other.password, password)));
+  }
+
+  @override
+  int get hashCode =>
+      runtimeType.hashCode ^ const DeepCollectionEquality().hash(password);
+
+  @JsonKey(ignore: true)
+  @override
+  $PasswordChangedCopyWith<PasswordChanged> get copyWith =>
+      _$PasswordChangedCopyWithImpl<PasswordChanged>(this, _$identity);
+
+  @override
+  @optionalTypeArgs
+  TResult when<TResult extends Object?>({
+    required TResult Function() signUpWithUserEmailAndPassword,
+    required TResult Function(String email) emailChanged,
+    required TResult Function(String password) passwordChanged,
+  }) {
+    return passwordChanged(password);
+  }
+
+  @override
+  @optionalTypeArgs
+  TResult maybeWhen<TResult extends Object?>({
+    TResult Function()? signUpWithUserEmailAndPassword,
+    TResult Function(String email)? emailChanged,
+    TResult Function(String password)? passwordChanged,
+    required TResult orElse(),
+  }) {
+    if (passwordChanged != null) {
+      return passwordChanged(password);
+    }
+    return orElse();
+  }
+
+  @override
+  @optionalTypeArgs
+  TResult map<TResult extends Object?>({
+    required TResult Function(SignUpWithUserEmailAndPassword value)
+        signUpWithUserEmailAndPassword,
+    required TResult Function(EmailChanged value) emailChanged,
+    required TResult Function(PasswordChanged value) passwordChanged,
+  }) {
+    return passwordChanged(this);
+  }
+
+  @override
+  @optionalTypeArgs
+  TResult maybeMap<TResult extends Object?>({
+    TResult Function(SignUpWithUserEmailAndPassword value)?
+        signUpWithUserEmailAndPassword,
+    TResult Function(EmailChanged value)? emailChanged,
+    TResult Function(PasswordChanged value)? passwordChanged,
+    required TResult orElse(),
+  }) {
+    if (passwordChanged != null) {
+      return passwordChanged(this);
+    }
+    return orElse();
+  }
+}
+
+abstract class PasswordChanged implements SignUpEvent {
+  const factory PasswordChanged(String password) = _$PasswordChanged;
+
+  String get password => throw _privateConstructorUsedError;
+  @JsonKey(ignore: true)
+  $PasswordChangedCopyWith<PasswordChanged> get copyWith =>
+      throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+class _$SignUpStateTearOff {
+  const _$SignUpStateTearOff();
+
+  _SignUpState call(
+      {String? email,
+      String? password,
+      required bool isSubmitting,
+      required Option<String> passwordError,
+      required Option<String> emailError,
+      required Option<Either<UserProfile, UserError>> successOrFail}) {
+    return _SignUpState(
+      email: email,
+      password: password,
+      isSubmitting: isSubmitting,
+      passwordError: passwordError,
+      emailError: emailError,
+      successOrFail: successOrFail,
+    );
+  }
+}
+
+/// @nodoc
+const $SignUpState = _$SignUpStateTearOff();
+
+/// @nodoc
+mixin _$SignUpState {
+  String? get email => throw _privateConstructorUsedError;
+  String? get password => throw _privateConstructorUsedError;
+  bool get isSubmitting => throw _privateConstructorUsedError;
+  Option<String> get passwordError => throw _privateConstructorUsedError;
+  Option<String> get emailError => throw _privateConstructorUsedError;
+  Option<Either<UserProfile, UserError>> get successOrFail =>
+      throw _privateConstructorUsedError;
+
+  @JsonKey(ignore: true)
+  $SignUpStateCopyWith<SignUpState> get copyWith =>
+      throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $SignUpStateCopyWith<$Res> {
+  factory $SignUpStateCopyWith(
+          SignUpState value, $Res Function(SignUpState) then) =
+      _$SignUpStateCopyWithImpl<$Res>;
+  $Res call(
+      {String? email,
+      String? password,
+      bool isSubmitting,
+      Option<String> passwordError,
+      Option<String> emailError,
+      Option<Either<UserProfile, UserError>> successOrFail});
+}
+
+/// @nodoc
+class _$SignUpStateCopyWithImpl<$Res> implements $SignUpStateCopyWith<$Res> {
+  _$SignUpStateCopyWithImpl(this._value, this._then);
+
+  final SignUpState _value;
+  // ignore: unused_field
+  final $Res Function(SignUpState) _then;
+
+  @override
+  $Res call({
+    Object? email = freezed,
+    Object? password = freezed,
+    Object? isSubmitting = freezed,
+    Object? passwordError = freezed,
+    Object? emailError = freezed,
+    Object? successOrFail = freezed,
+  }) {
+    return _then(_value.copyWith(
+      email: email == freezed
+          ? _value.email
+          : email // ignore: cast_nullable_to_non_nullable
+              as String?,
+      password: password == freezed
+          ? _value.password
+          : password // ignore: cast_nullable_to_non_nullable
+              as String?,
+      isSubmitting: isSubmitting == freezed
+          ? _value.isSubmitting
+          : isSubmitting // ignore: cast_nullable_to_non_nullable
+              as bool,
+      passwordError: passwordError == freezed
+          ? _value.passwordError
+          : passwordError // ignore: cast_nullable_to_non_nullable
+              as Option<String>,
+      emailError: emailError == freezed
+          ? _value.emailError
+          : emailError // ignore: cast_nullable_to_non_nullable
+              as Option<String>,
+      successOrFail: successOrFail == freezed
+          ? _value.successOrFail
+          : successOrFail // ignore: cast_nullable_to_non_nullable
+              as Option<Either<UserProfile, UserError>>,
+    ));
+  }
+}
+
+/// @nodoc
+abstract class _$SignUpStateCopyWith<$Res>
+    implements $SignUpStateCopyWith<$Res> {
+  factory _$SignUpStateCopyWith(
+          _SignUpState value, $Res Function(_SignUpState) then) =
+      __$SignUpStateCopyWithImpl<$Res>;
+  @override
+  $Res call(
+      {String? email,
+      String? password,
+      bool isSubmitting,
+      Option<String> passwordError,
+      Option<String> emailError,
+      Option<Either<UserProfile, UserError>> successOrFail});
+}
+
+/// @nodoc
+class __$SignUpStateCopyWithImpl<$Res> extends _$SignUpStateCopyWithImpl<$Res>
+    implements _$SignUpStateCopyWith<$Res> {
+  __$SignUpStateCopyWithImpl(
+      _SignUpState _value, $Res Function(_SignUpState) _then)
+      : super(_value, (v) => _then(v as _SignUpState));
+
+  @override
+  _SignUpState get _value => super._value as _SignUpState;
+
+  @override
+  $Res call({
+    Object? email = freezed,
+    Object? password = freezed,
+    Object? isSubmitting = freezed,
+    Object? passwordError = freezed,
+    Object? emailError = freezed,
+    Object? successOrFail = freezed,
+  }) {
+    return _then(_SignUpState(
+      email: email == freezed
+          ? _value.email
+          : email // ignore: cast_nullable_to_non_nullable
+              as String?,
+      password: password == freezed
+          ? _value.password
+          : password // ignore: cast_nullable_to_non_nullable
+              as String?,
+      isSubmitting: isSubmitting == freezed
+          ? _value.isSubmitting
+          : isSubmitting // ignore: cast_nullable_to_non_nullable
+              as bool,
+      passwordError: passwordError == freezed
+          ? _value.passwordError
+          : passwordError // ignore: cast_nullable_to_non_nullable
+              as Option<String>,
+      emailError: emailError == freezed
+          ? _value.emailError
+          : emailError // ignore: cast_nullable_to_non_nullable
+              as Option<String>,
+      successOrFail: successOrFail == freezed
+          ? _value.successOrFail
+          : successOrFail // ignore: cast_nullable_to_non_nullable
+              as Option<Either<UserProfile, UserError>>,
+    ));
+  }
+}
+
+/// @nodoc
+
+class _$_SignUpState implements _SignUpState {
+  const _$_SignUpState(
+      {this.email,
+      this.password,
+      required this.isSubmitting,
+      required this.passwordError,
+      required this.emailError,
+      required this.successOrFail});
+
+  @override
+  final String? email;
+  @override
+  final String? password;
+  @override
+  final bool isSubmitting;
+  @override
+  final Option<String> passwordError;
+  @override
+  final Option<String> emailError;
+  @override
+  final Option<Either<UserProfile, UserError>> successOrFail;
+
+  @override
+  String toString() {
+    return 'SignUpState(email: $email, password: $password, isSubmitting: $isSubmitting, passwordError: $passwordError, emailError: $emailError, successOrFail: $successOrFail)';
+  }
+
+  @override
+  bool operator ==(dynamic other) {
+    return identical(this, other) ||
+        (other is _SignUpState &&
+            (identical(other.email, email) ||
+                const DeepCollectionEquality().equals(other.email, email)) &&
+            (identical(other.password, password) ||
+                const DeepCollectionEquality()
+                    .equals(other.password, password)) &&
+            (identical(other.isSubmitting, isSubmitting) ||
+                const DeepCollectionEquality()
+                    .equals(other.isSubmitting, isSubmitting)) &&
+            (identical(other.passwordError, passwordError) ||
+                const DeepCollectionEquality()
+                    .equals(other.passwordError, passwordError)) &&
+            (identical(other.emailError, emailError) ||
+                const DeepCollectionEquality()
+                    .equals(other.emailError, emailError)) &&
+            (identical(other.successOrFail, successOrFail) ||
+                const DeepCollectionEquality()
+                    .equals(other.successOrFail, successOrFail)));
+  }
+
+  @override
+  int get hashCode =>
+      runtimeType.hashCode ^
+      const DeepCollectionEquality().hash(email) ^
+      const DeepCollectionEquality().hash(password) ^
+      const DeepCollectionEquality().hash(isSubmitting) ^
+      const DeepCollectionEquality().hash(passwordError) ^
+      const DeepCollectionEquality().hash(emailError) ^
+      const DeepCollectionEquality().hash(successOrFail);
+
+  @JsonKey(ignore: true)
+  @override
+  _$SignUpStateCopyWith<_SignUpState> get copyWith =>
+      __$SignUpStateCopyWithImpl<_SignUpState>(this, _$identity);
+}
+
+abstract class _SignUpState implements SignUpState {
+  const factory _SignUpState(
+          {String? email,
+          String? password,
+          required bool isSubmitting,
+          required Option<String> passwordError,
+          required Option<String> emailError,
+          required Option<Either<UserProfile, UserError>> successOrFail}) =
+      _$_SignUpState;
+
+  @override
+  String? get email => throw _privateConstructorUsedError;
+  @override
+  String? get password => throw _privateConstructorUsedError;
+  @override
+  bool get isSubmitting => throw _privateConstructorUsedError;
+  @override
+  Option<String> get passwordError => throw _privateConstructorUsedError;
+  @override
+  Option<String> get emailError => throw _privateConstructorUsedError;
+  @override
+  Option<Either<UserProfile, UserError>> get successOrFail =>
+      throw _privateConstructorUsedError;
+  @override
+  @JsonKey(ignore: true)
+  _$SignUpStateCopyWith<_SignUpState> get copyWith =>
+      throw _privateConstructorUsedError;
+}

+ 3 - 1
app_flowy/lib/user/infrastructure/deps_resolver.dart

@@ -1,4 +1,5 @@
-import 'package:app_flowy/user/application/sign_in/sign_in_bloc.dart';
+import 'package:app_flowy/user/application/sign_in_bloc.dart';
+import 'package:app_flowy/user/application/sign_up_bloc.dart';
 import 'package:app_flowy/user/domain/i_auth.dart';
 import 'package:app_flowy/user/domain/i_auth.dart';
 import 'package:app_flowy/user/infrastructure/repos/auth_repo.dart';
 import 'package:app_flowy/user/infrastructure/repos/auth_repo.dart';
 import 'package:app_flowy/user/infrastructure/i_auth_impl.dart';
 import 'package:app_flowy/user/infrastructure/i_auth_impl.dart';
@@ -14,5 +15,6 @@ class UserDepsResolver {
 
 
     //Bloc
     //Bloc
     getIt.registerFactory<SignInBloc>(() => SignInBloc(getIt<IAuth>()));
     getIt.registerFactory<SignInBloc>(() => SignInBloc(getIt<IAuth>()));
+    getIt.registerFactory<SignUpBloc>(() => SignUpBloc(getIt<IAuth>()));
   }
   }
 }
 }

+ 6 - 1
app_flowy/lib/user/infrastructure/i_auth_impl.dart

@@ -1,3 +1,4 @@
+import 'package:app_flowy/user/presentation/sign_up/sign_up_screen.dart';
 import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
 import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
 import 'package:app_flowy/workspace/presentation/workspace/workspace_select_screen.dart';
 import 'package:app_flowy/workspace/presentation/workspace/workspace_select_screen.dart';
 import 'package:dartz/dartz.dart';
 import 'package:dartz/dartz.dart';
@@ -50,6 +51,10 @@ class AuthRouterImpl extends IAuthRouter {
 
 
   @override
   @override
   void showSignUpScreen(BuildContext context) {
   void showSignUpScreen(BuildContext context) {
-    // TODO: implement showSignUpScreen
+    Navigator.of(context).push(
+      PageRoutes.fade(
+        () => const SignUpScreen(),
+      ),
+    );
   }
   }
 }
 }

+ 6 - 6
app_flowy/lib/user/presentation/sign_in/sign_in_screen.dart → app_flowy/lib/user/presentation/sign_in_screen.dart

@@ -1,5 +1,5 @@
 import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/startup/startup.dart';
-import 'package:app_flowy/user/application/sign_in/sign_in_bloc.dart';
+import 'package:app_flowy/user/application/sign_in_bloc.dart';
 import 'package:app_flowy/user/domain/i_auth.dart';
 import 'package:app_flowy/user/domain/i_auth.dart';
 import 'package:app_flowy/user/presentation/sign_in/widgets/background.dart';
 import 'package:app_flowy/user/presentation/sign_in/widgets/background.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra/theme.dart';
@@ -63,9 +63,9 @@ class SignInForm extends StatelessWidget {
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
     return Align(
     return Align(
       alignment: Alignment.center,
       alignment: Alignment.center,
-      child: SignInFormContainer(
+      child: AuthFormContainer(
         children: [
         children: [
-          const SignInTitle(
+          const AuthFormTitle(
             title: 'Login to Appflowy',
             title: 'Login to Appflowy',
             logoSize: Size(60, 60),
             logoSize: Size(60, 60),
           ),
           ),
@@ -128,7 +128,7 @@ class LoginButton extends StatelessWidget {
     final theme = context.watch<AppTheme>();
     final theme = context.watch<AppTheme>();
     return RoundedTextButton(
     return RoundedTextButton(
       title: 'Login',
       title: 'Login',
-      height: 45,
+      height: 48,
       borderRadius: BorderRadius.circular(10),
       borderRadius: BorderRadius.circular(10),
       color: theme.main1,
       color: theme.main1,
       press: () {
       press: () {
@@ -180,7 +180,7 @@ class PasswordTextField extends StatelessWidget {
           obscureText: true,
           obscureText: true,
           obscureIcon: svgWidgetWithName("home/Hide.svg"),
           obscureIcon: svgWidgetWithName("home/Hide.svg"),
           obscureHideIcon: svgWidgetWithName("home/Show.svg"),
           obscureHideIcon: svgWidgetWithName("home/Show.svg"),
-          hintText: 'password',
+          hintText: 'Password',
           normalBorderColor: theme.shader4,
           normalBorderColor: theme.shader4,
           highlightBorderColor: theme.red,
           highlightBorderColor: theme.red,
           errorText: context
           errorText: context
@@ -210,7 +210,7 @@ class EmailTextField extends StatelessWidget {
           previous.emailError != current.emailError,
           previous.emailError != current.emailError,
       builder: (context, state) {
       builder: (context, state) {
         return RoundedInputField(
         return RoundedInputField(
-          hintText: 'email',
+          hintText: 'Email',
           normalBorderColor: theme.shader4,
           normalBorderColor: theme.shader4,
           highlightBorderColor: theme.red,
           highlightBorderColor: theme.red,
           errorText: context
           errorText: context

+ 0 - 0
app_flowy/lib/user/presentation/sign_up/sign_up_screen.dart


+ 202 - 0
app_flowy/lib/user/presentation/sign_up_screen.dart

@@ -0,0 +1,202 @@
+import 'package:app_flowy/startup/startup.dart';
+import 'package:app_flowy/user/application/sign_up_bloc.dart';
+import 'package:app_flowy/user/presentation/widgets/background.dart';
+import 'package:flowy_infra/theme.dart';
+import 'package:flowy_infra_ui/widget/rounded_button.dart';
+import 'package:flowy_infra_ui/widget/rounded_input_field.dart';
+import 'package:flowy_infra_ui/widget/spacing.dart';
+import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:dartz/dartz.dart';
+import 'package:flowy_infra/image.dart';
+
+class SignUpScreen extends StatelessWidget {
+  const SignUpScreen({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocProvider(
+      create: (context) => getIt<SignUpBloc>(),
+      child: BlocListener<SignUpBloc, SignUpState>(
+        listener: (context, state) {
+          state.successOrFail.fold(
+            () => null,
+            (result) => _handleSuccessOrFail(result, context),
+          );
+        },
+        child: const Scaffold(
+          body: SignUpForm(),
+        ),
+      ),
+    );
+  }
+
+  void _handleSuccessOrFail(
+      Either<UserProfile, UserError> result, BuildContext context) {
+    result.fold(
+      (user) => {
+        // router.showWorkspaceSelectScreen(context, user)
+      },
+      (error) => _showErrorMessage(context, error.msg),
+    );
+  }
+
+  void _showErrorMessage(BuildContext context, String msg) {
+    ScaffoldMessenger.of(context).showSnackBar(
+      SnackBar(
+        content: Text(msg),
+      ),
+    );
+  }
+}
+
+class SignUpForm extends StatelessWidget {
+  const SignUpForm({
+    Key? key,
+  }) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Align(
+      alignment: Alignment.center,
+      child: AuthFormContainer(
+        children: [
+          const AuthFormTitle(
+            title: 'Sign Up to Appflowy',
+            logoSize: Size(60, 60),
+          ),
+          const VSpace(30),
+          const EmailTextField(),
+          const PasswordTextField(),
+          const PasswordTextField(hintText: "Repeate password"),
+          const VSpace(30),
+          const SignUpButton(),
+          const VSpace(10),
+          const SignUpPrompt(),
+          if (context.read<SignUpBloc>().state.isSubmitting) ...[
+            const SizedBox(height: 8),
+            const LinearProgressIndicator(value: null),
+          ]
+        ],
+      ),
+    );
+  }
+}
+
+class SignUpPrompt extends StatelessWidget {
+  const SignUpPrompt({
+    Key? key,
+  }) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    final theme = context.watch<AppTheme>();
+    return Row(
+      children: [
+        Text("Already have an account",
+            style: TextStyle(color: theme.shader3, fontSize: 12)),
+        TextButton(
+          style: TextButton.styleFrom(
+            textStyle: const TextStyle(fontSize: 12),
+          ),
+          onPressed: () => Navigator.pop(context),
+          child: Text(
+            'Sign In',
+            style: TextStyle(color: theme.main1),
+          ),
+        ),
+      ],
+      mainAxisAlignment: MainAxisAlignment.center,
+    );
+  }
+}
+
+class SignUpButton extends StatelessWidget {
+  const SignUpButton({
+    Key? key,
+  }) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    final theme = context.watch<AppTheme>();
+    return RoundedTextButton(
+      title: 'Get Started',
+      height: 48,
+      borderRadius: BorderRadius.circular(10),
+      color: theme.main1,
+      press: () {
+        context
+            .read<SignUpBloc>()
+            .add(const SignUpEvent.signUpWithUserEmailAndPassword());
+      },
+    );
+  }
+}
+
+class PasswordTextField extends StatelessWidget {
+  final String hintText;
+  const PasswordTextField({
+    Key? key,
+    this.hintText = "Password",
+  }) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    final theme = context.watch<AppTheme>();
+    return BlocBuilder<SignUpBloc, SignUpState>(
+      buildWhen: (previous, current) =>
+          previous.passwordError != current.passwordError,
+      builder: (context, state) {
+        return RoundedInputField(
+          obscureText: true,
+          obscureIcon: svgWidgetWithName("home/Hide.svg"),
+          obscureHideIcon: svgWidgetWithName("home/Show.svg"),
+          fontSize: 14,
+          fontWeight: FontWeight.w500,
+          hintText: hintText,
+          normalBorderColor: theme.shader4,
+          highlightBorderColor: theme.red,
+          errorText: context
+              .read<SignUpBloc>()
+              .state
+              .passwordError
+              .fold(() => "", (error) => error),
+          onChanged: (value) => context
+              .read<SignUpBloc>()
+              .add(SignUpEvent.passwordChanged(value)),
+        );
+      },
+    );
+  }
+}
+
+class EmailTextField extends StatelessWidget {
+  const EmailTextField({
+    Key? key,
+  }) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    final theme = context.watch<AppTheme>();
+    return BlocBuilder<SignUpBloc, SignUpState>(
+      buildWhen: (previous, current) =>
+          previous.emailError != current.emailError,
+      builder: (context, state) {
+        return RoundedInputField(
+          hintText: 'Email',
+          normalBorderColor: theme.shader4,
+          highlightBorderColor: theme.red,
+          errorText: context
+              .read<SignUpBloc>()
+              .state
+              .emailError
+              .fold(() => "", (error) => error),
+          onChanged: (value) =>
+              context.read<SignUpBloc>().add(SignUpEvent.emailChanged(value)),
+        );
+      },
+    );
+  }
+}

+ 11 - 6
app_flowy/lib/user/presentation/sign_in/widgets/background.dart → app_flowy/lib/user/presentation/widgets/background.dart

@@ -1,12 +1,14 @@
+import 'dart:math';
+
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
 import 'package:provider/provider.dart';
 
 
-class SignInFormContainer extends StatelessWidget {
+class AuthFormContainer extends StatelessWidget {
   final List<Widget> children;
   final List<Widget> children;
-  const SignInFormContainer({
+  const AuthFormContainer({
     Key? key,
     Key? key,
     required this.children,
     required this.children,
   }) : super(key: key);
   }) : super(key: key);
@@ -15,7 +17,7 @@ class SignInFormContainer extends StatelessWidget {
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
     final size = MediaQuery.of(context).size;
     final size = MediaQuery.of(context).size;
     return SizedBox(
     return SizedBox(
-      width: size.width * 0.3,
+      width: min(size.width, 340),
       child: Column(
       child: Column(
         mainAxisAlignment: MainAxisAlignment.center,
         mainAxisAlignment: MainAxisAlignment.center,
         children: children,
         children: children,
@@ -24,10 +26,10 @@ class SignInFormContainer extends StatelessWidget {
   }
   }
 }
 }
 
 
-class SignInTitle extends StatelessWidget {
+class AuthFormTitle extends StatelessWidget {
   final String title;
   final String title;
   final Size logoSize;
   final Size logoSize;
-  const SignInTitle({
+  const AuthFormTitle({
     Key? key,
     Key? key,
     required this.title,
     required this.title,
     required this.logoSize,
     required this.logoSize,
@@ -40,7 +42,10 @@ class SignInTitle extends StatelessWidget {
       child: Column(
       child: Column(
         mainAxisAlignment: MainAxisAlignment.center,
         mainAxisAlignment: MainAxisAlignment.center,
         children: [
         children: [
-          svgWidgetWithName("small_logo.svg"),
+          SizedBox.fromSize(
+            size: const Size.square(40),
+            child: svgWidgetWithName("flowy_logo.svg"),
+          ),
           const VSpace(30),
           const VSpace(30),
           Text(
           Text(
             title,
             title,

+ 7 - 42
app_flowy/packages/flowy_infra/lib/theme.dart

@@ -12,19 +12,6 @@ class AppTheme {
 
 
   bool isDark;
   bool isDark;
   late Color surface; //
   late Color surface; //
-  late Color accent1;
-  late Color accent1Dark;
-  late Color accent1Darker;
-  late Color accent2;
-  late Color accent3;
-  late Color grey;
-  late Color greyStrong;
-  late Color greyWeak;
-  late Color error;
-  late Color focus;
-  late Color txt;
-  late Color accentTxt;
-
   late Color hover;
   late Color hover;
   late Color selector;
   late Color selector;
   late Color red;
   late Color red;
@@ -58,10 +45,7 @@ class AppTheme {
   late Color main2;
   late Color main2;
 
 
   /// Default constructor
   /// Default constructor
-  AppTheme({this.isDark = true}) {
-    txt = isDark ? Colors.white : Colors.black;
-    accentTxt = isDark ? Colors.black : Colors.white;
-  }
+  AppTheme({this.isDark = true});
 
 
   /// fromType factory constructor
   /// fromType factory constructor
   factory AppTheme.fromType(ThemeType t) {
   factory AppTheme.fromType(ThemeType t) {
@@ -69,16 +53,6 @@ class AppTheme {
       case ThemeType.light:
       case ThemeType.light:
         return AppTheme(isDark: false)
         return AppTheme(isDark: false)
           ..surface = Colors.white
           ..surface = Colors.white
-          ..accent1 = const Color(0xff00a086)
-          ..accent1Dark = const Color(0xff00856f)
-          ..accent1Darker = const Color(0xff006b5a)
-          ..accent2 = const Color(0xfff09433)
-          ..accent3 = const Color(0xff5bc91a)
-          ..greyWeak = const Color(0xff909f9c)
-          ..grey = const Color(0xff515d5a)
-          ..greyStrong = const Color(0xff151918)
-          ..error = Colors.red.shade900
-          ..focus = const Color(0xFFe0f8ff)
           ..hover = const Color(0xFFe0f8ff) //
           ..hover = const Color(0xFFe0f8ff) //
           ..selector = const Color(0xfff2fcff)
           ..selector = const Color(0xfff2fcff)
           ..red = const Color(0xfffb006d)
           ..red = const Color(0xfffb006d)
@@ -109,19 +83,7 @@ class AppTheme {
 
 
       case ThemeType.dark:
       case ThemeType.dark:
         return AppTheme(isDark: true)
         return AppTheme(isDark: true)
-          ..bg1 = const Color(0xff121212)
-          ..bg2 = const Color(0xff2c2c2c)
           ..surface = const Color(0xff252525)
           ..surface = const Color(0xff252525)
-          ..accent1 = const Color(0xff00a086)
-          ..accent1Dark = const Color(0xff00caa5)
-          ..accent1Darker = const Color(0xff00caa5)
-          ..accent2 = const Color(0xfff19e46)
-          ..accent3 = const Color(0xff5BC91A)
-          ..greyWeak = const Color(0xffa8b3b0)
-          ..grey = const Color(0xffced4d3)
-          ..greyStrong = const Color(0xffffffff)
-          ..error = const Color(0xffe55642)
-          ..focus = const Color(0xff0ee2b1)
           ..hover = const Color(0xFFe0f8ff) //
           ..hover = const Color(0xFFe0f8ff) //
           ..selector = const Color(0xfff2fcff)
           ..selector = const Color(0xfff2fcff)
           ..red = const Color(0xfffb006d)
           ..red = const Color(0xfffb006d)
@@ -153,8 +115,9 @@ class AppTheme {
   }
   }
 
 
   ThemeData get themeData {
   ThemeData get themeData {
-    var t = ThemeData.from(
+    var t = ThemeData(
       textTheme: (isDark ? ThemeData.dark() : ThemeData.light()).textTheme,
       textTheme: (isDark ? ThemeData.dark() : ThemeData.light()).textTheme,
+      textSelectionTheme: TextSelectionThemeData(cursorColor: main1),
       colorScheme: ColorScheme(
       colorScheme: ColorScheme(
           brightness: isDark ? Brightness.dark : Brightness.light,
           brightness: isDark ? Brightness.dark : Brightness.light,
           primary: main1,
           primary: main1,
@@ -164,15 +127,17 @@ class AppTheme {
           background: bg1,
           background: bg1,
           surface: surface,
           surface: surface,
           onBackground: bg1,
           onBackground: bg1,
-          onSurface: txt,
+          onSurface: surface,
           onError: red,
           onError: red,
           onPrimary: bg1,
           onPrimary: bg1,
           onSecondary: bg1,
           onSecondary: bg1,
-          error: error),
+          error: red),
     );
     );
+
     return t.copyWith(
     return t.copyWith(
         materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
         materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
         highlightColor: main1,
         highlightColor: main1,
+        indicatorColor: main1,
         toggleableActiveColor: main1);
         toggleableActiveColor: main1);
   }
   }
 
 

+ 27 - 4
app_flowy/packages/flowy_infra_ui/lib/widget/rounded_input_field.dart

@@ -1,7 +1,9 @@
+import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/widget/rounded_button.dart';
 import 'package:flowy_infra_ui/widget/rounded_button.dart';
 import 'package:flowy_infra_ui/widget/text_field_container.dart';
 import 'package:flowy_infra_ui/widget/text_field_container.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:flowy_infra/time/duration.dart';
 import 'package:flowy_infra/time/duration.dart';
+import 'package:provider/provider.dart';
 
 
 // ignore: must_be_immutable
 // ignore: must_be_immutable
 class RoundedInputField extends StatefulWidget {
 class RoundedInputField extends StatefulWidget {
@@ -10,11 +12,14 @@ class RoundedInputField extends StatefulWidget {
   final bool obscureText;
   final bool obscureText;
   final Widget? obscureIcon;
   final Widget? obscureIcon;
   final Widget? obscureHideIcon;
   final Widget? obscureHideIcon;
+  final FontWeight? fontWeight;
+  final double? fontSize;
   final Color normalBorderColor;
   final Color normalBorderColor;
   final Color highlightBorderColor;
   final Color highlightBorderColor;
   final String errorText;
   final String errorText;
   final ValueChanged<String>? onChanged;
   final ValueChanged<String>? onChanged;
   late bool enableObscure;
   late bool enableObscure;
+  var _text = "";
 
 
   RoundedInputField({
   RoundedInputField({
     Key? key,
     Key? key,
@@ -26,6 +31,8 @@ class RoundedInputField extends StatefulWidget {
     this.onChanged,
     this.onChanged,
     this.normalBorderColor = Colors.transparent,
     this.normalBorderColor = Colors.transparent,
     this.highlightBorderColor = Colors.transparent,
     this.highlightBorderColor = Colors.transparent,
+    this.fontWeight = FontWeight.normal,
+    this.fontSize = 20,
     this.errorText = "",
     this.errorText = "",
   }) : super(key: key) {
   }) : super(key: key) {
     enableObscure = obscureText;
     enableObscure = obscureText;
@@ -38,6 +45,7 @@ class RoundedInputField extends StatefulWidget {
 class _RoundedInputFieldState extends State<RoundedInputField> {
 class _RoundedInputFieldState extends State<RoundedInputField> {
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
+    final theme = context.watch<AppTheme>();
     final Icon? newIcon = widget.icon == null
     final Icon? newIcon = widget.icon == null
         ? null
         ? null
         : Icon(
         : Icon(
@@ -52,15 +60,23 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
 
 
     List<Widget> children = [
     List<Widget> children = [
       TextFieldContainer(
       TextFieldContainer(
+        height: 48,
         borderRadius: BorderRadius.circular(10),
         borderRadius: BorderRadius.circular(10),
         borderColor: borderColor,
         borderColor: borderColor,
         child: TextFormField(
         child: TextFormField(
-          onChanged: widget.onChanged,
-          cursorColor: const Color(0xFF6F35A5),
+          onChanged: (value) {
+            widget._text = value;
+            if (widget.onChanged != null) {
+              widget.onChanged!(value);
+            }
+            setState(() {});
+          },
+          cursorColor: theme.main1,
           obscureText: widget.enableObscure,
           obscureText: widget.enableObscure,
           decoration: InputDecoration(
           decoration: InputDecoration(
             icon: newIcon,
             icon: newIcon,
             hintText: widget.hintText,
             hintText: widget.hintText,
+            hintStyle: TextStyle(color: widget.normalBorderColor),
             border: InputBorder.none,
             border: InputBorder.none,
             suffixIcon: suffixIcon(),
             suffixIcon: suffixIcon(),
           ),
           ),
@@ -71,7 +87,10 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
     if (widget.errorText.isNotEmpty) {
     if (widget.errorText.isNotEmpty) {
       children.add(Text(
       children.add(Text(
         widget.errorText,
         widget.errorText,
-        style: TextStyle(color: widget.highlightBorderColor),
+        style: TextStyle(
+            color: widget.highlightBorderColor,
+            fontWeight: widget.fontWeight,
+            fontSize: widget.fontSize),
       ));
       ));
     }
     }
 
 
@@ -89,6 +108,10 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
       return null;
       return null;
     }
     }
 
 
+    if (widget._text.isEmpty) {
+      return SizedBox.fromSize(size: const Size.square(16));
+    }
+
     Widget? icon;
     Widget? icon;
     if (widget.obscureText == true) {
     if (widget.obscureText == true) {
       assert(widget.obscureIcon != null && widget.obscureHideIcon != null);
       assert(widget.obscureIcon != null && widget.obscureHideIcon != null);
@@ -104,7 +127,7 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
     }
     }
 
 
     return RoundedImageButton(
     return RoundedImageButton(
-      size: 20,
+      size: 16,
       press: () {
       press: () {
         widget.enableObscure = !widget.enableObscure;
         widget.enableObscure = !widget.enableObscure;
         setState(() {});
         setState(() {});