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/error_view.dart'; import '../../core/api/api_client.dart'; import 'surat_provider.dart'; class SuratDetailScreen extends ConsumerWidget { final int id; const SuratDetailScreen({super.key, required this.id}); @override Widget build(BuildContext context, WidgetRef ref) { final async = ref.watch(suratDetailProvider(id)); return async.when( loading: () => const Scaffold(body: Center(child: CircularProgressIndicator())), error: (e, _) => Scaffold(appBar: AppBar(), body: ErrorView(message: e.toString(), onRetry: () => ref.invalidate(suratDetailProvider(id)))), data: (surat) => Scaffold( appBar: AppBar( title: const Text('Letter Detail'), actions: [ IconButton( icon: const Icon(Icons.edit_outlined), onPressed: () async { await context.push('/surat/$id/edit'); ref.invalidate(suratDetailProvider(id)); }, ), ], ), body: Column( children: [ // Status banner Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), color: surat.isApproved ? AppColors.primaryLight : AppColors.warningLight, child: Row(children: [ Icon( surat.isApproved ? Icons.check_circle_outline : Icons.hourglass_top_outlined, size: 16, color: surat.isApproved ? AppColors.primaryDark : const Color(0xFFB45309), ), const SizedBox(width: 8), Text( surat.isApproved ? 'This letter has been approved' : 'Pending approval', style: TextStyle( fontSize: 13, fontWeight: FontWeight.w600, color: surat.isApproved ? AppColors.primaryDark : const Color(0xFFB45309), ), ), ]), ), Expanded( child: ListView( padding: const EdgeInsets.all(16), children: [ _card(Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _info('Letter No.', surat.noSurat), _info('Subject', surat.subject), if (surat.perihal != null) _info('Notes', surat.perihal!), if (surat.tanggal != null) _info('Date', DateFormat('d MMMM yyyy').format(surat.tanggal!)), ], )), const SizedBox(height: 12), if (surat.body != null && surat.body!.isNotEmpty) _card(Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('Letter Content', style: TextStyle(fontWeight: FontWeight.w700, fontSize: 13)), const Divider(height: 16), Text(surat.body!.replaceAll(RegExp(r'<[^>]*>'), ''), style: const TextStyle(fontSize: 14, color: AppColors.text, height: 1.5)), ], )), const SizedBox(height: 12), if (surat.taskId != null) GestureDetector( onTap: () => context.push('/tasks/${surat.taskId}'), child: Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: AppColors.blueLight, borderRadius: BorderRadius.circular(10), border: Border.all(color: AppColors.blue.withOpacity(0.3)), ), child: Row(children: [ const Icon(Icons.link, size: 15, color: AppColors.blue), const SizedBox(width: 8), Text('Linked to Task #${surat.taskId}', style: const TextStyle(color: AppColors.blue, fontSize: 13, fontWeight: FontWeight.w600)), const Spacer(), const Icon(Icons.chevron_right, color: AppColors.blue), ]), ), ), const SizedBox(height: 80), ], ), ), // Bottom action bar (approve/reject) if (!surat.isApproved) Container( padding: const EdgeInsets.fromLTRB(16, 12, 16, 16 + kBottomNavigationBarHeight * 0), decoration: const BoxDecoration( color: AppColors.surface, border: Border(top: BorderSide(color: AppColors.border)), ), child: Row( children: [ Expanded( child: OutlinedButton( style: OutlinedButton.styleFrom( foregroundColor: AppColors.danger, side: const BorderSide(color: AppColors.danger), minimumSize: const Size(0, 46), ), onPressed: () async { await _confirm(context, ref, false); }, child: const Text('Reject'), ), ), const SizedBox(width: 12), Expanded( child: ElevatedButton( onPressed: () async { await _confirm(context, ref, true); }, style: ElevatedButton.styleFrom(minimumSize: const Size(0, 46)), child: const Text('Approve'), ), ), ], ), ), if (surat.isApproved) Padding( padding: const EdgeInsets.fromLTRB(16, 8, 16, 16), child: OutlinedButton( style: OutlinedButton.styleFrom( foregroundColor: AppColors.danger, side: const BorderSide(color: AppColors.danger), minimumSize: const Size(double.infinity, 46), ), onPressed: () async { await _confirm(context, ref, false); }, child: const Text('Revoke Approval'), ), ), ], ), ), ); } Future _confirm(BuildContext context, WidgetRef ref, bool approve) async { try { if (approve) { await approveSurat(id); } else { await unapproveSurat(id); } ref.invalidate(suratDetailProvider(id)); } on ApiException catch (e) { if (context.mounted) ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(e.message), backgroundColor: AppColors.danger)); } } Widget _card(Widget child) => Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(12), border: Border.all(color: AppColors.border), ), child: child, ); Widget _info(String label, String value) => Padding( padding: const EdgeInsets.only(bottom: 8), child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(width: 110, child: Text(label, style: const TextStyle(fontSize: 13, color: AppColors.textSub))), Expanded(child: Text(value, style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: AppColors.text))), ]), ); }