feat: Refactor code structure and optimize performance across multiple modules
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
import 'package:auto_route/annotations.dart';
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:krow/core/presentation/styles/kw_text_styles.dart';
|
||||
import 'package:krow/core/presentation/styles/theme.dart';
|
||||
import 'package:krow/core/presentation/widgets/scroll_layout_helper.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_app_bar.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_button.dart';
|
||||
import 'package:krow/features/sign_in/domain/bloc/sign_in_bloc.dart';
|
||||
import 'package:krow/features/sign_in/presentation/reset_pass_screen/widgets/enter_new_pass_form.dart';
|
||||
import 'package:krow/features/sign_in/presentation/reset_pass_screen/widgets/reset_success_form.dart';
|
||||
|
||||
@RoutePage()
|
||||
class EnterNewPassScreen extends StatefulWidget {
|
||||
final String? code;
|
||||
|
||||
const EnterNewPassScreen({super.key, @QueryParam('oobCode') this.code});
|
||||
|
||||
@override
|
||||
State<EnterNewPassScreen> createState() => _EnterNewPassScreenState();
|
||||
}
|
||||
|
||||
class _EnterNewPassScreenState extends State<EnterNewPassScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
context
|
||||
.read<SignInBloc>()
|
||||
.add(SignInEventOnResetVerified(widget.code ?? ''));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: KwAppBar(),
|
||||
body: BlocBuilder<SignInBloc, SignInState>(
|
||||
builder: (context, state) {
|
||||
var form = _getForm(state);
|
||||
|
||||
return ScrollLayoutHelper(
|
||||
upperWidget: form,
|
||||
lowerWidget: Column(
|
||||
children: [
|
||||
KwButton.primary(
|
||||
label: _buttonText(state),
|
||||
onPressed: () {
|
||||
context.read<SignInBloc>().add(ResetPassNextStepEvent());
|
||||
},
|
||||
),
|
||||
const Gap(36),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
text: 'Remember your password? ',
|
||||
style: AppTextStyles.bodyMediumReg
|
||||
.copyWith(color: AppColors.blackGray),
|
||||
children: [
|
||||
TextSpan(
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
Navigator.maybePop(context);
|
||||
},
|
||||
text: 'Log In',
|
||||
style: AppTextStyles.bodyMediumSmb,
|
||||
),
|
||||
],
|
||||
)),
|
||||
const Gap(36),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _buttonText(SignInState state) {
|
||||
switch (state.resetPassStep) {
|
||||
case ResetPassStep.password:
|
||||
return 'Save New Password';
|
||||
case ResetPassStep.success:
|
||||
return 'Go to Login';
|
||||
default:
|
||||
return 'Next';
|
||||
}
|
||||
}
|
||||
|
||||
_getForm(SignInState state) {
|
||||
if (state.resetPassStep == ResetPassStep.success) {
|
||||
return const ResetSuccessForm();
|
||||
} else {
|
||||
return EnterNewPassForm(obscurePassword: state.obscurePassword);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:krow/core/application/routing/routes.gr.dart';
|
||||
import 'package:krow/core/presentation/styles/kw_text_styles.dart';
|
||||
import 'package:krow/core/presentation/styles/theme.dart';
|
||||
import 'package:krow/core/presentation/widgets/scroll_layout_helper.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_app_bar.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_button.dart';
|
||||
import 'package:krow/features/sign_in/domain/bloc/sign_in_bloc.dart';
|
||||
import 'package:krow/features/sign_in/presentation/reset_pass_screen/widgets/reset_email_form.dart';
|
||||
import 'package:krow/features/sign_in/presentation/reset_pass_screen/widgets/waiting_email_link_form.dart';
|
||||
|
||||
@RoutePage()
|
||||
class ResetPassScreen extends StatelessWidget {
|
||||
const ResetPassScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: KwAppBar(),
|
||||
body: BlocConsumer<SignInBloc, SignInState>(
|
||||
listener: (context, state) {
|
||||
if (state.resetPassStep == ResetPassStep.password) {
|
||||
context.router.replace(EnterNewPassRoute());
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
var form = _getForm(state);
|
||||
return ScrollLayoutHelper(
|
||||
upperWidget: form,
|
||||
lowerWidget: Column(
|
||||
children: [
|
||||
KwButton.primary(
|
||||
disabled: state.resetPassStep != ResetPassStep.email,
|
||||
label: _buttonText(state),
|
||||
onPressed: () {
|
||||
if (state.resetPassStep == ResetPassStep.email) {
|
||||
context.read<SignInBloc>().add(ResetPassNextStepEvent());
|
||||
}
|
||||
},
|
||||
),
|
||||
const Gap(36),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
text: 'Remember your password? ',
|
||||
style: AppTextStyles.bodyMediumReg
|
||||
.copyWith(color: AppColors.blackGray),
|
||||
children: [
|
||||
TextSpan(
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
Navigator.maybePop(context);
|
||||
},
|
||||
text: 'Log In',
|
||||
style: AppTextStyles.bodyMediumSmb,
|
||||
),
|
||||
],
|
||||
)),
|
||||
const Gap(36),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _buttonText(SignInState state) {
|
||||
switch (state.resetPassStep) {
|
||||
case ResetPassStep.email:
|
||||
return 'Send Reset Link';
|
||||
case ResetPassStep.link:
|
||||
return 'Continue';
|
||||
default:
|
||||
return 'Next';
|
||||
}
|
||||
}
|
||||
|
||||
_getForm(SignInState state) {
|
||||
switch (state.resetPassStep) {
|
||||
case ResetPassStep.email:
|
||||
return const ResetEmailForm();
|
||||
case ResetPassStep.link:
|
||||
return WaitingEmailLinkForm(email: state.email);
|
||||
default:
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:krow/core/presentation/gen/assets.gen.dart';
|
||||
import 'package:krow/core/presentation/styles/kw_text_styles.dart';
|
||||
import 'package:krow/core/presentation/styles/theme.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_input.dart';
|
||||
import 'package:krow/features/sign_in/domain/bloc/sign_in_bloc.dart';
|
||||
|
||||
class EnterNewPassForm extends StatelessWidget {
|
||||
final bool obscurePassword;
|
||||
|
||||
const EnterNewPassForm({super.key, required this.obscurePassword});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Gap(36),
|
||||
const Text(
|
||||
'Reset Your Password',
|
||||
style: AppTextStyles.headingH1,
|
||||
),
|
||||
const Gap(8),
|
||||
Text(
|
||||
'Create a new password for your account',
|
||||
style:
|
||||
AppTextStyles.bodyMediumReg.copyWith(color: AppColors.blackGray),
|
||||
),
|
||||
const Gap(24),
|
||||
KwTextInput(
|
||||
title: 'New Password',
|
||||
hintText: 'Enter password here',
|
||||
obscureText: obscurePassword,
|
||||
maxLines: 1,
|
||||
suffixIcon: GestureDetector(
|
||||
onTap: () {
|
||||
BlocProvider.of<SignInBloc>(context)
|
||||
.add(SwitchObscurePasswordEvent());
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 16),
|
||||
child: obscurePassword
|
||||
? Assets.images.icons.eyeOff.svg()
|
||||
: Assets.images.icons.eye.svg(),
|
||||
),
|
||||
),
|
||||
controller: TextEditingController()),
|
||||
const Gap(8),
|
||||
KwTextInput(
|
||||
title: 'Confirm Password',
|
||||
hintText: 'Enter password here',
|
||||
maxLines: 1,
|
||||
obscureText: obscurePassword,
|
||||
suffixIcon: GestureDetector(
|
||||
onTap: () {
|
||||
BlocProvider.of<SignInBloc>(context)
|
||||
.add(SwitchObscurePasswordEvent());
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 16),
|
||||
child: obscurePassword
|
||||
? Assets.images.icons.eyeOff.svg()
|
||||
: Assets.images.icons.eye.svg(),
|
||||
),
|
||||
),
|
||||
controller: TextEditingController()),
|
||||
const Gap(24),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:krow/core/presentation/styles/kw_text_styles.dart';
|
||||
import 'package:krow/core/presentation/styles/theme.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_input.dart';
|
||||
import 'package:krow/features/sign_in/domain/bloc/sign_in_bloc.dart';
|
||||
|
||||
class ResetEmailForm extends StatefulWidget {
|
||||
const ResetEmailForm({super.key});
|
||||
|
||||
@override
|
||||
State<ResetEmailForm> createState() => _ResetEmailFormState();
|
||||
}
|
||||
|
||||
class _ResetEmailFormState extends State<ResetEmailForm> {
|
||||
var textEditingController = TextEditingController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Gap(36),
|
||||
const Text(
|
||||
'Forgot Password?',
|
||||
style: AppTextStyles.headingH1,
|
||||
),
|
||||
const Gap(8),
|
||||
Text(
|
||||
'Enter the email address associated with your account',
|
||||
style:
|
||||
AppTextStyles.bodyMediumReg.copyWith(color: AppColors.blackGray),
|
||||
),
|
||||
const Gap(24),
|
||||
BlocBuilder<SignInBloc, SignInState>(
|
||||
builder: (context, state) {
|
||||
return KwTextInput(
|
||||
title: 'Email',
|
||||
hintText: 'Enter your email',
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
onChanged: (str) {
|
||||
context.read<SignInBloc>().add(SignInEventEmailChanged(str));
|
||||
},
|
||||
helperText: state.inputValidationError,
|
||||
showError: state.inputValidationError.isNotEmpty,
|
||||
controller: textEditingController);
|
||||
},
|
||||
),
|
||||
const Gap(24),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:krow/core/presentation/styles/kw_text_styles.dart';
|
||||
import 'package:krow/core/presentation/styles/theme.dart';
|
||||
|
||||
class ResetSuccessForm extends StatelessWidget {
|
||||
const ResetSuccessForm({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Gap(36),
|
||||
const Text(
|
||||
'Password Reset Successful!',
|
||||
style: AppTextStyles.headingH1,
|
||||
),
|
||||
const Gap(8),
|
||||
Text(
|
||||
'Your password has been updated. You can now log in with your new password',
|
||||
style:
|
||||
AppTextStyles.bodyMediumReg.copyWith(color: AppColors.blackGray),
|
||||
),
|
||||
const Gap(24),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:krow/core/presentation/styles/kw_text_styles.dart';
|
||||
import 'package:krow/core/presentation/styles/theme.dart';
|
||||
|
||||
class WaitingEmailLinkForm extends StatelessWidget {
|
||||
final String email;
|
||||
|
||||
const WaitingEmailLinkForm({super.key, required this.email});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Gap(36),
|
||||
const Text(
|
||||
'Check Your Email',
|
||||
style: AppTextStyles.headingH1,
|
||||
),
|
||||
const Gap(8),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
text: 'We\'ve sent a password reset link to ',
|
||||
style: AppTextStyles.bodyMediumReg
|
||||
.copyWith(color: AppColors.blackGray),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: email,
|
||||
style: AppTextStyles.bodyMediumMed,
|
||||
),
|
||||
TextSpan(
|
||||
text:
|
||||
'. Please check your inbox and follow the instructions to reset your password',
|
||||
style: AppTextStyles.bodyMediumReg
|
||||
.copyWith(color: AppColors.blackGray),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
//на око
|
||||
top: (MediaQuery.of(context).size.height - 520) / 2), //на око
|
||||
child: RichText(
|
||||
textAlign: TextAlign.center,
|
||||
text: TextSpan(
|
||||
text: 'Didn\'t receive the email?\n',
|
||||
style: AppTextStyles.bodyMediumReg
|
||||
.copyWith(color: AppColors.blackGray),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: 'Resend',
|
||||
style: AppTextStyles.bodyMediumSmb
|
||||
.copyWith(color: AppColors.primaryBlue),
|
||||
recognizer: TapGestureRecognizer()..onTap = () {},
|
||||
),
|
||||
TextSpan(
|
||||
text: ' or ',
|
||||
style: AppTextStyles.bodyMediumReg
|
||||
.copyWith(color: AppColors.blackGray),
|
||||
),
|
||||
TextSpan(
|
||||
text: 'Contact Support',
|
||||
style: AppTextStyles.bodyMediumSmb
|
||||
.copyWith(color: AppColors.primaryBlue),
|
||||
recognizer: TapGestureRecognizer()..onTap = () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:krow/features/sign_in/domain/bloc/sign_in_bloc.dart';
|
||||
|
||||
@RoutePage()
|
||||
class SignInFlowScreen extends StatelessWidget {
|
||||
const SignInFlowScreen({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (_) => SignInBloc(),
|
||||
child: const AutoRouter(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:krow/core/application/routing/routes.gr.dart';
|
||||
import 'package:krow/core/presentation/gen/assets.gen.dart';
|
||||
import 'package:krow/core/presentation/styles/kw_text_styles.dart';
|
||||
import 'package:krow/core/presentation/styles/theme.dart';
|
||||
import 'package:krow/core/presentation/widgets/scroll_layout_helper.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_app_bar.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_button.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_input.dart';
|
||||
import 'package:krow/features/sign_in/domain/bloc/sign_in_bloc.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
|
||||
@RoutePage()
|
||||
class SignInScreen extends StatefulWidget {
|
||||
const SignInScreen({super.key});
|
||||
|
||||
@override
|
||||
State<SignInScreen> createState() => _SignInScreenState();
|
||||
}
|
||||
|
||||
class _SignInScreenState extends State<SignInScreen> {
|
||||
final emailController = TextEditingController();
|
||||
final passController = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: KwAppBar(),
|
||||
body: BlocConsumer<SignInBloc, SignInState>(
|
||||
listener: (context, state) {
|
||||
if (state.authSuccess) {
|
||||
context.router.replace(const SplashRoute());
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
return ModalProgressHUD(
|
||||
inAsyncCall: state.inLoading,
|
||||
child: ScrollLayoutHelper(
|
||||
upperWidget: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Gap(36),
|
||||
const Text(
|
||||
'Welcome Back!',
|
||||
style: AppTextStyles.headingH1,
|
||||
),
|
||||
const Gap(8),
|
||||
Text(
|
||||
'Log in to find work opportunities that match your skills',
|
||||
style: AppTextStyles.bodyMediumReg
|
||||
.copyWith(color: AppColors.blackGray),
|
||||
),
|
||||
const Gap(24),
|
||||
KwTextInput(
|
||||
title: 'Email',
|
||||
hintText: 'Enter your email',
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
helperText: state.emailValidationError,
|
||||
showError: state.emailValidationError.isNotEmpty,
|
||||
onChanged: (_) {
|
||||
BlocProvider.of<SignInBloc>(context)
|
||||
.add(SignInEventEmailChanged(emailController.text));
|
||||
},
|
||||
controller: emailController),
|
||||
const Gap(8),
|
||||
KwTextInput(
|
||||
title: 'Password',
|
||||
hintText: 'Enter password here',
|
||||
obscureText: state.obscurePassword,
|
||||
keyboardType: TextInputType.visiblePassword,
|
||||
helperText: state.passValidationError,
|
||||
showError: state.passValidationError.isNotEmpty,
|
||||
maxLines: 1,
|
||||
onChanged: (_) {
|
||||
BlocProvider.of<SignInBloc>(context)
|
||||
.add(SignInEventPassChanged());
|
||||
},
|
||||
suffixIcon: GestureDetector(
|
||||
onTap: () {
|
||||
BlocProvider.of<SignInBloc>(context)
|
||||
.add(SwitchObscurePasswordEvent());
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 16),
|
||||
child: state.obscurePassword
|
||||
? Assets.images.icons.eyeOff.svg()
|
||||
: Assets.images.icons.eye.svg(),
|
||||
),
|
||||
),
|
||||
controller: passController),
|
||||
// GestureDetector(
|
||||
// onTap: () async {
|
||||
// await context.router.push(const ResetPassRoute());
|
||||
// BlocProvider.of<SignInBloc>(context)
|
||||
// .add(ResetPassBackEvent());
|
||||
// },
|
||||
// child: const Padding(
|
||||
// padding: EdgeInsets.only(left: 16, top: 12),
|
||||
// child: Text(
|
||||
// 'Forgot password',
|
||||
// style: AppTextStyles.bodyTinyMed,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
const Gap(24),
|
||||
],
|
||||
),
|
||||
lowerWidget: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 36),
|
||||
child: KwButton.primary(
|
||||
disabled:
|
||||
emailController.text.isEmpty || passController.text.isEmpty,
|
||||
label: 'Continue',
|
||||
onPressed: () {
|
||||
BlocProvider.of<SignInBloc>(context).add(SignInEventSignIn(
|
||||
passController.text,
|
||||
));
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:krow/core/application/routing/routes.gr.dart';
|
||||
import 'package:krow/core/presentation/gen/assets.gen.dart';
|
||||
import 'package:krow/core/presentation/styles/kw_text_styles.dart';
|
||||
import 'package:krow/core/presentation/styles/theme.dart';
|
||||
import 'package:krow/core/presentation/widgets/ui_kit/kw_button.dart';
|
||||
|
||||
@RoutePage()
|
||||
class WelcomeScreen extends StatelessWidget {
|
||||
const WelcomeScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
type: MaterialType.transparency,
|
||||
child: Stack(fit: StackFit.expand, children: [
|
||||
_background(context),
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: ClipPath(
|
||||
clipper: ArcClipper(),
|
||||
child: Container(
|
||||
clipBehavior: Clip.none,
|
||||
height: MediaQuery.of(context).size.height - 280,
|
||||
decoration: const BoxDecoration(
|
||||
//unnamed color from figma for this shape
|
||||
color: Color(0xFF2246EA),
|
||||
),
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: Assets.images.bgPattern.svg(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
alignment: Alignment.bottomCenter,
|
||||
fit: BoxFit.fitWidth,
|
||||
colorFilter: const ColorFilter.mode(
|
||||
//unnamed color from figma for this image
|
||||
Color(0xFF2D50EB),
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
children: [
|
||||
Assets.images.logo.svg(),
|
||||
const Gap(10),
|
||||
Flexible(child: Assets.images.welcome.image()),
|
||||
const Gap(24),
|
||||
Text(
|
||||
'Take Control of Your Shifts and Events',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppTextStyles.headingH1.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
const Gap(8),
|
||||
Text(
|
||||
'Streamline your operations with powerful tools to manage schedules, track performance, and keep your team on the same page—all in one place',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppTextStyles.bodyMediumReg.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
const Gap(24),
|
||||
KwButton.accent(
|
||||
label: 'Sign In',
|
||||
onPressed: () {
|
||||
context.router.push(const SignInRoute());
|
||||
}),
|
||||
// const Gap(12),
|
||||
// KwButton.outlinedAccent(
|
||||
// leftIcon: Assets.images.signInApple,
|
||||
// label: 'Sign In with Apple',
|
||||
// onPressed: () {},
|
||||
// ),
|
||||
// const Gap(12),
|
||||
// KwButton.outlinedAccent(
|
||||
// leftIcon: Assets.images.signInGoogle,
|
||||
// label: 'Sign In with Google',
|
||||
// onPressed: () {})
|
||||
// .copyWith(originalIconsColors: true),
|
||||
const Gap(32),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
Container _background(BuildContext context) {
|
||||
return Container(
|
||||
alignment: Alignment.topCenter,
|
||||
height: MediaQuery.of(context).size.height,
|
||||
color: AppColors.primaryBlue,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ArcClipper extends CustomClipper<Path> {
|
||||
@override
|
||||
Path getClip(Size size) {
|
||||
final path = Path();
|
||||
path.lineTo(0, size.height - 120);
|
||||
path.quadraticBezierTo(
|
||||
size.width / 2,
|
||||
size.height,
|
||||
size.width,
|
||||
size.height - 120,
|
||||
);
|
||||
path.lineTo(size.width, 0);
|
||||
path.close();
|
||||
return path;
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
|
||||
}
|
||||
Reference in New Issue
Block a user