import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'dart:convert'; import '../models/film.dart'; import '../widgets/schedule_selection_widget.dart'; class DetailPage extends StatelessWidget { final Film film; final String username; final bool isGuest; const DetailPage({ super.key, required this.film, required this.username, required this.isGuest, }); Widget _buildFilmImage(String? imageUrl, {required double width, required double height}) { if (imageUrl == null || imageUrl.isEmpty) { return Center( child: Icon(Icons.movie, size: 100, color: Colors.grey), ); } if (imageUrl.startsWith('data:image')) { // Base64 image try { final base64String = imageUrl.split(',')[1]; final bytes = base64Decode(base64String); return ClipRRect( borderRadius: BorderRadius.circular(16), child: Image.memory( bytes, width: width, height: height, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return Center( child: Icon(Icons.movie, size: 100, color: Colors.grey), ); }, ), ); } catch (e) { return Center( child: Icon(Icons.movie, size: 100, color: Colors.grey), ); } } else { // Network image (URL) return ClipRRect( borderRadius: BorderRadius.circular(16), child: Image.network( imageUrl, width: width, height: height, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return Center( child: Icon(Icons.movie, size: 100, color: Colors.grey), ); }, ), ); } } @override Widget build(BuildContext context) { final isComingSoon = film.releaseDate.isAfter(DateTime.now()); return Scaffold( appBar: AppBar( backgroundColor: Colors.black, title: const Text('Detail Film'), actions: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Row( children: [ const Icon(Icons.person, size: 20), const SizedBox(width: 8), Text(username), ], ), ), ], ), body: SingleChildScrollView( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 300, height: 450, decoration: BoxDecoration( color: Colors.grey[800], borderRadius: BorderRadius.circular(16), ), child: Stack( children: [ _buildFilmImage(film.imageUrl, width: 300, height: 450), Positioned( top: 12, left: 12, child: Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 6), decoration: BoxDecoration( color: Colors.black87, borderRadius: BorderRadius.circular(8), ), child: Text( film.ageRating, style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 14), ), ), ), ], ), ), const SizedBox(width: 32), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( film.title, style: const TextStyle( fontSize: 36, fontWeight: FontWeight.bold), ), const SizedBox(height: 16), Row( children: [ const Icon(Icons.star, size: 28, color: Color(0xFFFBBF24)), const SizedBox(width: 8), Text( film.rating.toString(), style: const TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Color(0xFFFBBF24), ), ), const SizedBox(width: 24), Text(film.genre, style: const TextStyle(color: Colors.grey)), const SizedBox(width: 24), const Icon(Icons.access_time, size: 20, color: Colors.grey), const SizedBox(width: 4), Text( '${film.duration} menit', style: const TextStyle(color: Colors.grey), ), ], ), const SizedBox(height: 24), _buildInfoRow('Sutradara', film.director), const SizedBox(height: 8), _buildInfoRow('Pemain', film.cast.join(', ')), const SizedBox(height: 8), _buildInfoRow( 'Tanggal Rilis', DateFormat('dd MMMM yyyy').format(film.releaseDate), ), const SizedBox(height: 24), const Text( 'Sinopsis', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 8), Text( film.description, style: const TextStyle( fontSize: 16, color: Colors.grey, height: 1.5), ), const SizedBox(height: 32), if (isComingSoon) Container( padding: const EdgeInsets.all(24), decoration: BoxDecoration( color: const Color(0xFF1F2937), borderRadius: BorderRadius.circular(12), border: Border.all(color: const Color(0xFF374151)), ), child: Column( children: [ const Icon(Icons.schedule, size: 48, color: Color(0xFFFBBF24)), const SizedBox(height: 16), const Text( 'Film ini akan segera tayang', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 8), Text( 'Mulai ${DateFormat('dd MMMM yyyy').format(film.releaseDate)}', style: const TextStyle( color: Color(0xFFFBBF24), fontSize: 16), ), ], ), ) else ScheduleSelectionWidget( film: film, username: username, isGuest: isGuest, ), ], ), ), ], ), ], ), ), ); } Widget _buildInfoRow(String label, String value) { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 120, child: Text( label, style: const TextStyle( color: Colors.grey, fontWeight: FontWeight.w500), ), ), const Text(': ', style: TextStyle(color: Colors.grey)), Expanded( child: Text(value, style: const TextStyle(fontWeight: FontWeight.w500)), ), ], ); } }