Files
enaklo-flutter/lib/presentation/pages/reward/widgets/redemption_card.dart
T
efrilm 38850b281f
Build & Deploy iOS to TestFlight / build-and-deploy (push) Canceled after 0s
feat: integrate enakgame and voucher
2026-10-10 02:33:16 +07:00

134 lines
3.8 KiB
Dart

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';
/// Satu voucher di "Voucher saya" (ยง9.3).
class RedemptionCard extends StatelessWidget {
const RedemptionCard({
super.key,
required this.redemption,
required this.onTap,
});
final VoucherRedemption redemption;
final VoidCallback onTap;
bool get _isReady => redemption.status == VoucherRedemptionStatus.completed;
@override
Widget build(BuildContext context) {
final status = redemption.status;
return TicketCard(
active: _isReady,
onTap: onTap,
stub: TicketStub(
image: VoucherImage(
url: redemption.voucherImageUrl,
size: 44,
dimmed: !_isReady,
),
pointCost: redemption.pointCost.thousandFormat,
active: _isReady,
),
body: Padding(
padding: const EdgeInsets.fromLTRB(14, 12, 14, 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
voucherTypeLabel(
redemption.voucherType,
redemption.faceValue,
).toUpperCase(),
style: AppStyle.xs.copyWith(
color: AppColor.textSecondary,
fontWeight: FontWeight.w700,
letterSpacing: 0.6,
),
),
),
if (status != VoucherRedemptionStatus.unknown)
VoucherRedemptionStatusBadge(status: status),
],
),
const SizedBox(height: 4),
Text(
redemption.voucherName,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: AppStyle.lg.copyWith(
color: _isReady ? AppColor.textPrimary : AppColor.textSecondary,
fontWeight: FontWeight.w700,
),
),
if (_isReady && redemption.code != null) ...[
const SizedBox(height: 2),
Text(
redemption.code!,
style: AppStyle.sm.copyWith(
fontWeight: FontWeight.w700,
letterSpacing: 1,
),
),
],
const SizedBox(height: 8),
_buildFootnote(),
],
),
),
);
}
Widget _buildFootnote() {
final (IconData icon, String text) = switch (redemption.status) {
VoucherRedemptionStatus.completed => (
Icons.schedule,
redemption.codeExpiresAt == null
? 'Tunjukkan ke kasir'
: 'Berlaku sampai ${formatWibDate(redemption.codeExpiresAt!)}',
),
VoucherRedemptionStatus.pending => (
Icons.hourglass_top_rounded,
'Voucher sedang diproses',
),
VoucherRedemptionStatus.failed => (
Icons.undo_rounded,
'EnakPoint sudah dikembalikan',
),
VoucherRedemptionStatus.unknown => (
Icons.info_outline,
redemption.createdAt == null
? ''
: 'Ditukar ${formatWibDate(redemption.createdAt!)}',
),
};
return Row(
children: [
Icon(icon, size: 14, color: AppColor.textSecondary),
const SizedBox(width: 4),
Expanded(
child: Text(
text,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: AppStyle.xs.copyWith(
color: AppColor.textSecondary,
fontWeight: FontWeight.w600,
),
),
),
],
);
}
}