import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/l10n/app_localizations.dart'; import '../../../core/navigation/broker_navigation.dart'; import '../../../core/theme/app_colors.dart'; import '../../../data/repositories/broker_repository.dart'; import '../../widgets/common/app_refresh_indicator.dart'; final _applyListProvider = FutureProvider.autoDispose>>((ref) async { final repo = ref.read(brokerRepositoryProvider); return repo.getMyApplyList(); }); class BrokerApplyScreen extends ConsumerWidget { const BrokerApplyScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final l10n = AppLocalizations.of(context)!; final cs = Theme.of(context).colorScheme; final isDark = Theme.of(context).brightness == Brightness.dark; final listAsync = ref.watch(_applyListProvider); Future refreshList() async { ref.invalidate(_applyListProvider); await ref.read(_applyListProvider.future); } return Scaffold( appBar: AppBar( title: Text( l10n.brokerApplyRecords, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600), ), centerTitle: true, ), body: listAsync.when( loading: () => const Center(child: CircularProgressIndicator()), error: (_, __) => AppRefreshIndicator( onRefresh: refreshList, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), child: SizedBox( height: MediaQuery.sizeOf(context).height * 0.6, child: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Text(l10n.loadFailed, style: TextStyle(color: cs.onSurface.withAlpha(153))), const SizedBox(height: 12), ElevatedButton( onPressed: refreshList, child: Text(l10n.retry), ), ], ), ), ), ), ), data: (list) { if (list.isEmpty) { return AppRefreshIndicator( onRefresh: refreshList, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), child: SizedBox( height: MediaQuery.sizeOf(context).height * 0.6, child: _EmptyState( l10n: l10n, cs: cs, isDark: isDark, onApply: () => showBrokerApplyDialog(context, ref).then((_) { ref.invalidate(_applyListProvider); }), ), ), ), ); } return AppRefreshIndicator( onRefresh: refreshList, child: ListView.separated( physics: const AlwaysScrollableScrollPhysics(), padding: const EdgeInsets.all(16), itemCount: list.length, separatorBuilder: (_, __) => const SizedBox(height: 12), itemBuilder: (_, i) => _ApplyCard( item: list[i], l10n: l10n, cs: cs, isDark: isDark, ), ), ); }, ), ); } } class _EmptyState extends StatelessWidget { const _EmptyState({ required this.l10n, required this.cs, required this.isDark, required this.onApply, }); final AppLocalizations l10n; final ColorScheme cs; final bool isDark; final VoidCallback onApply; @override Widget build(BuildContext context) { return Center( child: Padding( padding: const EdgeInsets.all(32), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.inbox_outlined, size: 64, color: cs.onSurface.withAlpha(60)), const SizedBox(height: 16), Text(l10n.noRecord, style: TextStyle( color: cs.onSurface.withAlpha(153), fontSize: 15)), const SizedBox(height: 24), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: onApply, style: ElevatedButton.styleFrom( backgroundColor: AppColors.brand, foregroundColor: Colors.black, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), padding: const EdgeInsets.symmetric(vertical: 14), ), child: Text( l10n.applyNow, style: const TextStyle( fontSize: 15, fontWeight: FontWeight.w600, ), ), ), ), ], ), ), ); } } class _ApplyCard extends StatelessWidget { const _ApplyCard( {required this.item, required this.l10n, required this.cs, required this.isDark}); final Map item; final AppLocalizations l10n; final ColorScheme cs; final bool isDark; @override Widget build(BuildContext context) { final status = item['auditStatus']; // 0=待审核, 1=审核失败, 2=审核通过 final isPending = isBrokerApplyPending(status); final isApproved = status == 2 || status == 'AUDIT_SUCCESS'; final isRejected = status == 1 || status == 'AUDIT_DEFEATED'; final statusText = isApproved ? l10n.auditStatusApproved : isPending ? l10n.auditStatusPending : l10n.auditStatusRejected; final statusColor = isApproved ? AppColors.rise : isPending ? AppColors.brand : cs.error; final statusBg = isApproved ? AppColors.rise.withAlpha(25) : isPending ? AppColors.brand.withAlpha(25) : cs.error.withAlpha(25); final createTime = item['createTime']?.toString() ?? ''; final rejectReason = item['rejectReason']?.toString() ?? ''; return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: isDark ? AppColors.darkBgSecondary : AppColors.lightBgSecondary, borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: Text( l10n.brokerApplyTitle, style: TextStyle( color: cs.onSurface, fontSize: 15, fontWeight: FontWeight.w600), ), ), Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: statusBg, borderRadius: BorderRadius.circular(12), ), child: Text( statusText, style: TextStyle( color: statusColor, fontSize: 12, fontWeight: FontWeight.w600), ), ), ], ), if (createTime.isNotEmpty) ...[ const SizedBox(height: 8), Text('${l10n.applyTime}: $createTime', style: TextStyle(color: cs.onSurface.withAlpha(120), fontSize: 13)), ], if (isRejected && rejectReason.isNotEmpty) ...[ const SizedBox(height: 8), Text('${l10n.rejectReasonLabel}: $rejectReason', style: TextStyle(color: cs.error, fontSize: 13)), ], ], ), ); } }