134 lines
3.8 KiB
Dart
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,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|