import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:device_preview/device_preview.dart'; import 'package:flutter/foundation.dart'; import 'login/login.dart'; import '../api/LoginApi.dart'; import '../absensi/absensi.dart'; import '../api/AbsensiApi.dart'; import 'models/Absensi_model.dart'; import 'tugas/Penugasan.dart'; import 'tugas/Progress.dart'; import '../api/PenugasanApi.dart'; import 'models/Penugasan_model.dart'; import 'keuangan/FinanceMain.dart'; import 'profil/Profil.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:intl/intl.dart'; import 'package:intl/date_symbol_data_local.dart'; // ── Palette (konsisten dengan login screen) ────────────────────────────────── const _bg = Color(0xFFF9FAFB); const _bg1 = Color(0xFFFFFFFF); const _bg2 = Color(0xFFF3F4F6); const _green = Color(0xFF10B981); const _greenDim = Color(0x1A10B981); const _greenGlow = Color(0x4D10B981); const _cyan = Color(0xFF06B6D4); const _cyanDim = Color(0x1A06B6D4); const _amber = Color(0xFFF59E0B); const _amberDim = Color(0x1AF59E0B); const _rose = Color(0xFFEF4444); const _roseDim = Color(0x1AEF4444); const _violet = Color(0xFF8B5CF6); const _violetDim = Color(0x1A8B5CF6); const _t1 = Color(0xFF111827); const _t2 = Color(0xFF6B7280); const _t3 = Color(0xFF9CA3AF); const _line2 = Color(0xFFE5E7EB); void main() async { WidgetsFlutterBinding.ensureInitialized(); await initializeDateFormatting('id_ID', null); runApp( DevicePreview( enabled: !kReleaseMode, builder: (context) => const MyApp(), ), ); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( useInheritedMediaQuery: true, builder: DevicePreview.appBuilder, locale: DevicePreview.locale(context), debugShowCheckedModeBanner: false, title: 'PDAM Teknisi', theme: ThemeData( fontFamily: 'Roboto', brightness: Brightness.light, scaffoldBackgroundColor: _bg, primarySwatch: Colors.blue, colorScheme: ColorScheme.fromSeed( seedColor: _green, brightness: Brightness.light, primary: _green, surface: _bg1, background: _bg, ), useMaterial3: true, ), initialRoute: '/', routes: { '/': (context) => const LoginScreen(), '/dashboard': (context) => const DashboardScreen(), }, ); } } class DashboardScreen extends StatefulWidget { const DashboardScreen({super.key}); @override State createState() => _DashboardScreenState(); } class _DashboardScreenState extends State { int _selectedIndex = 0; final ApiService _apiService = ApiService(); Map? _userData; Map? _dashboardData; bool _isLoadingProfile = false; bool _isLoadingDashboard = false; @override void initState() { super.initState(); _loadUserData(); _loadDashboardData(); } Future _loadUserData() async { setState(() { _isLoadingProfile = true; }); final localUserData = await _apiService.getUserData(); if (localUserData != null) { setState(() { _userData = localUserData; }); } final result = await _apiService.getProfile(); setState(() { _isLoadingProfile = false; }); if (result['success'] == true && result['data'] != null) { setState(() { _userData = result['data']; }); } else if (result['logout'] == true) { if (mounted) { Navigator.of(context).pushNamedAndRemoveUntil('/', (route) => false); } } } Future _loadDashboardData() async { setState(() { _isLoadingDashboard = true; }); final result = await _apiService.getDashboardData(); if (mounted) { setState(() { _isLoadingDashboard = false; if (result['success'] == true) { _dashboardData = result['data']; } }); } } List get _pages => [ HomePage( userData: _userData, dashboardData: _dashboardData, isLoading: _isLoadingProfile || _isLoadingDashboard, onNavigate: _onItemTapped, ), const AbsensiScreen(), PenugasanScreen(), ProgressScreen(), const FinanceMainScreen(), ]; void _onItemTapped(int index) { setState(() { _selectedIndex = index; }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: _bg, body: _pages[_selectedIndex], bottomNavigationBar: _buildBottomNav(), ); } Widget _buildBottomNav() { final items = [ {'icon': Icons.grid_view_rounded, 'label': 'Dashboard'}, {'icon': Icons.fingerprint_rounded, 'label': 'Absensi'}, {'icon': Icons.assignment_rounded, 'label': 'Tugas'}, {'icon': Icons.trending_up_rounded, 'label': 'Progress'}, {'icon': Icons.account_balance_wallet_rounded, 'label': 'Gaji'}, ]; return Container( decoration: const BoxDecoration( color: _bg1, border: Border(top: BorderSide(color: _line2, width: 1)), ), child: SafeArea( top: false, child: Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: List.generate(items.length, (i) { final active = i == _selectedIndex; return GestureDetector( onTap: () => _onItemTapped(i), child: AnimatedContainer( duration: const Duration(milliseconds: 200), padding: const EdgeInsets.symmetric( horizontal: 14, vertical: 6), decoration: active ? BoxDecoration( color: _greenDim, borderRadius: BorderRadius.circular(12), border: Border.all( color: _green.withOpacity(0.3)), ) : null, child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon( items[i]['icon'] as IconData, size: 22, color: active ? _green : _t3, ), const SizedBox(height: 3), Text( items[i]['label'] as String, style: TextStyle( fontSize: 10, fontWeight: active ? FontWeight.w700 : FontWeight.w400, color: active ? _green : _t3, letterSpacing: active ? 0.3 : 0, ), ), ], ), ), ); }), ), ), ), ); } } class HomePage extends StatelessWidget { final Map? userData; final Map? dashboardData; final bool isLoading; final Function(int) onNavigate; const HomePage({ super.key, this.userData, this.dashboardData, this.isLoading = false, required this.onNavigate, }); Future _handleLogout(BuildContext context) async { final confirmed = await showDialog( context: context, builder: (context) => Dialog( backgroundColor: _bg1, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), side: const BorderSide(color: _line2), ), child: Padding( padding: const EdgeInsets.all(24), child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( width: 52, height: 52, decoration: BoxDecoration( color: _roseDim, borderRadius: BorderRadius.circular(14), border: Border.all(color: _rose.withOpacity(0.3)), ), child: const Icon(Icons.logout_rounded, color: _rose, size: 24), ), const SizedBox(height: 16), const Text('Konfirmasi Logout', style: TextStyle( fontSize: 17, fontWeight: FontWeight.w700, color: _t1)), const SizedBox(height: 8), const Text('Apakah Anda yakin ingin keluar?', style: TextStyle(fontSize: 13, color: _t2), textAlign: TextAlign.center), const SizedBox(height: 24), Row(children: [ Expanded( child: OutlinedButton( onPressed: () => Navigator.pop(context, false), style: OutlinedButton.styleFrom( foregroundColor: _t2, side: const BorderSide(color: _line2), padding: const EdgeInsets.symmetric(vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), ), child: const Text('Batal'), ), ), const SizedBox(width: 12), Expanded( child: ElevatedButton( onPressed: () => Navigator.pop(context, true), style: ElevatedButton.styleFrom( backgroundColor: _rose, foregroundColor: Colors.white, elevation: 0, padding: const EdgeInsets.symmetric(vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), ), child: const Text('Logout', style: TextStyle(fontWeight: FontWeight.w700)), ), ), ]), ], ), ), ), ); if (confirmed == true && context.mounted) { final apiService = ApiService(); await apiService.logout(); if (context.mounted) { Navigator.of(context).pushNamedAndRemoveUntil('/', (route) => false); } } } @override Widget build(BuildContext context) { final teknisi = userData?['teknisi']; final namaTeknisi = (teknisi?['nama'] ?? 'Teknisi') as String; final idTeknisi = teknisi?['id_teknisi'] ?? '-'; final username = userData?['username'] ?? '-'; final initial = namaTeknisi.isNotEmpty ? namaTeknisi[0].toUpperCase() : 'T'; return Scaffold( backgroundColor: _bg, appBar: AppBar( elevation: 0, backgroundColor: _bg1, title: Row(children: [ Container( width: 30, height: 30, decoration: BoxDecoration( color: _greenDim, borderRadius: BorderRadius.circular(8), border: Border.all(color: _green.withOpacity(0.35)), ), child: const Icon(Icons.water_drop_rounded, color: _green, size: 15), ), const SizedBox(width: 10), const Text('PDAM Teknisi', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w800, color: _t1, letterSpacing: 0.2)), ]), actions: [ IconButton( icon: const Icon(Icons.account_circle_rounded, color: _t2, size: 24), onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const ProfilScreen())), ), IconButton( icon: const Icon(Icons.logout_rounded, color: _rose, size: 22), onPressed: () => _handleLogout(context), ), const SizedBox(width: 8), ], ), body: RefreshIndicator( color: _green, backgroundColor: _bg1, onRefresh: () async { final apiService = ApiService(); await apiService.getProfile(); }, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), padding: const EdgeInsets.fromLTRB(20, 20, 20, 32), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // New Premium Header with Attendance Status Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Halo, $namaTeknisi!', style: const TextStyle(fontSize: 26, fontWeight: FontWeight.w900, color: _t1, letterSpacing: -1)), const SizedBox(height: 4), Row( children: [ Container(width: 8, height: 8, decoration: const BoxDecoration(color: _green, shape: BoxShape.circle)), const SizedBox(width: 8), const Text('Online & Siap Bertugas', style: TextStyle(fontSize: 12, color: _t2, fontWeight: FontWeight.w600)), ], ), ], ), ], ), const SizedBox(height: 32), // Wallet & Earnings Section (Horizontal Scroll or Compact) Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: _bg1, borderRadius: BorderRadius.circular(28), border: Border.all(color: _line2), boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.2), blurRadius: 20, offset: const Offset(0, 10))], ), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text('RINGKASAN PENDAPATAN', style: TextStyle(fontSize: 10, fontWeight: FontWeight.w800, color: _t3, letterSpacing: 1.5)), Icon(Icons.account_balance_wallet_rounded, color: _green.withOpacity(0.5), size: 18), ], ), const SizedBox(height: 20), Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('Estimasi Gaji', style: TextStyle(fontSize: 11, color: _t2, fontWeight: FontWeight.w600)), const SizedBox(height: 4), Text(_formatCurrency(dashboardData?['statistik']?['estimasi_gaji'] ?? 0), style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w900, color: _green)), ], ), ), Container(width: 1, height: 40, color: _line2), const SizedBox(width: 20), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('Kasbon Aktif', style: TextStyle(fontSize: 11, color: _t2, fontWeight: FontWeight.w600)), const SizedBox(height: 4), Text(_formatCurrency(dashboardData?['statistik']?['total_kasbon'] ?? 0), style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w900, color: _rose)), ], ), ), ], ), ], ), ), const SizedBox(height: 28), // New Performance & Statistics Section _sectionLabel('RINGKASAN KINERJA BULAN INI'), const SizedBox(height: 16), Container( padding: const EdgeInsets.all(24), decoration: BoxDecoration( color: _bg1, borderRadius: BorderRadius.circular(32), border: Border.all(color: _line2), boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.2), blurRadius: 30, offset: const Offset(0, 15))], ), child: Row( children: [ // Circular Progress Stack( alignment: Alignment.center, children: [ SizedBox( width: 86, height: 86, child: CircularProgressIndicator( value: ((dashboardData?['statistik']?['kehadiran'] ?? 0) as num) / 100.0, strokeWidth: 9, backgroundColor: _green.withOpacity(0.08), valueColor: const AlwaysStoppedAnimation(_green), strokeCap: StrokeCap.round, ), ), Column( mainAxisSize: MainAxisSize.min, children: [ Text('${dashboardData?['statistik']?['kehadiran'] ?? 0}%', style: const TextStyle(fontSize: 19, fontWeight: FontWeight.w900, color: _t1, letterSpacing: -0.5)), Text('Hadir', style: TextStyle(fontSize: 9, color: _green.withOpacity(0.6), fontWeight: FontWeight.w800, letterSpacing: 0.5)), ], ), ], ), const SizedBox(width: 24), // Stats Details Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _miniRow(Icons.check_circle_outline_rounded, _green, 'Tugas Selesai', '${dashboardData?['statistik']?['tugas_selesai'] ?? 0} Item'), const SizedBox(height: 12), _miniRow(Icons.timer_outlined, _amber, 'Jam Kerja', '${dashboardData?['statistik']?['jam_kerja'] ?? 0} Jam'), const SizedBox(height: 12), _miniRow(Icons.trending_up_rounded, _cyan, 'Efisiensi', '+${dashboardData?['statistik']?['efisiensi'] ?? 0}%'), ], ), ), ], ), ), const SizedBox(height: 28), // Quick Actions or Status _sectionLabel('AKTIVITAS TERAKHIR'), const SizedBox(height: 16), _buildModernStatCard( 'Gaji Terakhir Diterima', _formatCurrency(dashboardData?['statistik']?['gaji_terakhir'] ?? 0), Icons.history_rounded, _cyan, isWide: true ), ], ), ), ), ); } Widget _miniRow(IconData icon, Color color, String label, String value) { return Row( children: [ Icon(icon, color: color, size: 14), const SizedBox(width: 8), Text(label, style: const TextStyle(fontSize: 11, color: _t2, fontWeight: FontWeight.w500)), const Spacer(), Text(value, style: const TextStyle(fontSize: 11, fontWeight: FontWeight.w800, color: _t1)), ], ); } Widget _buildModernStatCard(String title, String value, IconData icon, Color color, {bool isWide = false}) { return Container( width: double.infinity, padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: _bg1, borderRadius: BorderRadius.circular(24), border: Border.all(color: _line2), boxShadow: [ BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: 20, offset: const Offset(0, 10)) ], ), child: isWide ? Row( children: [ Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration(color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(14)), child: Icon(icon, color: color, size: 22), ), const SizedBox(width: 16), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, style: const TextStyle(fontSize: 10, fontWeight: FontWeight.w700, color: _t3, letterSpacing: 0.5)), const SizedBox(height: 4), Text(value, style: TextStyle(fontSize: 18, fontWeight: FontWeight.w900, color: color)), ], ), ], ) : Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration(color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(12)), child: Icon(icon, color: color, size: 20), ), const SizedBox(height: 20), Text(value, style: TextStyle(fontSize: 18, fontWeight: FontWeight.w900, color: color)), const SizedBox(height: 4), Text(title, style: const TextStyle(fontSize: 10, fontWeight: FontWeight.w700, color: _t3)), ], ), ); } Widget _pill(String text, Color bg, Color fg) { return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( color: bg, borderRadius: BorderRadius.circular(99), border: Border.all(color: fg.withOpacity(0.25)), ), child: Text(text, style: TextStyle(fontSize: 10, fontWeight: FontWeight.w600, color: fg)), ); } Widget _sectionLabel(String label) { return Text(label, style: const TextStyle(fontSize: 10, fontWeight: FontWeight.w700, color: _t3, letterSpacing: 1.4)); } Widget _buildStatCard(String title, String value, IconData icon, Color color, Color dimColor) { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: _bg1, borderRadius: BorderRadius.circular(14), border: Border.all(color: _line2), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 34, height: 34, decoration: BoxDecoration( color: dimColor, borderRadius: BorderRadius.circular(9), border: Border.all(color: color.withOpacity(0.25)), ), child: Icon(icon, color: color, size: 17), ), const SizedBox(height: 10), Text(value, style: TextStyle(fontSize: 22, fontWeight: FontWeight.w800, color: color, letterSpacing: -0.5)), const SizedBox(height: 2), Text(title, style: const TextStyle(fontSize: 11, color: _t3, fontWeight: FontWeight.w500)), ], ), ); } Widget _buildMenuCard(String title, IconData icon, Color color, Color dimColor, VoidCallback onTap) { return Material( color: _bg1, borderRadius: BorderRadius.circular(14), child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(14), child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration(borderRadius: BorderRadius.circular(14), border: Border.all(color: _line2)), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( width: 36, height: 36, decoration: BoxDecoration(color: dimColor, borderRadius: BorderRadius.circular(10), border: Border.all(color: color.withOpacity(0.25))), child: Icon(icon, color: color, size: 18), ), Text(title, style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: _t1)), ], ), ), ), ); } String _formatCurrency(dynamic amount) { final formatter = NumberFormat.currency(locale: 'id_ID', symbol: 'Rp ', decimalDigits: 0); return formatter.format(amount ?? 0); } } class SalaryHistoryPage extends StatefulWidget { const SalaryHistoryPage({super.key}); @override State createState() => _SalaryHistoryPageState(); } class _SalaryHistoryPageState extends State { final ApiService _apiService = ApiService(); List _riwayatGaji = []; bool _isLoading = false; @override void initState() { super.initState(); _fetchRiwayat(); } Future _fetchRiwayat() async { setState(() => _isLoading = true); final res = await _apiService.getGajiRiwayat(); if (mounted) { setState(() { _isLoading = false; if (res['success'] == true) { _riwayatGaji = res['data'] ?? []; } }); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: _bg, appBar: AppBar( elevation: 0, backgroundColor: _bg1, title: const Row(children: [ Icon(Icons.account_balance_wallet_rounded, color: _amber, size: 18), SizedBox(width: 8), Text('Riwayat Gaji', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w700, color: _t1)), ]), actions: [ IconButton(onPressed: _fetchRiwayat, icon: const Icon(Icons.refresh, color: _t2)), ], ), body: _isLoading ? const Center(child: CircularProgressIndicator(color: _amber)) : _riwayatGaji.isEmpty ? const Center(child: Text('Belum ada riwayat gaji', style: TextStyle(color: _t2))) : ListView.builder( padding: const EdgeInsets.all(16), itemCount: _riwayatGaji.length, itemBuilder: (context, i) { final item = _riwayatGaji[i]; return Container( margin: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: _bg1, borderRadius: BorderRadius.circular(16), border: Border.all(color: _line2), ), child: Row( children: [ Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration(color: _amberDim, borderRadius: BorderRadius.circular(12)), child: const Icon(Icons.receipt_long_rounded, color: _amber, size: 20), ), const SizedBox(width: 16), Expanded( child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Periode: ${item['periode']}', style: const TextStyle(color: _t1, fontWeight: FontWeight.bold)), Text('Tanggal Bayar: ${item['tanggal_bayar'] ?? '-'}', style: const TextStyle(color: _t2, fontSize: 12)), ]), ), Text('Rp${item['gaji_bersih']}', style: const TextStyle(color: _green, fontWeight: FontWeight.bold, fontSize: 16)), ], ), ); }, ), ); } } class KasbonHistoryPage extends StatefulWidget { const KasbonHistoryPage({super.key}); @override State createState() => _KasbonHistoryPageState(); } class _KasbonHistoryPageState extends State { final ApiService _apiService = ApiService(); List _riwayat = []; bool _isLoading = false; @override void initState() { super.initState(); _fetch(); } Future _fetch() async { setState(() => _isLoading = true); final res = await _apiService.getKasbonRiwayat(); if (mounted) { setState(() { _isLoading = false; if (res['success'] == true) _riwayat = res['data'] ?? []; }); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF9FAFB), appBar: AppBar( elevation: 0, backgroundColor: const Color(0xFFFFFFFF), title: const Text('Riwayat Kasbon', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Color(0xFF111827))), ), body: _isLoading ? const Center(child: CircularProgressIndicator(color: Color(0xFFF59E0B))) : _riwayat.isEmpty ? const Center(child: Text('Belum ada riwayat kasbon', style: TextStyle(color: Color(0xFF6B7280)))) : ListView.builder( padding: const EdgeInsets.all(16), itemCount: _riwayat.length, itemBuilder: (context, i) { final item = _riwayat[i]; final bool isLunas = item['status'] == 'Lunas'; return Container( margin: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.all(16), decoration: BoxDecoration(color: const Color(0xFFFFFFFF), borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFFE5E7EB))), child: Row(children: [ Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration(color: isLunas ? const Color(0x1A10B981) : const Color(0x1AEF4444), borderRadius: BorderRadius.circular(12)), child: Icon(isLunas ? Icons.check_circle_rounded : Icons.pending_rounded, color: isLunas ? const Color(0xFF10B981) : const Color(0xFFEF4444), size: 20), ), const SizedBox(width: 16), Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Rp${item['jumlah']}', style: const TextStyle(color: Color(0xFF111827), fontWeight: FontWeight.bold)), Text(item['keterangan'] ?? 'Tanpa keterangan', style: const TextStyle(color: Color(0xFF6B7280), fontSize: 12)), Text(item['tanggal'] ?? '-', style: const TextStyle(color: Color(0xFF9CA3AF), fontSize: 11)), ])), _statusBadge(item['status']), ]), ); }, ), ); } Widget _statusBadge(String status) { final bool isLunas = status == 'Lunas'; return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration(color: isLunas ? const Color(0x1A10B981) : const Color(0x1AEF4444), borderRadius: BorderRadius.circular(8), border: Border.all(color: isLunas ? const Color(0xFF10B981).withOpacity(0.3) : const Color(0xFFEF4444).withOpacity(0.3))), child: Text(status, style: TextStyle(color: isLunas ? const Color(0xFF10B981) : const Color(0xFFEF4444), fontSize: 10, fontWeight: FontWeight.bold)), ); } }