proxibuy/lib/presentation/pages/login_page.dart

211 lines
7.5 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// lib/presentation/pages/login_page.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) {
// ******** شروع تغییر ۱ ********
// BlocProvider.value حذف شد
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),
);
}
}