import 'dart:convert'; import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flutter_html/flutter_html.dart'; import '../theme/app_theme.dart'; /// Detail screen for a tapped carousel slide. /// Displays the banner image (base64 or network URL), title, and rich HTML detail content. class CarouselDetailScreen extends StatelessWidget { final dynamic slide; const CarouselDetailScreen({super.key, required this.slide}); @override Widget build(BuildContext context) { final title = slide['name'] as String? ?? 'Slide Details'; final bodyHtml = slide['body'] as String? ?? ''; final base64Img = slide['image'] as String?; final externalUrl = slide['image_url'] as String?; return Scaffold( appBar: AppBar(title: Text(title)), body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Slide image (full width) _buildSlideImage(base64Img, externalUrl), Padding( padding: const EdgeInsets.fromLTRB(20, 20, 20, 8), child: Text( title, style: Theme.of(context).textTheme.titleLarge, ), ), if (bodyHtml.isNotEmpty) Padding( padding: const EdgeInsets.symmetric(horizontal: 12), child: Html( data: bodyHtml, style: { 'body': Style( color: AppTheme.onSurface, fontFamily: 'Manrope', fontSize: FontSize(15), lineHeight: const LineHeight(1.6), ), 'p': Style(margin: Margins.only(bottom: 12)), 'h1': Style( color: AppTheme.onSurface, fontSize: FontSize(22), fontWeight: FontWeight.bold, ), 'h2': Style( color: AppTheme.onSurface, fontSize: FontSize(18), fontWeight: FontWeight.bold, ), 'a': Style(color: AppTheme.secondary), }, ), ) else Padding( padding: const EdgeInsets.all(20), child: Text( 'No content available.', style: Theme.of(context).textTheme.bodyMedium, ), ), const SizedBox(height: 32), ], ), ), ); } Widget _buildSlideImage(String? base64Img, String? externalUrl) { if (base64Img != null && base64Img.isNotEmpty) { try { final Uint8List bytes = base64Decode(base64Img); return Image.memory( bytes, width: double.infinity, height: 220, fit: BoxFit.cover, ); } catch (_) { return _placeholder(); } } else if (externalUrl != null && externalUrl.isNotEmpty) { return Image.network( externalUrl, width: double.infinity, height: 220, fit: BoxFit.cover, errorBuilder: (_, _, _) => _placeholder(), loadingBuilder: (ctx, child, progress) { if (progress == null) return child; return Container( height: 220, color: AppTheme.surfaceContainer, child: const Center(child: CircularProgressIndicator()), ); }, ); } else { return _placeholder(); } } Widget _placeholder() { return Container( height: 220, color: AppTheme.surfaceContainer, child: const Center( child: Icon(Icons.image_rounded, size: 56, color: AppTheme.outlineVariant), ), ); } }