mirror of
https://gitlab.com/foxixus/neomovies_mobile.git
synced 2025-10-27 22:38:50 +05:00
221 lines
7.0 KiB
Dart
221 lines
7.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:neomovies_mobile/presentation/providers/auth_provider.dart';
|
|
import 'package:neomovies_mobile/presentation/screens/auth/verify_screen.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
class LoginScreen extends StatefulWidget {
|
|
const LoginScreen({super.key});
|
|
|
|
@override
|
|
State<LoginScreen> createState() => _LoginScreenState();
|
|
}
|
|
|
|
class _LoginScreenState extends State<LoginScreen> with SingleTickerProviderStateMixin {
|
|
late TabController _tabController;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_tabController = TabController(length: 2, vsync: this);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_tabController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: const Text('Account'),
|
|
bottom: TabBar(
|
|
controller: _tabController,
|
|
tabs: const [
|
|
Tab(text: 'Login'),
|
|
Tab(text: 'Register'),
|
|
],
|
|
),
|
|
),
|
|
body: TabBarView(
|
|
controller: _tabController,
|
|
children: [
|
|
_LoginForm(),
|
|
_RegisterForm(),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _LoginForm extends StatefulWidget {
|
|
@override
|
|
__LoginFormState createState() => __LoginFormState();
|
|
}
|
|
|
|
class __LoginFormState extends State<_LoginForm> {
|
|
final _formKey = GlobalKey<FormState>();
|
|
String _email = '';
|
|
String _password = '';
|
|
|
|
void _submit() {
|
|
if (_formKey.currentState!.validate()) {
|
|
_formKey.currentState!.save();
|
|
Provider.of<AuthProvider>(context, listen: false).login(_email, _password);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Consumer<AuthProvider>(
|
|
builder: (context, auth, child) {
|
|
if (auth.needsVerification && auth.pendingEmail != null) {
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
Navigator.of(context).pushReplacement(
|
|
MaterialPageRoute(
|
|
builder: (_) => VerifyScreen(email: auth.pendingEmail!),
|
|
),
|
|
);
|
|
auth.clearVerificationFlag();
|
|
});
|
|
} else if (auth.state == AuthState.authenticated) {
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
Navigator.of(context).pop();
|
|
});
|
|
}
|
|
|
|
return Form(
|
|
key: _formKey,
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Column(
|
|
children: [
|
|
TextFormField(
|
|
decoration: const InputDecoration(labelText: 'Email'),
|
|
keyboardType: TextInputType.emailAddress,
|
|
validator: (value) => value!.isEmpty ? 'Email is required' : null,
|
|
onSaved: (value) => _email = value!,
|
|
),
|
|
TextFormField(
|
|
decoration: const InputDecoration(labelText: 'Password'),
|
|
obscureText: true,
|
|
validator: (value) => value!.isEmpty ? 'Password is required' : null,
|
|
onSaved: (value) => _password = value!,
|
|
),
|
|
const SizedBox(height: 20),
|
|
if (auth.state == AuthState.loading)
|
|
const CircularProgressIndicator()
|
|
else
|
|
ElevatedButton(
|
|
onPressed: _submit,
|
|
child: const Text('Login'),
|
|
),
|
|
if (auth.state == AuthState.error && auth.error != null)
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 16.0),
|
|
child: Text(auth.error!, style: TextStyle(color: Theme.of(context).colorScheme.error)),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
class _RegisterForm extends StatefulWidget {
|
|
@override
|
|
__RegisterFormState createState() => __RegisterFormState();
|
|
}
|
|
|
|
class __RegisterFormState extends State<_RegisterForm> {
|
|
final _formKey = GlobalKey<FormState>();
|
|
String _name = '';
|
|
String _email = '';
|
|
String _password = '';
|
|
|
|
void _submit() async {
|
|
if (_formKey.currentState!.validate()) {
|
|
_formKey.currentState!.save();
|
|
|
|
try {
|
|
await Provider.of<AuthProvider>(context, listen: false)
|
|
.register(_name, _email, _password);
|
|
|
|
final auth = Provider.of<AuthProvider>(context, listen: false);
|
|
|
|
// Проверяем, что регистрация прошла успешно
|
|
if (auth.state != AuthState.error) {
|
|
// Переходим к экрану верификации
|
|
if (mounted) {
|
|
Navigator.of(context).push(
|
|
MaterialPageRoute(
|
|
builder: (_) => VerifyScreen(email: _email),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
// Обрабатываем ошибку, если она произошла
|
|
if (mounted) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content: Text('Registration error: ${e.toString()}'),
|
|
backgroundColor: Theme.of(context).colorScheme.error,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Consumer<AuthProvider>(
|
|
builder: (context, auth, child) {
|
|
return Form(
|
|
key: _formKey,
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Column(
|
|
children: [
|
|
TextFormField(
|
|
decoration: const InputDecoration(labelText: 'Name'),
|
|
validator: (value) => value!.isEmpty ? 'Name is required' : null,
|
|
onSaved: (value) => _name = value!,
|
|
),
|
|
TextFormField(
|
|
decoration: const InputDecoration(labelText: 'Email'),
|
|
keyboardType: TextInputType.emailAddress,
|
|
validator: (value) => value!.isEmpty ? 'Email is required' : null,
|
|
onSaved: (value) => _email = value!,
|
|
),
|
|
TextFormField(
|
|
decoration: const InputDecoration(labelText: 'Password'),
|
|
obscureText: true,
|
|
validator: (value) => value!.length < 6 ? 'Password must be at least 6 characters long' : null,
|
|
onSaved: (value) => _password = value!,
|
|
),
|
|
const SizedBox(height: 20),
|
|
if (auth.state == AuthState.loading)
|
|
const CircularProgressIndicator()
|
|
else
|
|
ElevatedButton(
|
|
onPressed: _submit,
|
|
child: const Text('Register'),
|
|
),
|
|
if (auth.state == AuthState.error && auth.error != null)
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 16.0),
|
|
child: Text(auth.error!, style: TextStyle(color: Theme.of(context).colorScheme.error)),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
} |