Files
enaklo-flutter/lib/presentation/pages/promo/widgets/promo_card.dart
T
efrilmandClaude Opus 5.5 c35d0eedbe EnakPromo: halaman promo dan detail promo
- Banner promo unggulan, info cara dapat, filter per tipe hadiah, daftar
  promo berlangsung dan segera hadir
- Detail promo: hadiah, periode, outlet, cara dapat, S&K, CTA ke Reward
  Saya atau daftar outlet
- Data contoh mengikuti bentuk campaign backend (POINTS/COINS/REWARD)
- Filter chip Reward Saya dipindah ke komponen bersama FilterBarDelegate

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 02:17:54 +07:00

121 lines
4.3 KiB
Dart

import 'package:flutter/material.dart';
import '../../../../common/theme/theme.dart';
import '../../../../sample/promo_sample_data.dart';
import '../promo_ui.dart';
class PromoCard extends StatelessWidget {
const PromoCard({super.key, required this.promo, required this.onTap});
final Promo promo;
final VoidCallback onTap;
@override
Widget build(BuildContext context) {
final color = promo.type.color;
return Material(
color: AppColor.white,
borderRadius: BorderRadius.circular(16),
shadowColor: Colors.black.withOpacity(0.25),
elevation: 1,
child: InkWell(
borderRadius: BorderRadius.circular(16),
onTap: onTap,
child: Padding(
padding: const EdgeInsets.all(14),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 56,
height: 56,
alignment: Alignment.center,
decoration: BoxDecoration(
color: color.withOpacity(0.08),
borderRadius: BorderRadius.circular(14),
),
child: PromoTypeIcon(type: promo.type, size: 34),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 3,
),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(6),
),
child: Text(
promo.rewardLabel,
style: AppStyle.xs.copyWith(
color: color,
fontWeight: FontWeight.w800,
),
),
),
const SizedBox(height: 6),
Text(
promo.title,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: AppStyle.md.copyWith(fontWeight: FontWeight.w700),
),
const SizedBox(height: 2),
Text(
promo.subtitle,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: AppStyle.sm.copyWith(
color: AppColor.textSecondary,
),
),
const SizedBox(height: 10),
// Wrap: di layar sempit label waktu turun ke baris baru
// supaya nama outlet tidak terpotong.
Wrap(
spacing: 8,
runSpacing: 6,
crossAxisAlignment: WrapCrossAlignment.center,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(
Icons.storefront_outlined,
size: 14,
color: AppColor.textSecondary,
),
const SizedBox(width: 4),
Flexible(
child: Text(
promoOutletLabel(promo),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: AppStyle.xs.copyWith(
color: AppColor.textSecondary,
fontWeight: FontWeight.w600,
),
),
),
],
),
PromoTimeBadge(promo: promo),
],
),
],
),
),
],
),
),
),
);
}
}