Files
be_happy_public/lib/presentation/screens/pin_login_screen.dart

184 lines
6.7 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.

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import '../../core/app_colors.dart';
import '../components/code_dots.dart';
import '../event/map_event.dart';
import '../event/pin_event.dart';
import '../event/spalsh_event.dart';
import '../state/pin_state.dart';
import '../viewmodel/map_bloc.dart';
import '../viewmodel/pin_bloc.dart';
import '../viewmodel/splash_bloc.dart';
class PinLoginScreen extends StatefulWidget {
const PinLoginScreen({super.key});
@override
State<PinLoginScreen> createState() => _PinLoginScreenState();
}
class _PinLoginScreenState extends State<PinLoginScreen> {
final TextEditingController controller = TextEditingController();
final FocusNode focusNode = FocusNode();
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
focusNode.requestFocus();
});
controller.addListener(_onTextChanged);
}
void _onTextChanged() {
final text = controller.text;
context.read<PinBloc>().add(PinDigitChanged(text));
if (text.length == 6) {
context.read<PinBloc>().add(PinSubmitted(text));
}
}
@override
void dispose() {
controller.dispose();
focusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return BlocListener<PinBloc, PinState>(
listener: (context, state) {
if (state is PinSuccess) {
if (state.isProfileIncomplete) {
// Переходим на заполнение профиля, если хотя бы одно поле пустое
context.go('/edit-profile?isRegistration=true');
} else {
// Все поля заполнены — завершаем авторизацию и идем на главный экран
context.read<SplashBloc>().add(PinVerificationSuccess());
context.go('/home');
}
}
if (state.error != null) {
controller.clear();
focusNode.requestFocus();
}
},
child: Scaffold(
body: GestureDetector(
onTap: () => focusNode.requestFocus(),
child: Container(
decoration: const BoxDecoration(
gradient: AppColors.phoneScreenBg,
),
child: SafeArea(
child: Stack(
children: [
Positioned(
top: 310, left: 0, right: 0,
child: Image.asset("assets/wave.png", fit: BoxFit.cover),
),
BlocBuilder<PinBloc, PinState>(
builder: (context, state) {
final title = state is PinCreateInProgress
? "Создайте PIN-код"
: "Введите PIN-код";
final subtitle = state is PinCreateInProgress
? "Запомните PIN-код"
: "Введите ваш пароль для входа";
if (state is PinLoading) {
return const Center(child: CircularProgressIndicator());
}
return Column(
children: [
const SizedBox(height: 60),
Text(
title,
style: const TextStyle(
color: AppColors.whiteText,
fontSize: 20,
),
),
const SizedBox(height: 35),
Stack(
alignment: Alignment.center,
children: [
CodeDots(
code: state.pin,
length: 6,
),
SizedBox(
width: 200,
height: 50,
child: TextField(
controller: controller,
focusNode: focusNode,
keyboardType: TextInputType.number,
maxLength: 6,
showCursor: false,
decoration: const InputDecoration(
border: InputBorder.none,
counterText: "",
),
style: const TextStyle(color: Colors.transparent),
),
),
],
),
const SizedBox(height: 12),
if (state.error != null)
Text(
state.error!,
style: const TextStyle(
color: AppColors.pinError,
fontSize: 14,
),
),
const SizedBox(height: 40),
Text(
subtitle,
style: const TextStyle(color: AppColors.white70),
),
const SizedBox(height: 20),
if (state is! PinCreateInProgress)
TextButton(
onPressed: () {
context.read<MapBloc>().add(LogoutPressed());
context.read<SplashBloc>().add(AuthCheckRequested());
},
child: const Text(
"Забыли PIN-код?",
style: TextStyle(
color: AppColors.whiteText,
decoration: TextDecoration.underline,
fontSize: 14,
),
),
),
const SizedBox(height: 40),
],
);
},
),
],
),
),
),
),
),
);
}
}