feat: integrate enakgame and voucher
Build & Deploy iOS to TestFlight / build-and-deploy (push) Waiting to run

This commit is contained in:
efrilm
2026-10-10 02:33:16 +07:00
parent e5515d5871
commit 38850b281f
104 changed files with 7122 additions and 8063 deletions
+10 -8
View File
@@ -137,18 +137,20 @@ List<NewsArticle> get newsSamples => [
),
NewsArticle(
id: 'n6',
title: 'Cara Bayar Pakai EnakPoint di Kasir',
summary: 'Cukup tunjukkan kode bayar. PIN tidak pernah diketik di kasir.',
title: 'Cara Tukar EnakPoint ke Voucher',
summary:
'Pilih voucher di EnakReward, masukkan PIN, lalu tunjukkan ke kasir.',
category: NewsCategory.tips,
publishedAt: _daysAgo(5),
readMinutes: 3,
paragraphs: [
'EnakPoint bisa langsung dipakai untuk membayar di kasir. Setiap 1 '
'EnakPoint setara potongan Rp 1.',
'Tekan tombol Bayar di tengah menu bawah, lalu masukkan PIN kamu. '
'Aplikasi akan menampilkan kode angka dan QR.',
'Tunjukkan kode itu ke kasir. Kasir yang memilih berapa EnakPoint yang '
'dipakai. Kode berlaku 2 menit dan hanya bisa dipakai sekali.',
'EnakPoint kamu bisa ditukar dengan voucher, misalnya menu gratis atau '
'potongan belanja. Buka menu EnakReward untuk melihat voucher yang '
'tersedia.',
'Pilih voucher, tekan Tukar, lalu masukkan PIN kamu. Penukaran tidak '
'bisa dibatalkan.',
'Voucher yang sudah ditukar ada di tab Voucher saya. Tunjukkan layar '
'voucher atau kodenya ke kasir saat memesan.',
'PIN hanya dimasukkan di aplikasi, tidak pernah di mesin kasir. Jangan '
'berikan PIN kamu kepada siapa pun, termasuk petugas outlet.',
],
-139
View File
@@ -1,139 +0,0 @@
// Models
enum RewardStatus { active, used, expired }
class Reward {
final String id;
final String name;
final String emoji;
final String description;
final String categoryName;
final int pointsUsed;
final DateTime redeemedAt;
final DateTime validUntil;
final RewardStatus status;
final String? couponCode;
final DateTime? usedAt;
final String? termsAndConditions;
const Reward({
required this.id,
required this.name,
required this.emoji,
required this.description,
required this.categoryName,
required this.pointsUsed,
required this.redeemedAt,
required this.validUntil,
required this.status,
this.couponCode,
this.usedAt,
this.termsAndConditions,
});
}
// Sample Data
//
// 1 EnakPoint = potongan Rp 1, jadi harga reward dibuat sedikit di bawah harga
// menunya supaya menukar lebih untung daripada bayar langsung pakai poin.
// Menu gratis berlaku 14 hari dan voucher potongan 30 hari sejak ditukar.
DateTime _daysAgo(int days) => DateTime.now().subtract(Duration(days: days));
DateTime _daysFromNow(int days) => DateTime.now().add(Duration(days: days));
/// Getter, bukan `final`, supaya perubahan data langsung terbaca saat hot
/// reload (variabel global yang sudah terisi tidak diisi ulang).
List<Reward> get rewardSamples => [
Reward(
id: 'r1',
name: 'Kopi Susu',
emoji: '☕',
description: '1 Kopi Susu regular di Tumulu Coffee',
categoryName: 'Minuman',
pointsUsed: 20000,
redeemedAt: _daysAgo(11),
validUntil: _daysFromNow(3),
status: RewardStatus.active,
couponCode: 'ENK-7QM2PX',
termsAndConditions:
'Berlaku untuk 1 Kopi Susu ukuran regular di Tumulu Coffee, dine-in '
'atau take away. Upsize dan tambahan topping dibayar terpisah. '
'Tunjukkan kode ke kasir sebelum membayar.',
),
Reward(
id: 'r2',
name: 'Bakso Urat',
emoji: '🍲',
description: '1 porsi Bakso Urat di Bakso 343',
categoryName: 'Makanan',
pointsUsed: 18000,
redeemedAt: DateTime.now().subtract(const Duration(hours: 5)),
validUntil: _daysFromNow(14),
status: RewardStatus.active,
couponCode: 'ENK-B3HW8N',
termsAndConditions:
'Berlaku untuk 1 porsi Bakso Urat di Bakso 343, dine-in atau take '
'away. Tunjukkan kode ke kasir sebelum membayar.',
),
Reward(
id: 'r3',
name: 'Potongan Rp 10.000',
emoji: '🎟️',
description: 'Min. belanja Rp 50.000 di semua outlet',
categoryName: 'Voucher',
pointsUsed: 8000,
redeemedAt: _daysAgo(2),
validUntil: _daysFromNow(28),
status: RewardStatus.active,
couponCode: 'ENK-K9D4TR',
termsAndConditions:
'Berlaku untuk 1 transaksi dengan minimum belanja Rp 50.000 di semua '
'outlet. Tidak dapat digabung dengan voucher lain dan tidak dapat '
'diuangkan.',
),
Reward(
id: 'r4',
name: 'Es Teh Manis',
emoji: '🥤',
description: '1 gelas Es Teh Manis di semua outlet',
categoryName: 'Minuman',
pointsUsed: 4000,
redeemedAt: _daysAgo(9),
validUntil: _daysFromNow(5),
usedAt: _daysAgo(8),
status: RewardStatus.used,
couponCode: 'ENK-5TRJ6C',
termsAndConditions:
'Berlaku untuk 1 gelas Es Teh Manis ukuran regular di semua outlet.',
),
Reward(
id: 'r5',
name: 'Gyoza Goreng',
emoji: '🥟',
description: '5 pcs Gyoza goreng di Ramenmulu',
categoryName: 'Cemilan',
pointsUsed: 16000,
redeemedAt: _daysAgo(20),
validUntil: _daysAgo(6),
usedAt: _daysAgo(16),
status: RewardStatus.used,
couponCode: 'ENK-G8VL2F',
termsAndConditions:
'Berlaku untuk 1 porsi Gyoza goreng isi 5 di Ramenmulu. Tidak berlaku '
'untuk menu paket.',
),
Reward(
id: 'r6',
name: 'Potongan Rp 5.000',
emoji: '🎟️',
description: 'Min. belanja Rp 30.000 di semua outlet',
categoryName: 'Voucher',
pointsUsed: 4000,
redeemedAt: _daysAgo(50),
validUntil: _daysAgo(20),
status: RewardStatus.expired,
couponCode: 'ENK-P2XN7D',
termsAndConditions:
'Berlaku untuk 1 transaksi dengan minimum belanja Rp 30.000 di semua '
'outlet. Tidak dapat digabung dengan voucher lain dan tidak dapat '
'diuangkan.',
),
];