fix(mobile): resolve laundry service price dynamically based on selectedJenisLayanan in recommendation cards and details
This commit is contained in:
parent
00dc5b4a96
commit
c04f98eadf
|
|
@ -12,6 +12,8 @@ class Laundry {
|
||||||
final String jamTutup;
|
final String jamTutup;
|
||||||
final double hargaPerKg;
|
final double hargaPerKg;
|
||||||
final double hargaKiloan;
|
final double hargaKiloan;
|
||||||
|
final double hargaHarian;
|
||||||
|
final double hargaJam;
|
||||||
final int waktuProses; // dalam jam
|
final int waktuProses; // dalam jam
|
||||||
final String? deskripsi;
|
final String? deskripsi;
|
||||||
final String? fotoUtama;
|
final String? fotoUtama;
|
||||||
|
|
@ -34,6 +36,8 @@ class Laundry {
|
||||||
required this.jamTutup,
|
required this.jamTutup,
|
||||||
required this.hargaPerKg,
|
required this.hargaPerKg,
|
||||||
required this.hargaKiloan,
|
required this.hargaKiloan,
|
||||||
|
required this.hargaHarian,
|
||||||
|
required this.hargaJam,
|
||||||
required this.waktuProses,
|
required this.waktuProses,
|
||||||
this.deskripsi,
|
this.deskripsi,
|
||||||
this.fotoUtama,
|
this.fotoUtama,
|
||||||
|
|
@ -67,23 +71,34 @@ class Laundry {
|
||||||
hargaKiloan = double.tryParse(json['harga_kiloan'].toString()) ?? 0;
|
hargaKiloan = double.tryParse(json['harga_kiloan'].toString()) ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((harga == 0 || hargaKiloan == 0) &&
|
double hargaHarian = 0;
|
||||||
json['layanan'] != null &&
|
double hargaJam = 0;
|
||||||
|
|
||||||
|
if (json['layanan'] != null &&
|
||||||
(json['layanan'] as List).isNotEmpty) {
|
(json['layanan'] as List).isNotEmpty) {
|
||||||
final layananList = json['layanan'] as List;
|
final layananList = json['layanan'] as List;
|
||||||
harga = harga > 0
|
harga = harga > 0
|
||||||
? harga
|
? harga
|
||||||
: double.tryParse(layananList.first['harga']?.toString() ?? '0') ?? 0;
|
: double.tryParse(layananList.first['harga']?.toString() ?? '0') ?? 0;
|
||||||
for (final item in layananList) {
|
for (final item in layananList) {
|
||||||
final jenis = item['jenis_layanan']?.toString().toLowerCase();
|
final jenis = item['jenis_layanan']?.toString().toLowerCase() ?? '';
|
||||||
final itemHarga =
|
final itemHarga =
|
||||||
double.tryParse(item['harga']?.toString() ?? '0') ?? 0;
|
double.tryParse(item['harga']?.toString() ?? '0') ?? 0;
|
||||||
if (jenis == 'kiloan') {
|
|
||||||
|
if (jenis == 'harian' || jenis == 'kiloan' || jenis == 'reguler') {
|
||||||
|
hargaHarian = itemHarga;
|
||||||
hargaKiloan = itemHarga;
|
hargaKiloan = itemHarga;
|
||||||
|
} else if (jenis == 'jam' || jenis == 'express' || jenis == 'kilat' || jenis == 'satuan') {
|
||||||
|
hargaJam = itemHarga;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback if not populated
|
||||||
|
if (hargaHarian == 0) hargaHarian = hargaKiloan > 0 ? hargaKiloan : harga;
|
||||||
|
if (hargaJam == 0) hargaJam = harga;
|
||||||
|
|
||||||
|
|
||||||
// Get foto from API and build gallery list
|
// Get foto from API and build gallery list
|
||||||
final List<GaleriLaundry> galleryList = [];
|
final List<GaleriLaundry> galleryList = [];
|
||||||
|
|
||||||
|
|
@ -129,6 +144,8 @@ class Laundry {
|
||||||
jamTutup: _parseTime(json['jam_tutup'], '20:00'),
|
jamTutup: _parseTime(json['jam_tutup'], '20:00'),
|
||||||
hargaPerKg: harga,
|
hargaPerKg: harga,
|
||||||
hargaKiloan: hargaKiloan,
|
hargaKiloan: hargaKiloan,
|
||||||
|
hargaHarian: hargaHarian,
|
||||||
|
hargaJam: hargaJam,
|
||||||
waktuProses: json['waktu_proses'] ?? 24,
|
waktuProses: json['waktu_proses'] ?? 24,
|
||||||
deskripsi: json['deskripsi'],
|
deskripsi: json['deskripsi'],
|
||||||
fotoUtama: json['foto_utama'],
|
fotoUtama: json['foto_utama'],
|
||||||
|
|
@ -196,7 +213,23 @@ class Laundry {
|
||||||
|
|
||||||
// Format harga dengan Rupiah
|
// Format harga dengan Rupiah
|
||||||
String get formattedHarga {
|
String get formattedHarga {
|
||||||
return 'Rp ${_formatRupiah(hargaPerKg)}';
|
return 'Rp ${_formatRupiah(hargaHarian > 0 ? hargaHarian : hargaPerKg)}';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format harga sesuai jenis layanan (harian / jam)
|
||||||
|
String formattedHargaFor(String? jenisLayanan) {
|
||||||
|
if (jenisLayanan == null || jenisLayanan.isEmpty) {
|
||||||
|
return formattedHarga;
|
||||||
|
}
|
||||||
|
|
||||||
|
final target = jenisLayanan.toLowerCase();
|
||||||
|
if (target == 'jam' || target == 'express' || target == 'kilat' || target == 'satuan') {
|
||||||
|
final val = hargaJam > 0 ? hargaJam : hargaPerKg;
|
||||||
|
return 'Rp ${_formatRupiah(val)}';
|
||||||
|
} else {
|
||||||
|
final val = hargaHarian > 0 ? hargaHarian : hargaPerKg;
|
||||||
|
return 'Rp ${_formatRupiah(val)}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _formatRupiah(double value) {
|
String _formatRupiah(double value) {
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,13 @@ import '../widgets/app_placeholder.dart';
|
||||||
|
|
||||||
class LaundryDetailScreen extends StatefulWidget {
|
class LaundryDetailScreen extends StatefulWidget {
|
||||||
final Laundry laundry;
|
final Laundry laundry;
|
||||||
|
final String? selectedJenisLayanan;
|
||||||
|
|
||||||
const LaundryDetailScreen({super.key, required this.laundry});
|
const LaundryDetailScreen({
|
||||||
|
super.key,
|
||||||
|
required this.laundry,
|
||||||
|
this.selectedJenisLayanan,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<LaundryDetailScreen> createState() => _LaundryDetailScreenState();
|
State<LaundryDetailScreen> createState() => _LaundryDetailScreenState();
|
||||||
|
|
@ -286,7 +291,7 @@ class _LaundryDetailScreenState extends State<LaundryDetailScreen> {
|
||||||
_buildHeaderChip(
|
_buildHeaderChip(
|
||||||
icon: Icons.payments_rounded,
|
icon: Icons.payments_rounded,
|
||||||
label:
|
label:
|
||||||
'${widget.laundry.formattedHargaKiloan}/kg',
|
'${widget.laundry.formattedHargaFor(widget.selectedJenisLayanan)}/kg',
|
||||||
),
|
),
|
||||||
_buildHeaderChip(
|
_buildHeaderChip(
|
||||||
icon: Icons.schedule_rounded,
|
icon: Icons.schedule_rounded,
|
||||||
|
|
@ -355,6 +360,23 @@ class _LaundryDetailScreenState extends State<LaundryDetailScreen> {
|
||||||
title: 'Harga',
|
title: 'Harga',
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
if (widget.laundry.hargaHarian > 0) ...[
|
||||||
|
_buildPriceCard(
|
||||||
|
'Laundry Kiloan (Harian/Reguler)',
|
||||||
|
widget.laundry.formattedHargaFor("harian"),
|
||||||
|
Icons.scale,
|
||||||
|
const Color(0xFF00897B),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
],
|
||||||
|
if (widget.laundry.hargaJam > 0)
|
||||||
|
_buildPriceCard(
|
||||||
|
'Laundry Express (Jam/Satuan)',
|
||||||
|
widget.laundry.formattedHargaFor("jam"),
|
||||||
|
Icons.flash_on,
|
||||||
|
const Color(0xFFFF9800),
|
||||||
|
),
|
||||||
|
if (widget.laundry.hargaHarian == 0 && widget.laundry.hargaJam == 0)
|
||||||
_buildPriceCard(
|
_buildPriceCard(
|
||||||
'Laundry Kiloan',
|
'Laundry Kiloan',
|
||||||
widget.laundry.formattedHargaKiloan,
|
widget.laundry.formattedHargaKiloan,
|
||||||
|
|
|
||||||
|
|
@ -3101,6 +3101,7 @@ class _RecommendationScreenState extends State<RecommendationScreen> {
|
||||||
laundry: Laundry.fromJson(itemData),
|
laundry: Laundry.fromJson(itemData),
|
||||||
userLatitude: _userLatitude,
|
userLatitude: _userLatitude,
|
||||||
userLongitude: _userLongitude,
|
userLongitude: _userLongitude,
|
||||||
|
selectedJenisLayanan: _selectedJenisLayanan,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ class LaundryCard extends StatelessWidget {
|
||||||
final bool showRanking;
|
final bool showRanking;
|
||||||
final double? userLatitude;
|
final double? userLatitude;
|
||||||
final double? userLongitude;
|
final double? userLongitude;
|
||||||
|
final String? selectedJenisLayanan;
|
||||||
|
|
||||||
const LaundryCard({
|
const LaundryCard({
|
||||||
super.key,
|
super.key,
|
||||||
|
|
@ -20,6 +21,7 @@ class LaundryCard extends StatelessWidget {
|
||||||
this.showRanking = false,
|
this.showRanking = false,
|
||||||
this.userLatitude,
|
this.userLatitude,
|
||||||
this.userLongitude,
|
this.userLongitude,
|
||||||
|
this.selectedJenisLayanan,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -198,7 +200,7 @@ class LaundryCard extends StatelessWidget {
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
laundry.formattedHarga,
|
laundry.formattedHargaFor(selectedJenisLayanan),
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue