import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:fl_chart/fl_chart.dart'; import '../controllers/analisis_controller.dart'; class AnalisisView extends StatelessWidget { const AnalisisView({super.key}); @override Widget build(BuildContext context) { final AnalisisController controller = Get.put(AnalisisController()); return Scaffold( extendBodyBehindAppBar: true, body: Obx(() { final monthlyData = controller.monthlyData; final topCities = controller.topCities; final selectedMonth = controller.selectedMonth.value; return Container( decoration: const BoxDecoration( gradient: LinearGradient( colors: [Color(0xFF1976D2), Color(0xFFE3F2FD)], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), ), child: SafeArea( child: Column( children: [ const SizedBox(height: 12), // 🔹 Grafik Pengiriman Bulanan Container( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(18), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Column( children: [ Row( children: const [ Icon(Icons.bar_chart, color: Color(0xFF1976D2)), SizedBox(width: 8), Text( "Pengiriman Bulanan", style: TextStyle( fontWeight: FontWeight.bold, color: Colors.black87, fontSize: 16, ), ), ], ), const SizedBox(height: 12), monthlyData.isEmpty ? const SizedBox( height: 200, child: Center( child: Text( "Belum ada data pengiriman", style: TextStyle(color: Colors.black54), ), ), ) : SizedBox( height: 220, child: BarChart( BarChartData( alignment: BarChartAlignment.spaceAround, gridData: FlGridData(show: false), borderData: FlBorderData(show: false), titlesData: FlTitlesData( leftTitles: const AxisTitles( sideTitles: SideTitles(showTitles: false), ), topTitles: const AxisTitles( sideTitles: SideTitles(showTitles: false), ), rightTitles: const AxisTitles( sideTitles: SideTitles(showTitles: false), ), bottomTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, getTitlesWidget: (value, _) { final index = value.toInt(); if (index >= 0 && index < monthlyData.length) { return Padding( padding: const EdgeInsets.only(top: 6), child: Text( monthlyData[index]['month'], style: const TextStyle( fontSize: 12, color: Colors.black87, fontWeight: FontWeight.w500, ), ), ); } return const SizedBox.shrink(); }, ), ), ), barGroups: monthlyData.asMap().entries.map((e) { final pengiriman = (e.value['pengiriman'] as num) .toDouble(); return BarChartGroupData( x: e.key, barRods: [ BarChartRodData( toY: pengiriman, gradient: const LinearGradient( colors: [ Color(0xFF1976D2), Color(0xFF64B5F6), ], begin: Alignment.bottomCenter, end: Alignment.topCenter, ), width: 18, borderRadius: BorderRadius.circular(6), ), ], ); }).toList(), ), ), ), // 🔹 Tampilkan jumlah di atas batang if (monthlyData.isNotEmpty) const SizedBox(height: 12), if (monthlyData.isNotEmpty) Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: monthlyData.map((e) { return Text( e['pengiriman'].toString(), style: const TextStyle( fontSize: 12, color: Colors.black54, fontWeight: FontWeight.w600, ), ); }).toList(), ), ], ), ), // 🔹 Top Kota Tujuan per Bulan Expanded( child: Container( width: double.infinity, margin: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(18), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.08), blurRadius: 8, offset: const Offset(0, 3), ), ], ), child: Column( children: [ Padding( padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 12), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: const [ Icon(Icons.location_city, color: Color(0xFF1976D2)), SizedBox(width: 6), Text( "Top 10 Kota Tujuan", style: TextStyle( fontWeight: FontWeight.bold, color: Colors.black87, fontSize: 16, ), ), ], ), // 🔹 Dropdown pilih bulan DropdownButton( value: selectedMonth, items: controller.monthlyData .map((e) => DropdownMenuItem( value: e['month'], child: Text(e['month']), )) .toList(), onChanged: (value) { if (value != null) { controller.setSelectedMonth(value); } }, underline: const SizedBox(), style: const TextStyle( color: Colors.black87, fontSize: 14), icon: const Icon(Icons.arrow_drop_down, color: Color(0xFF1976D2)), ), ], ), ), const Divider(height: 1, color: Color(0xFFE0E0E0)), Expanded( child: topCities.isEmpty ? const Center( child: Text( "Tidak ada data untuk bulan ini", style: TextStyle(color: Colors.black54), ), ) : ListView.separated( padding: const EdgeInsets.symmetric( horizontal: 12), itemCount: topCities.length, separatorBuilder: (_, __) => Divider( color: Colors.grey.shade200, height: 1, ), itemBuilder: (context, index) { final city = topCities[index]; return ListTile( contentPadding: const EdgeInsets.symmetric( horizontal: 8, vertical: 6), leading: CircleAvatar( backgroundColor: Colors.blue.shade50, child: Text( '${index + 1}', style: const TextStyle( color: Color(0xFF1976D2), fontWeight: FontWeight.bold, ), ), ), title: Text( city['city'], style: const TextStyle( fontWeight: FontWeight.w600, fontSize: 14, ), ), subtitle: Text( "Pengiriman: ${city['transaksi']} kali\nPendapatan: ${controller.formatRupiah(city['pendapatan'])}", style: const TextStyle(fontSize: 12), ), // trailing: const Icon( // Icons.chevron_right_rounded, // color: Colors.grey, // ), ); }, ), ), ], ), ), ), const SizedBox(height: 16), ], ), ), ); }), ); } }