proxibuy/lib/presentation/pages/login_page.dart

207 lines
7.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:country_picker/country_picker.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:proxibuy/presentation/auth/bloc/auth_bloc.dart';
import 'package:proxibuy/presentation/pages/otp_page.dart';
import '../../core/gen/assets.gen.dart';
class LoginPage extends StatefulWidget {
const LoginPage({super.key});
@override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final TextEditingController _phoneController = TextEditingController();
Country _selectedCountry = Country.parse('IR');
void _sendOtp() {
context.read<AuthBloc>().add(
SendOTPEvent(
phoneNumber: _phoneController.text,
countryCode: _selectedCountry.phoneCode,
),
);
}
@override
void dispose() {
_phoneController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
return Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 32),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Hero(
tag: 'auth_logo',
child: Center(child: Assets.icons.logo.svg(height: 160)),
),
const SizedBox(height: 48),
Text(
"ورود",
style: textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 48),
TextField(
readOnly: true,
controller: TextEditingController(
text: _selectedCountry.name,
),
onTap: _showCountryPicker,
decoration: InputDecoration(
labelText: "کشور",
prefixIcon: Padding(
padding: const EdgeInsets.only(
left: 12.0,
right: 8.0,
top: 7,
),
child: Text(
_selectedCountry.flagEmoji,
style: const TextStyle(fontSize: 24),
),
),
suffixIcon: const Icon(Icons.keyboard_arrow_down_rounded),
),
),
const SizedBox(height: 16),
TextField(
controller: _phoneController,
keyboardType: TextInputType.phone,
textDirection: TextDirection.ltr,
textAlign: TextAlign.left,
decoration: InputDecoration(
labelText: "شماره موبایل",
hintText: "- - - - - - - - - -",
suffix: Padding(
padding: const EdgeInsets.symmetric(horizontal: 2.0),
child: Text(
_selectedCountry.phoneCode,
style: textTheme.bodyLarge?.copyWith(
color: Colors.black,
),
),
),
),
),
const SizedBox(height: 24),
BlocConsumer<AuthBloc, AuthState>(
listener: (context, state) {
if (state is AuthFailure) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(state.message),
backgroundColor: Colors.red,
),
);
}
if (state is AuthCodeSentSuccess) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => OtpPage(
phoneNumber:
"${state.countryCode}${state.phone}",
phone: state.phone,
countryCode: state.countryCode,
),
),
);
}
},
builder: (context, state) {
bool isLoading = state is AuthLoading;
return SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: isLoading ? null : _sendOtp,
child: isLoading
? const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
color: Colors.white,
strokeWidth: 3,
),
)
: const Text("کد یکبار مصرف"),
),
);
},
),
const SizedBox(height: 32),
Row(
children: [
const Expanded(child: Divider()),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
"یا ادامه با",
style: textTheme.bodyMedium?.copyWith(
color: Colors.grey,
),
),
),
const Expanded(child: Divider()),
],
),
const SizedBox(height: 32),
SizedBox(
width: double.infinity,
child: OutlinedButton.icon(
icon: Assets.icons.googleSvg.svg(width: 24),
label: const Text(
"ورود با حساب گوگل",
style: TextStyle(color: Colors.black),
),
onPressed: () {},
),
),
]
.animate(interval: 100.ms)
.fadeIn(duration: 400.ms, curve: Curves.easeOut)
.slideY(begin: 0.2, duration: 400.ms, curve: Curves.easeOut),
),
),
),
),
);
}
void _showCountryPicker() {
showCountryPicker(
context: context,
countryListTheme: CountryListThemeData(
bottomSheetHeight: 500,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
inputDecoration: InputDecoration(
labelText: 'جستجو',
hintText: 'کشور مورد نظر را جستجو کنید',
prefixIcon: const Icon(Icons.search),
),
),
onSelect: (Country country) => setState(() => _selectedCountry = country),
);
}
}