import 'package:flutter/material.dart'; import '../../../../common/extension/extension.dart'; import '../../../../common/theme/theme.dart'; import '../../../../domain/wallet/wallet.dart'; import '../../wallet/wallet_ui.dart'; import '../reward_ui.dart'; import 'ticket_card.dart'; /// Voucher di katalog (§9.1). class VoucherCard extends StatelessWidget { const VoucherCard({ super.key, required this.voucher, required this.canAfford, required this.onTap, }); final Voucher voucher; /// Saldo EnakPoint cukup untuk [Voucher.pointCost]. final bool canAfford; final VoidCallback onTap; bool get _canRedeem => canAfford && !voucher.isOutOfStock; @override Widget build(BuildContext context) { final faceValue = voucherFaceValueLabel(voucher.type, voucher.faceValue); return TicketCard( active: _canRedeem, onTap: onTap, stub: TicketStub( image: VoucherImage( url: voucher.imageUrl, size: 44, dimmed: voucher.isOutOfStock, ), pointCost: voucher.pointCost.thousandFormat, active: _canRedeem, ), body: Padding( padding: const EdgeInsets.fromLTRB(14, 12, 14, 12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( voucherTypeLabel(voucher.type, voucher.faceValue).toUpperCase(), style: AppStyle.xs.copyWith( color: AppColor.textSecondary, fontWeight: FontWeight.w700, letterSpacing: 0.6, ), ), const SizedBox(height: 4), Text( voucher.name, maxLines: 2, overflow: TextOverflow.ellipsis, style: AppStyle.lg.copyWith(fontWeight: FontWeight.w700), ), if (faceValue != null) Text( faceValue, style: AppStyle.sm.copyWith(color: AppColor.textSecondary), ), const SizedBox(height: 10), Row( children: [ Expanded(child: _buildFootnote()), const SizedBox(width: 8), _buildAction(), ], ), ], ), ), ); } Widget _buildFootnote() { final parts = [ if (voucher.validUntil != null) 's/d ${formatWibDate(voucher.validUntil!)}', if (voucher.available != null && !voucher.isOutOfStock) 'sisa ${voucher.available!.thousandFormat}', ]; if (parts.isEmpty) return const SizedBox.shrink(); return Text( parts.join(' · '), maxLines: 2, overflow: TextOverflow.ellipsis, style: AppStyle.xs.copyWith( color: AppColor.textSecondary, fontWeight: FontWeight.w600, ), ); } Widget _buildAction() { final (String label, bool enabled) = voucher.isOutOfStock ? ('Habis', false) : canAfford ? ('Tukar', true) : ('Poin kurang', false); return Container( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 6), decoration: BoxDecoration( color: enabled ? AppColor.primary : AppColor.background, borderRadius: BorderRadius.circular(20), ), child: Text( label, style: AppStyle.sm.copyWith( color: enabled ? AppColor.white : AppColor.textSecondary, fontWeight: FontWeight.w700, ), ), ); } }