import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../bloc/book/book_bloc.dart'; import '../bloc/book/book_event.dart'; import '../models/models.dart'; import '../theme/app_theme.dart'; import '../theme/app_spacing.dart'; import 'add_book_screen.dart'; class BookDetailsScreen extends StatelessWidget { final Book book; const BookDetailsScreen({super.key, required this.book}); @override Widget build(BuildContext context) { final colorScheme = Theme.of(context).colorScheme; final textTheme = Theme.of(context).textTheme; final statusLabel = switch (book.status) { 'reading' => 'Читаю', 'done' => 'Прочитано', 'want_to_read' => 'Хочу прочитать', _ => book.status, }; return SingleChildScrollView( child: Material( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Hero section Stack( children: [ if (book.coverUrl != null) SizedBox( height: 300, width: double.infinity, child: ShaderMask( shaderCallback: (rect) => LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [colorScheme.surface, Colors.transparent], ).createShader(rect), blendMode: BlendMode.dstIn, child: Image.network(book.coverUrl!, fit: BoxFit.cover), ), ), SafeArea( child: Padding( padding: const EdgeInsets.fromLTRB( AppSpacing.sm, AppSpacing.sm, AppSpacing.sm, 0, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconButton( icon: const Icon(Icons.arrow_back), onPressed: () => Navigator.pop(context), ), IconButton( icon: const Icon(Icons.more_vert), onPressed: () {}, ), ], ), ), ), Positioned.fill( child: Align( alignment: Alignment.bottomCenter, child: Hero( tag: 'book-cover-${book.id}', child: Container( width: 140, height: 210, margin: const EdgeInsets.only(bottom: 0), decoration: BoxDecoration( borderRadius: BorderRadius.circular( AppSpacing.radiusLarge, ), boxShadow: AppTheme.shadowXl, ), child: ClipRRect( borderRadius: BorderRadius.circular( AppSpacing.radiusLarge, ), child: book.coverUrl != null ? Image.network(book.coverUrl!, fit: BoxFit.cover) : Container( color: colorScheme.surfaceContainerHighest, child: Center( child: Icon( Icons.book, color: colorScheme.primary.withValues( alpha: 0.3, ), size: 48, ), ), ), ), ), ), ), ), ], ), const SizedBox(height: AppSpacing.md), // Status badge Center( child: Container( padding: const EdgeInsets.symmetric( horizontal: AppSpacing.md, vertical: AppSpacing.sm, ), decoration: BoxDecoration( color: colorScheme.primaryContainer, border: Border.all(color: colorScheme.primary), borderRadius: BorderRadius.circular(AppSpacing.radiusPill), ), child: Text( statusLabel, style: textTheme.labelMedium?.copyWith( color: colorScheme.primary, ), ), ), ), const SizedBox(height: AppSpacing.md), // Title & Author Padding( padding: const EdgeInsets.symmetric(horizontal: AppSpacing.lg), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(book.title, style: textTheme.displayMedium), const SizedBox(height: AppSpacing.xs), Text( book.author, style: textTheme.titleLarge?.copyWith( color: colorScheme.onSurface.withValues(alpha: 0.7), ), ), const SizedBox(height: AppSpacing.md), // Genre tag Container( padding: const EdgeInsets.symmetric( horizontal: AppSpacing.md, vertical: AppSpacing.sm, ), decoration: BoxDecoration( color: colorScheme.surfaceContainerHighest, border: Border.all(color: colorScheme.outline), borderRadius: BorderRadius.circular(AppSpacing.radiusSmall), ), child: Text(book.genre, style: textTheme.labelMedium), ), const SizedBox(height: AppSpacing.lg), // Action buttons Row( children: [ Expanded( child: ElevatedButton.icon( onPressed: () { Navigator.of(context).push( MaterialPageRoute( builder: (_) => AddBookScreen(editBook: book), ), ); }, icon: const Icon(Icons.edit, size: 18), label: const Text('Изменить'), ), ), const SizedBox(width: AppSpacing.md), Expanded( child: OutlinedButton.icon( onPressed: () { context.read().add(DeleteBook(book.id)); Navigator.pop(context); }, icon: const Icon(Icons.delete_outline, size: 18), label: const Text('Удалить'), style: OutlinedButton.styleFrom( foregroundColor: colorScheme.error, side: BorderSide(color: colorScheme.error), ), ), ), ], ), const SizedBox(height: AppSpacing.lg), // About Text('О книге', style: textTheme.headlineMedium), const SizedBox(height: AppSpacing.sm), Text(book.annotation, style: textTheme.bodyLarge), const SizedBox(height: AppSpacing.lg), // Info grid GridView.count( crossAxisCount: 2, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), mainAxisSpacing: AppSpacing.md, crossAxisSpacing: AppSpacing.md, childAspectRatio: 2.5, children: [ _infoTile( context, Icons.menu_book, Colors.blue, 'Страницы', '${book.pages ?? "—"}', ), _infoTile( context, Icons.language, Colors.purple, 'Язык', book.language ?? '—', ), _infoTile( context, Icons.calendar_month, Colors.orange, 'Год', '${book.publishedYear ?? "—"}', ), _infoTile( context, Icons.star, Colors.amber, 'Рейтинг', '${book.rating ?? "—"}', ), ], ), const SizedBox(height: 40), ], ), ), ], ), ), ); } Widget _infoTile( BuildContext context, IconData icon, Color color, String label, String value, ) { final colorScheme = Theme.of(context).colorScheme; final textTheme = Theme.of(context).textTheme; return Container( padding: const EdgeInsets.all(AppSpacing.md), decoration: BoxDecoration( color: colorScheme.surface, border: Border.all(color: colorScheme.outline), borderRadius: BorderRadius.circular(AppSpacing.radiusMedium), boxShadow: AppTheme.shadowSm, ), child: Row( children: [ Container( padding: const EdgeInsets.all(AppSpacing.sm), decoration: BoxDecoration( color: color.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(AppSpacing.radiusSmall), ), child: Icon(icon, color: color, size: 22), ), const SizedBox(width: AppSpacing.sm), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Text(label, style: textTheme.labelSmall), Text( value, style: textTheme.titleSmall, overflow: TextOverflow.ellipsis, ), ], ), ), ], ), ); } }