Chepuhagram/lib/presentation/screens/account_setup_screen.dart

235 lines
8.7 KiB
Dart
Raw Permalink 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:provider/provider.dart';
import '../../logic/auth_provider.dart';
import 'contacts_screen.dart';
class AccountSetupScreen extends StatefulWidget {
const AccountSetupScreen({super.key});
@override
State<AccountSetupScreen> createState() => _AccountSetupScreenState();
}
class _AccountSetupScreenState extends State<AccountSetupScreen> {
final _formKey = GlobalKey<FormState>();
final _firstNameController = TextEditingController();
final _lastNameController = TextEditingController();
final _masterPasswordController = TextEditingController();
final _confirmPasswordController = TextEditingController();
bool _isLoading = false;
String? _errorMessage;
@override
void dispose() {
_firstNameController.dispose();
_lastNameController.dispose();
_masterPasswordController.dispose();
_confirmPasswordController.dispose();
super.dispose();
}
Future<void> _setupAccount() async {
if (!_formKey.currentState!.validate()) return;
setState(() {
_isLoading = true;
_errorMessage = null;
});
try {
final authProvider = context.read<AuthProvider>();
// Отправляем данные на сервер с мастер-паролем
final success = await authProvider.updateProfileAndSecurity(
firstName: _firstNameController.text.trim(),
lastName: _lastNameController.text.trim(),
masterPassword: _masterPasswordController.text,
);
if (success && mounted) {
// Переходим на экран контактов
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (_) => const ContactsScreen()),
);
} else if (mounted) {
setState(() {
_errorMessage = 'Ошибка при сохранении профиля. Попробуйте еще раз.';
_isLoading = false;
});
}
} catch (e) {
if (mounted) {
setState(() {
_errorMessage = 'Ошибка: ${e.toString()}';
_isLoading = false;
});
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Завершение настройки'),
centerTitle: true,
elevation: 0,
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(24.0),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 16),
Text(
'Завершите настройку вашего профиля',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headlineSmall,
),
const SizedBox(height: 8),
Text(
'Введите ваше имя, фамилию и создайте мастер-пароль. Мастер-пароль будет использоваться для защиты ваших ключей шифрования.',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).textTheme.bodySmall?.color,
),
),
const SizedBox(height: 32),
// Поле Имя
TextFormField(
controller: _firstNameController,
decoration: InputDecoration(
labelText: 'Имя *',
prefixIcon: const Icon(Icons.person_outline),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
hintText: 'Введите ваше имя',
),
validator: (value) {
if (value == null || value.trim().isEmpty) {
return 'Имя не может быть пустым';
}
return null;
},
),
const SizedBox(height: 16),
// Поле Фамилия
TextFormField(
controller: _lastNameController,
decoration: InputDecoration(
labelText: 'Фамилия',
prefixIcon: const Icon(Icons.person_outline),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
hintText: 'Введите вашу фамилию (опционально)',
),
),
const SizedBox(height: 16),
// Поле Мастер-пароль
TextFormField(
controller: _masterPasswordController,
obscureText: true,
decoration: InputDecoration(
labelText: 'Мастер-пароль *',
prefixIcon: const Icon(Icons.lock_outline),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
hintText: 'Создайте надежный пароль',
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Мастер-пароль не может быть пустым';
}
if (value.length < 8) {
return 'Пароль должен содержать минимум 8 символов';
}
return null;
},
),
const SizedBox(height: 16),
// Поле Подтверждение пароля
TextFormField(
controller: _confirmPasswordController,
obscureText: true,
decoration: InputDecoration(
labelText: 'Подтвердите пароль *',
prefixIcon: const Icon(Icons.lock_outline),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
hintText: 'Повторите пароль',
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Подтвердите пароль';
}
if (value != _masterPasswordController.text) {
return 'Пароли не совпадают';
}
return null;
},
),
const SizedBox(height: 24),
// Сообщение об ошибке
if (_errorMessage != null)
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.error.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: Text(
_errorMessage!,
style: TextStyle(
color: Theme.of(context).colorScheme.error,
),
),
),
const SizedBox(height: 24),
// Кнопка подтверждения
ElevatedButton(
onPressed: _isLoading ? null : _setupAccount,
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: _isLoading
? const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Text(
'Завершить настройку',
style: TextStyle(fontSize: 16),
),
),
const SizedBox(height: 24),
Text(
'Сохраните мастер-пароль в надежном месте. Он потребуется для восстановления ключей шифрования при переустановке приложения.',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.labelSmall,
),
],
),
),
),
);
}
}