// Models // // EnakShop adalah toko online. Tahap ini baru katalog; keranjang dan checkout // menyusul setelah API toko tersedia. enum ShopCategory { frozen('Makanan Beku', '🥟'), sauce('Sambal & Bumbu', '🌶️'), coffee('Kopi & Minuman', '☕'), noodle('Mie & Ramen', '🍜'), snack('Camilan', '🍪'), merch('Merchandise', '🛍️'), hampers('Hampers', '🎁'); const ShopCategory(this.label, this.emoji); final String label; final String emoji; } /// Label pojok kartu produk. enum ShopTag { bestSeller('Terlaris'), newArrival('Baru'); const ShopTag(this.label); final String label; } class ShopProduct { final String id; final String name; final ShopCategory category; final int price; /// Harga setelah diskon; `null` bila tidak sedang diskon. final int? discountPrice; final String emoji; /// Warna latar gambar produk, ARGB. final int tint; /// Berat atau isi, mis. "500 g" atau "Isi 25 butir". final String unit; final String description; /// Judul pilihan varian, mis. "Ukuran" atau "Level pedas". final String variantLabel; final List variants; final int soldCount; final int stock; final ShopTag? tag; final DateTime addedAt; const ShopProduct({ required this.id, required this.name, required this.category, required this.price, required this.emoji, required this.tint, required this.unit, required this.description, required this.soldCount, required this.stock, required this.addedAt, this.discountPrice, this.variantLabel = 'Varian', this.variants = const [], this.tag, }); bool get isDiscounted => discountPrice != null; int get finalPrice => discountPrice ?? price; /// Persen potongan, dibulatkan. int get discountPercent => isDiscounted ? ((price - discountPrice!) * 100 / price).round() : 0; } /// Banner promo di beranda toko; mengarah ke satu kategori. class ShopPromo { final String id; final String title; final String subtitle; final ShopCategory category; /// Warna gradasi banner, ARGB. final List gradient; const ShopPromo({ required this.id, required this.title, required this.subtitle, required this.category, required this.gradient, }); } // Sample Data DateTime _daysAgo(int days) => DateTime.now().subtract(Duration(days: days)); /// Getter, bukan `final`, supaya perubahan data langsung terbaca saat hot /// reload (variabel global yang sudah terisi tidak diisi ulang). List get shopPromoSamples => const [ ShopPromo( id: 'sp1', title: 'Diskon s.d. 20% Makanan Beku', subtitle: 'Stok bakso & dimsum di rumah', category: ShopCategory.frozen, gradient: [0xFFD90000, 0xFF990000], ), ShopPromo( id: 'sp2', title: 'Hampers Mulai Rp 299 Ribu', subtitle: 'Kirim rasa Nusantara untuk orang tersayang', category: ShopCategory.hampers, gradient: [0xFF43A047, 0xFF1B5E20], ), ShopPromo( id: 'sp3', title: 'Merchandise Diskon s.d. 15%', subtitle: 'Tumbler, kaos, dan tote bag Enaklo', category: ShopCategory.merch, gradient: [0xFFF59E0B, 0xFFC2410C], ), ]; List get shopSamples => [ ShopProduct( id: 's1', name: 'Bakso Sapi Frozen Bakso 343', category: ShopCategory.frozen, price: 65000, discountPrice: 52000, emoji: '🍲', tint: 0xFFF6D5D0, unit: 'Isi 25 butir', variantLabel: 'Ukuran', variants: ['Isi 25 butir', 'Isi 50 butir'], description: 'Bakso sapi resep Bakso 343, dibekukan segera setelah dibuat. Cukup ' 'rebus 5 menit. Tahan 3 bulan di freezer.', soldCount: 320, stock: 48, tag: ShopTag.bestSeller, addedAt: _daysAgo(60), ), ShopProduct( id: 's2', name: 'Dimsum Ayam Frozen', category: ShopCategory.frozen, price: 48000, emoji: '🥟', tint: 0xFFF3E6CF, unit: 'Isi 20 pcs', description: 'Dimsum ayam udang dengan kulit tipis. Kukus 10 menit dari beku, ' 'sajikan dengan sambal.', soldCount: 85, stock: 30, tag: ShopTag.newArrival, addedAt: _daysAgo(5), ), ShopProduct( id: 's3', name: 'Sambal Woku Pedas', category: ShopCategory.sauce, price: 35000, discountPrice: 29000, emoji: '🌶️', tint: 0xFFFBDCC8, unit: '200 g', variantLabel: 'Level pedas', variants: ['Level 2', 'Level 3', 'Level 5'], description: 'Sambal khas Woku Pedas dengan cabai, kemangi, dan rempah Manado. ' 'Tanpa pengawet, simpan di kulkas setelah dibuka.', soldCount: 540, stock: 120, tag: ShopTag.bestSeller, addedAt: _daysAgo(90), ), ShopProduct( id: 's4', name: 'Bumbu Rica-Rica Instan', category: ShopCategory.sauce, price: 18000, emoji: '🧂', tint: 0xFFF7E2C8, unit: '100 g', description: 'Bumbu rica-rica siap pakai untuk 1 kg ayam atau ikan. Tinggal tumis ' 'dan masak bersama bahan utama.', soldCount: 140, stock: 75, addedAt: _daysAgo(40), ), ShopProduct( id: 's5', name: 'Kopi Tumulu House Blend', category: ShopCategory.coffee, price: 85000, emoji: '☕', tint: 0xFFE8DCCF, unit: '250 g', variantLabel: 'Gilingan', variants: ['Biji utuh', 'Bubuk halus', 'Bubuk kasar'], description: 'Campuran arabika Gayo dan robusta Temanggung yang dipakai di Tumulu ' 'Coffee. Cocok untuk kopi susu maupun kopi tubruk.', soldCount: 410, stock: 64, tag: ShopTag.bestSeller, addedAt: _daysAgo(120), ), ShopProduct( id: 's6', name: 'Cold Brew Tumulu 1 Liter', category: ShopCategory.coffee, price: 75000, discountPrice: 65000, emoji: '🧋', tint: 0xFFE2D6CC, unit: '1 liter', description: 'Kopi seduh dingin 18 jam, tinggal tuang ke es dan susu. Simpan di ' 'kulkas, habiskan dalam 7 hari.', soldCount: 95, stock: 20, addedAt: _daysAgo(20), ), ShopProduct( id: 's7', name: 'Ramen Kit Shoyu Ramenmulu', category: ShopCategory.noodle, price: 79000, discountPrice: 69000, emoji: '🍜', tint: 0xFFF5E1C8, unit: '2 porsi', description: 'Mie ramen segar, kuah shoyu pekat, chashu, dan telur ajitama untuk ' '2 porsi. Siap dalam 10 menit.', soldCount: 150, stock: 18, tag: ShopTag.newArrival, addedAt: _daysAgo(3), ), ShopProduct( id: 's8', name: 'Mie Ramen Kering', category: ShopCategory.noodle, price: 32000, emoji: '🍝', tint: 0xFFF4EBD3, unit: '500 g', description: 'Mie ramen kering untuk 5 porsi, kenyal seperti mie segar. Rebus ' '3 menit.', soldCount: 60, stock: 90, addedAt: _daysAgo(30), ), ShopProduct( id: 's9', name: 'Keripik Kulit Ikan Pedas', category: ShopCategory.snack, price: 28000, emoji: '🍘', tint: 0xFFF6E7C1, unit: '100 g', description: 'Keripik kulit ikan renyah dengan bumbu woku pedas. Camilan pas ' 'teman nonton.', soldCount: 210, stock: 55, addedAt: _daysAgo(50), ), ShopProduct( id: 's10', name: 'Nastar Keju Premium', category: ShopCategory.snack, price: 95000, discountPrice: 85000, emoji: '🍪', tint: 0xFFF7E4B5, unit: 'Toples 500 g', description: 'Nastar selai nanas homemade dengan taburan keju edam. Tahan 1 bulan ' 'dalam toples tertutup.', soldCount: 130, stock: 25, addedAt: _daysAgo(15), ), ShopProduct( id: 's11', name: 'Tumbler Enaklo 500 ml', category: ShopCategory.merch, price: 129000, emoji: '🥤', tint: 0xFFF3D3D3, unit: '500 ml', variantLabel: 'Warna', variants: ['Merah', 'Hitam', 'Krem'], description: 'Tumbler stainless dua lapis yang menjaga minuman tetap dingin sampai ' '12 jam. Tutup anti tumpah.', soldCount: 75, stock: 40, tag: ShopTag.bestSeller, addedAt: _daysAgo(70), ), ShopProduct( id: 's12', name: 'Kaos "Enak Lho!"', category: ShopCategory.merch, price: 119000, emoji: '👕', tint: 0xFFE9E9E9, unit: 'Katun combed 30s', variantLabel: 'Ukuran', variants: ['S', 'M', 'L', 'XL'], description: 'Kaos katun yang adem dipakai seharian, dengan sablon "Enak Lho!" di ' 'bagian depan.', soldCount: 48, stock: 32, addedAt: _daysAgo(35), ), ShopProduct( id: 's13', name: 'Tote Bag Kanvas Enaklo', category: ShopCategory.merch, price: 90000, discountPrice: 76500, emoji: '🛍️', tint: 0xFFEDE3CF, unit: '38 × 42 cm', variantLabel: 'Warna', variants: ['Natural', 'Hitam'], description: 'Tote bag kanvas tebal dengan kantong dalam. Cukup untuk laptop 14 ' 'inci.', soldCount: 66, stock: 3, tag: ShopTag.newArrival, addedAt: _daysAgo(8), ), ShopProduct( id: 's14', name: 'Hampers Rasa Nusantara', category: ShopCategory.hampers, price: 350000, discountPrice: 299000, emoji: '🎁', tint: 0xFFDCEBD6, unit: 'Isi 5 produk', description: 'Sambal Woku Pedas, Kopi Tumulu House Blend, Nastar Keju Premium, ' 'Keripik Kulit Ikan Pedas, dan kartu ucapan dalam kotak kayu.', soldCount: 34, stock: 12, tag: ShopTag.newArrival, addedAt: _daysAgo(6), ), ];