import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; import 'package:intl/intl.dart'; class RiwayatBookingPage extends StatefulWidget { final String token; const RiwayatBookingPage({super.key, required this.token}); @override State createState() => _RiwayatBookingPageState(); } class _RiwayatBookingPageState extends State { Map> groupedBookings = {}; bool loading = true; @override void initState() { super.initState(); fetchBookings(); } Future fetchBookings() async { setState(() => loading = true); try { final response = await http.get( Uri.parse('http://angeliasalon.my.id/api/bookings'), headers: { 'Authorization': 'Bearer ${widget.token}', 'Accept': 'application/json', }, ); if (response.statusCode == 200) { final data = json.decode(response.body); List bookings = data is List ? data : data['bookings'] ?? []; // Kelompokkan berdasarkan tanggal_booking Map> tempGrouped = {}; for (var booking in bookings) { String tanggal = booking['tanggal_booking']; if (!tempGrouped.containsKey(tanggal)) { tempGrouped[tanggal] = []; } tempGrouped[tanggal]!.add(booking); } setState(() { groupedBookings = tempGrouped; }); } else { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Gagal mengambil riwayat booking')), ); } } catch (e) { print(e); } setState(() => loading = false); } @override Widget build(BuildContext context) { final primaryColor = const Color(0xFFF06292); final formatCurrency = NumberFormat.currency(locale: 'id_ID', symbol: 'Rp ', decimalDigits: 0); return Scaffold( appBar: AppBar( title: const Text('Riwayat Booking'), backgroundColor: primaryColor, ), body: loading ? const Center(child: CircularProgressIndicator()) : groupedBookings.isEmpty ? const Center(child: Text('Tidak ada riwayat booking')) : ListView( padding: const EdgeInsets.all(12), children: groupedBookings.entries.map((entry) { String tanggal = entry.key; List bookings = entry.value; int totalHarga = 0; return Card( margin: const EdgeInsets.only(bottom: 16), elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '📅 Tanggal Booking: $tanggal', style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.black87, ), ), const SizedBox(height: 12), Table( columnWidths: const { 0: FlexColumnWidth(2), // Layanan 1: FlexColumnWidth(2), // Jam (lebih kecil) 2: FlexColumnWidth(2.5), // Status (lebih lebar) 3: FlexColumnWidth(2.5), // Harga }, border: TableBorder.all(color: Colors.grey.shade300), children: [ const TableRow( decoration: BoxDecoration(color: Color(0xFFF8BBD0)), children: [ Padding( padding: EdgeInsets.all(8.0), child: Text('Layanan', style: TextStyle(fontWeight: FontWeight.bold)), ), Padding( padding: EdgeInsets.all(8.0), child: Text('Jam', style: TextStyle(fontWeight: FontWeight.bold)), ), Padding( padding: EdgeInsets.all(8.0), child: Text('Status', style: TextStyle(fontWeight: FontWeight.bold)), ), Padding( padding: EdgeInsets.all(8.0), child: Text('Harga', style: TextStyle(fontWeight: FontWeight.bold)), ), ], ), ...bookings.map((booking) { final service = booking['service']; final name = service['name']; final jam = booking['jam']; final status = booking['status']; final price = int.tryParse(service['price'].toString()) ?? 0; totalHarga += price; return TableRow( children: [ Padding( padding: const EdgeInsets.all(8.0), child: Text(name), ), Padding( padding: const EdgeInsets.all(8.0), child: Text(jam), ), Padding( padding: const EdgeInsets.all(8.0), child: Text(status), ), Padding( padding: const EdgeInsets.all(8.0), child: Text(formatCurrency.format(price)), ), ], ); }).toList(), ], ), const SizedBox(height: 12), Align( alignment: Alignment.centerRight, child: Text( 'Total Harga: ${formatCurrency.format(totalHarga)}', style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 14, ), ), ), ], ), ), ); }).toList(), ), ); } }