import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:image_picker/image_picker.dart'; import 'package:cached_network_image/cached_network_image.dart'; import '../bloc/app_bloc.dart'; import '../bloc/app_event.dart'; import '../models/models.dart'; class AddBookScreen extends StatefulWidget { final dynamic initialData; const AddBookScreen({super.key, this.initialData}); @override State createState() => _AddBookScreenState(); } class _AddBookScreenState extends State { final _formKey = GlobalKey(); late TextEditingController _titleController; late TextEditingController _authorController; late TextEditingController _genreController; late TextEditingController _annotationController; String? _coverUrl; BookStatus _selectedStatus = BookStatus.wantToRead; @override void initState() { super.initState(); _titleController = TextEditingController(); _authorController = TextEditingController(); _genreController = TextEditingController(); _annotationController = TextEditingController(); if (widget.initialData is Book) { final book = widget.initialData as Book; _titleController.text = book.title; _authorController.text = book.author; _genreController.text = book.genre; _annotationController.text = book.annotation; _coverUrl = book.coverUrl; _selectedStatus = book.status; } else if (widget.initialData is Map) { final data = widget.initialData as Map; _titleController.text = data['title']?.toString() ?? ''; _authorController.text = data['author']?.toString() ?? ''; _genreController.text = data['genre']?.toString() ?? ''; _annotationController.text = data['annotation']?.toString() ?? ''; _coverUrl = data['coverUrl']?.toString(); } } @override void dispose() { _titleController.dispose(); _authorController.dispose(); _genreController.dispose(); _annotationController.dispose(); super.dispose(); } Future _pickImage() async { final picker = ImagePicker(); final XFile? image = await picker.pickImage(source: ImageSource.gallery); if (image != null) { setState(() { _coverUrl = image.path; }); } } void _saveBook() { if (_formKey.currentState!.validate()) { context.read().add( BookSaved({ 'title': _titleController.text, 'author': _authorController.text, 'genre': _genreController.text, 'annotation': _annotationController.text, 'coverUrl': _coverUrl, 'status': _selectedStatus, }), ); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFF112116), appBar: AppBar( backgroundColor: const Color(0xFF112116).withValues(alpha: 0.9), leading: IconButton( icon: const Icon(Icons.arrow_back_ios_new, color: Colors.white), onPressed: () { context.read().add( widget.initialData is Book ? const ScreenChanged(AppScreen.details) : const ScreenChanged(AppScreen.library), ); }, ), title: const Text('Добавить книгу'), centerTitle: true, ), body: Form( key: _formKey, child: ListView( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16), children: [ Center( child: GestureDetector( onTap: _pickImage, child: Container( width: 160, height: 240, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), border: Border.all( color: const Color(0xFF346544), width: 2, ), color: const Color(0xFF1A3222), ), child: _coverUrl != null ? ClipRRect( borderRadius: BorderRadius.circular(10), child: _coverUrl!.startsWith('http') ? CachedNetworkImage( imageUrl: _coverUrl!, fit: BoxFit.cover, width: double.infinity, height: double.infinity, ) : Image.network(_coverUrl!, fit: BoxFit.cover), ) : Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: const Color(0xFF17CF54).withValues(alpha: 0.1), shape: BoxShape.circle, ), child: const Icon( Icons.add_a_photo, color: Color(0xFF17CF54), size: 28, ), ), const SizedBox(height: 12), const Text( 'Загрузить', style: TextStyle( fontSize: 12, color: Color(0xFF93C8A5), ), ), ], ), ), ), ), const SizedBox(height: 32), _buildTextField( controller: _titleController, label: 'Название', validator: (value) => value?.isEmpty ?? true ? 'Введите название' : null, ), const SizedBox(height: 16), _buildTextField( controller: _authorController, label: 'Автор', validator: (value) => value?.isEmpty ?? true ? 'Введите автора' : null, ), const SizedBox(height: 16), _buildTextField( controller: _genreController, label: 'Жанр', validator: (value) => value?.isEmpty ?? true ? 'Введите жанр' : null, ), const SizedBox(height: 16), _buildTextField( controller: _annotationController, label: 'Аннотация', maxLines: 4, validator: (value) => value?.isEmpty ?? true ? 'Введите аннотацию' : null, ), const SizedBox(height: 16), DropdownButtonFormField( initialValue: _selectedStatus, decoration: InputDecoration( labelText: 'Статус', labelStyle: const TextStyle( color: Color(0xFFE0E0E0), fontSize: 14, fontWeight: FontWeight.w600, ), filled: true, fillColor: const Color(0xFF1A3222), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF346544)), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF346544)), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF17CF54)), ), ), dropdownColor: const Color(0xFF1A3222), style: const TextStyle(color: Colors.white), items: BookStatus.values.map((status) { return DropdownMenuItem( value: status, child: Text(status.displayName), ); }).toList(), onChanged: (value) { if (value != null) { setState(() { _selectedStatus = value; }); } }, ), const SizedBox(height: 120), ], ), ), bottomNavigationBar: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: const Color(0xFF112116).withValues(alpha: 0.95), border: Border( top: BorderSide(color: Colors.white.withValues(alpha: 0.05), width: 1), ), ), child: Row( children: [ Expanded( child: OutlinedButton( onPressed: () { context.read().add( widget.initialData is Book ? const ScreenChanged(AppScreen.details) : const ScreenChanged(AppScreen.library), ); }, style: OutlinedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 16), side: const BorderSide(color: Colors.transparent), ), child: const Text('Отмена'), ), ), const SizedBox(width: 12), Expanded( flex: 2, child: ElevatedButton.icon( onPressed: _saveBook, icon: const Icon(Icons.save), label: const Text('Сохранить'), style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF17CF54), foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 16), ), ), ), ], ), ), ); } Widget _buildTextField({ required TextEditingController controller, required String label, int maxLines = 1, String? Function(String?)? validator, }) { return TextFormField( controller: controller, maxLines: maxLines, validator: validator, style: const TextStyle(color: Colors.white, fontSize: 16), decoration: InputDecoration( labelText: label, labelStyle: const TextStyle( color: Color(0xFFE0E0E0), fontSize: 14, fontWeight: FontWeight.w600, ), filled: true, fillColor: const Color(0xFF1A3222), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF346544)), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF346544)), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF17CF54)), ), ), ); } }