211 lines
7.5 KiB
Dart
211 lines
7.5 KiB
Dart
// 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),
|
||
);
|
||
}
|
||
} |