Files
syncrow-web/lib/pages/auth/view/login_mobile_page.dart
2025-06-12 15:33:32 +03:00

340 lines
16 KiB
Dart

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
import 'package:syncrow_web/pages/auth/bloc/auth_bloc.dart';
import 'package:syncrow_web/pages/auth/bloc/auth_event.dart';
import 'package:syncrow_web/pages/auth/bloc/auth_state.dart';
// import 'package:syncrow_web/pages/auth/model/region_model.dart';
import 'package:syncrow_web/pages/auth/view/forget_password_page.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/constants/routes_const.dart';
import 'package:syncrow_web/utils/style.dart';
class LoginMobilePage extends StatelessWidget {
const LoginMobilePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocProvider(
create: (context) => AuthBloc(),
child: BlocConsumer<AuthBloc, AuthState>(
listener: (context, state) {
if (state is LoginSuccess) {
// Navigate to home screen after successful login
context.go(RoutesConst.home, extra: {'clearHistory': true});
} else if (state is LoginFailure) {
// Show error message
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(state.error),
),
);
}
},
builder: (context, state) {
if (state is AuthLoading) {
return const Center(child: CircularProgressIndicator());
} else {
return _buildLoginForm(context);
}
},
),
),
);
}
Widget _buildLoginForm(BuildContext context) {
final loginBloc = BlocProvider.of<AuthBloc>(context);
return Center(
child: Stack(
children: [
Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(
Assets.background,
),
fit: BoxFit.cover,
),
),
),
Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(Assets.vector),
fit: BoxFit.cover,
opacity: 0.9,
),
),
),
SingleChildScrollView(
child: Container(
margin: const EdgeInsets.all(50),
decoration: BoxDecoration(
color: Colors.black.withValues(alpha: 0.3),
borderRadius: const BorderRadius.all(Radius.circular(20))),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(15.0),
child: SvgPicture.asset(
Assets.loginLogo,
),
),
Container(
margin: const EdgeInsets.all(30),
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.1),
borderRadius:
const BorderRadius.all(Radius.circular(30)),
border: Border.all(
color: ColorsManager.graysColor
.withValues(alpha: 0.2))),
child: Form(
key: loginBloc.loginFormKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 15),
const Text(
'Login',
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold),
),
const SizedBox(height: 30),
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.start,
// children: [
// Text(
// "Country/Region",
// style: Theme.of(context).textTheme.bodySmall,
// ),
// SizedBox(
// child: DropdownButtonFormField<String>(
// validator: loginBloc.validateRegion,
// icon: const Icon(
// Icons.keyboard_arrow_down_outlined,
// ),
// decoration: textBoxDecoration()!.copyWith(
// hintText: null,
// ),
// hint: const Align(
// alignment: Alignment.centerLeft,
// child: Text(
// 'Select your region/country',
// textAlign: TextAlign.center,
// ),
// ),
// isDense: true,
// style: const TextStyle(color: Colors.black),
// items: loginBloc.regionList!.map((RegionModel region) {
// return DropdownMenuItem<String>(
// value: region.name,
// child: Text(region.name),
// );
// }).toList(),
// onChanged: (String? value) {},
// ),
// )
// ],
// ),
// const SizedBox(height: 20.0),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
'Email',
style: Theme.of(context).textTheme.bodySmall,
),
SizedBox(
child: TextFormField(
validator: loginBloc.validateEmail,
controller: loginBloc.loginEmailController,
decoration: textBoxDecoration()!
.copyWith(hintText: 'Enter your email'),
style: const TextStyle(color: Colors.black),
),
),
],
),
const SizedBox(height: 20.0),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
'Password',
style: Theme.of(context).textTheme.bodySmall,
),
SizedBox(
child: TextFormField(
validator: loginBloc.validatePassword,
obscureText: loginBloc.obscureText,
keyboardType: TextInputType.visiblePassword,
controller:
loginBloc.loginPasswordController,
decoration: textBoxDecoration()!.copyWith(
hintText: 'At least 8 characters',
),
style: const TextStyle(color: Colors.black),
),
),
],
),
const SizedBox(
height: 10,
),
SizedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
InkWell(
onTap: () {
Navigator.of(context)
.push(MaterialPageRoute(
builder: (context) =>
const ForgetPasswordPage(),
));
},
child: Text(
'Forgot Password?',
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
color: ColorsManager.blackColor),
),
),
],
),
),
Row(
children: [
Transform.scale(
scale: 1.2, // Adjust the scale as needed
child: Checkbox(
fillColor: WidgetStateProperty.all<Color>(
Colors.white),
activeColor: Colors.white,
value: loginBloc.isChecked,
checkColor: Colors.black,
shape: const CircleBorder(),
onChanged: (bool? newValue) {
loginBloc.add(
CheckBoxEvent(newValue: newValue));
},
),
),
SizedBox(
width: MediaQuery.sizeOf(context).width * 0.5,
child: RichText(
text: TextSpan(
text: 'Agree to ',
style:
const TextStyle(color: Colors.white),
children: [
TextSpan(
text: '(Terms of Service)',
style: const TextStyle(
color: Colors.black),
recognizer: TapGestureRecognizer()
..onTap = () {
loginBloc.launchURL(
'https://example.com/terms');
},
),
TextSpan(
text: ' (Legal Statement)',
style: const TextStyle(
color: Colors.black),
recognizer: TapGestureRecognizer()
..onTap = () {
loginBloc.launchURL(
'https://example.com/legal');
},
),
TextSpan(
text: ' (Privacy Statement)',
style: const TextStyle(
color: Colors.black),
recognizer: TapGestureRecognizer()
..onTap = () {
loginBloc.launchURL(
'https://example.com/privacy');
},
),
],
),
),
),
],
),
const SizedBox(height: 20.0),
SizedBox(
child: DefaultButton(
backgroundColor: loginBloc.isChecked
? ColorsManager.btnColor
: ColorsManager.grayColor,
child: const Text('Sign in'),
onPressed: () {
if (loginBloc.loginFormKey.currentState!
.validate()) {
loginBloc.add(
LoginButtonPressed(
username:
loginBloc.loginEmailController.text,
password: loginBloc
.loginPasswordController.text,
),
);
}
},
),
),
const SizedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Flexible(
child: Text(
"Don't you have an account? ",
style: TextStyle(
color: Colors.white, fontSize: 13),
)),
Text(
'Sign up',
),
],
),
)
],
),
)),
],
),
),
),
],
),
);
}
}