import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart'; import '../../core/theme/app_theme.dart'; import '../../core/widgets/empty_state.dart'; import '../../core/widgets/error_view.dart'; import '../../shared/models/surat.dart'; import 'surat_provider.dart'; class SuratListScreen extends ConsumerStatefulWidget { const SuratListScreen({super.key}); @override ConsumerState createState() => _SuratListScreenState(); } class _SuratListScreenState extends ConsumerState { String _filter = 'all'; final _searchCtrl = TextEditingController(); @override void initState() { super.initState(); _searchCtrl.addListener(_reload); } @override void dispose() { _searchCtrl.removeListener(_reload); _searchCtrl.dispose(); super.dispose(); } void _reload() { ref.read(suratListProvider.notifier).load(filter: _filter, search: _searchCtrl.text); } void _setFilter(String f) { setState(() => _filter = f); ref.read(suratListProvider.notifier).load(filter: f, search: _searchCtrl.text); } @override Widget build(BuildContext context) { final state = ref.watch(suratListProvider); return Scaffold( appBar: AppBar(title: const Text('Letters')), body: Column( children: [ Padding( padding: const EdgeInsets.fromLTRB(16, 12, 16, 8), child: TextField( controller: _searchCtrl, decoration: const InputDecoration( hintText: 'Search letters...', prefixIcon: Icon(Icons.search, color: AppColors.textSub), ), ), ), SizedBox( height: 40, child: ListView( scrollDirection: Axis.horizontal, padding: const EdgeInsets.symmetric(horizontal: 16), children: [ for (final (val, label) in [('all', 'All'), ('pending', 'Pending'), ('approved', 'Approved')]) Padding( padding: const EdgeInsets.only(right: 8), child: ChoiceChip( label: Text(label, style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: _filter == val ? Colors.white : AppColors.textSub, )), selected: _filter == val, selectedColor: AppColors.primary, backgroundColor: AppColors.surface, side: BorderSide(color: _filter == val ? AppColors.primary : AppColors.border), onSelected: (_) => _setFilter(val), ), ), ], ), ), const SizedBox(height: 8), Expanded( child: state.when( loading: () => const Center(child: CircularProgressIndicator()), error: (e, _) => ErrorView( message: e.toString(), onRetry: () => ref.read(suratListProvider.notifier).load(), ), data: (paged) { if (paged.items.isEmpty) return EmptyState( message: 'No letters', icon: Icons.mail_outline, actionLabel: 'Create Letter', onAction: () => context.push('/surat/create'), ); return RefreshIndicator( color: AppColors.primary, onRefresh: () async => ref.read(suratListProvider.notifier).load( filter: _filter, search: _searchCtrl.text), child: ListView.separated( padding: const EdgeInsets.fromLTRB(16, 0, 16, 100), itemCount: paged.items.length, separatorBuilder: (_, __) => const SizedBox(height: 8), itemBuilder: (_, i) => _SuratCard(surat: paged.items[i]), ), ); }, ), ), ], ), floatingActionButton: FloatingActionButton( onPressed: () async { await context.push('/surat/create'); if (mounted) ref.read(suratListProvider.notifier).load(filter: _filter); }, child: const Icon(Icons.add), ), ); } } class _SuratCard extends StatelessWidget { final Surat surat; const _SuratCard({required this.surat}); @override Widget build(BuildContext context) { final borderColor = surat.isApproved ? AppColors.primary : AppColors.warning; return GestureDetector( onTap: () => context.push('/surat/${surat.id}'), child: Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(12), border: Border.all(color: AppColors.border), ), child: Row( children: [ Container(width: 4, height: 52, decoration: BoxDecoration( color: borderColor, borderRadius: BorderRadius.circular(2))), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(surat.noSurat, style: const TextStyle(fontWeight: FontWeight.w700, fontSize: 13, color: AppColors.text)), const SizedBox(height: 3), Text(surat.subject, style: const TextStyle(fontSize: 13, color: AppColors.textSub), maxLines: 1, overflow: TextOverflow.ellipsis), if (surat.tanggal != null) ...[ const SizedBox(height: 3), Text(DateFormat('d MMM yyyy', 'id').format(surat.tanggal!), style: const TextStyle(fontSize: 11, color: AppColors.textSub)), ], ], ), ), Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: surat.isApproved ? AppColors.primaryLight : AppColors.warningLight, borderRadius: BorderRadius.circular(999), ), child: Text(surat.statusLabel, style: TextStyle( fontSize: 10, fontWeight: FontWeight.w600, color: surat.isApproved ? AppColors.primaryDark : const Color(0xFFB45309), )), ), ], ), ), ); } }