import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../../application/outlet/outlet_list_loader/outlet_list_loader_bloc.dart'; import '../../../../application/outlet/selected_outlet/selected_outlet_bloc.dart'; import '../../../../common/theme/theme.dart'; import '../../../../domain/outlet/outlet.dart'; import '../../../components/spacer/spacer.dart'; import '../../../components/widgets/particle_card.dart'; class HomePromoBanner extends StatelessWidget { const HomePromoBanner({super.key}); @override Widget build(BuildContext context) { return BlocBuilder( builder: (context, outletListState) { if (outletListState.isFetching && outletListState.outlets.isEmpty) { return const _PromoBannerSkeleton(); } if (outletListState.outlets.isEmpty) { return const SizedBox.shrink(); } return BlocBuilder( builder: (context, selectedState) { return Padding( padding: const EdgeInsets.fromLTRB( AppValue.padding, 24, AppValue.padding, 0, ), child: Row( children: [ for (int i = 0; i < outletListState.outlets.length; i++) ...[ Expanded( child: _OutletCard( outlet: outletListState.outlets[i], isSelected: selectedState.selectedOutletId == outletListState.outlets[i].id, onTap: () { final tapped = outletListState.outlets[i]; if (selectedState.selectedOutletId == tapped.id) { // Tap outlet yang sama → deselect (Semua Outlet) context .read() .add(const SelectedOutletEvent.cleared()); } else { context .read() .add(SelectedOutletEvent.selected(tapped)); } }, ), ), if (i < outletListState.outlets.length - 1) const SpaceWidth(12), ], ], ), ); }, ); }, ); } } class _OutletCard extends StatelessWidget { final Outlet outlet; final bool isSelected; final VoidCallback onTap; const _OutletCard({ required this.outlet, required this.isSelected, required this.onTap, }); @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: AnimatedContainer( duration: const Duration(milliseconds: 200), decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), border: Border.all( color: isSelected ? AppColor.white : Colors.transparent, width: 2, ), boxShadow: isSelected ? [ BoxShadow( color: AppColor.white.withOpacity(0.3), blurRadius: 8, offset: const Offset(0, 2), ), ] : [], ), child: Opacity( opacity: isSelected ? 1.0 : 0.55, child: ParticleCard( height: 110, padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), decorationOpacity: 0.8, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ const Spacer(), _buildStatusBadge(outlet.isActive), ], ), const SpaceHeight(6), Text( outlet.name, style: AppStyle.sm.copyWith( color: AppColor.white, fontWeight: FontWeight.w800, height: 1.25, ), maxLines: 3, overflow: TextOverflow.ellipsis, ), ], ), ), ), ), ); } Widget _buildStatusBadge(bool isActive) { return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( color: isActive ? AppColor.success.withOpacity(0.9) : AppColor.error.withOpacity(0.9), borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: (isActive ? AppColor.success : AppColor.error) .withOpacity(0.3), blurRadius: 4, offset: const Offset(0, 2), ), ], ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( isActive ? Icons.check_circle : Icons.warning_rounded, color: AppColor.white, size: 12, ), const SpaceWidth(4), Text( isActive ? 'Sehat' : 'Tidak Sehat', style: AppStyle.xs.copyWith( color: AppColor.white, fontWeight: FontWeight.w700, fontSize: 9, ), ), ], ), ); } } class _PromoBannerSkeleton extends StatelessWidget { const _PromoBannerSkeleton(); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.fromLTRB( AppValue.padding, 24, AppValue.padding, 0, ), child: Row( children: [ Expanded(child: _skeletonCard()), const SpaceWidth(12), Expanded(child: _skeletonCard()), ], ), ); } Widget _skeletonCard() { return Container( height: 110, decoration: BoxDecoration( color: AppColor.border, borderRadius: BorderRadius.circular(12), ), ); } }