import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import '../../data/api/report_data_source.dart'; import '../../data/content_providers.dart'; import '../../data/models/models.dart'; import '../../routing/app_routes.dart'; import '../../theme/wise_tokens.dart'; import '../../widgets/app_card.dart'; import '../../widgets/badges.dart'; import '../../widgets/states.dart'; class InstitutionsPage extends HookConsumerWidget { const InstitutionsPage({required this.dataSource, super.key}); final ReportDataSource dataSource; @override Widget build(BuildContext context, WidgetRef ref) { final snapshot = ref.watch(institutionsProvider); return snapshot.when( loading: () => const LoadingState(), error: (error, _) => ErrorState( message: error.toString(), onRetry: () => ref.invalidate(institutionsProvider), ), data: (items) { final sorted = [...items] ..sort((a, b) => b.reportCount.compareTo(a.reportCount)); if (sorted.isEmpty) { return const EmptyState( title: '暂无机构信息', message: '稍后再试', icon: Icons.account_balance_outlined, ); } return ListView( padding: const EdgeInsets.all(WiseSpacing.x4), children: [ Text('研报来源机构', style: Theme.of(context).textTheme.titleLarge), const SizedBox(height: WiseSpacing.x3), for (final item in sorted) ...[ InstitutionCard( institution: item, onTap: () => openInstitutionDetail( context, dataSource, item.id, ), ), const SizedBox(height: WiseSpacing.x3), ], ], ); }, ); } } class InstitutionCard extends StatelessWidget { const InstitutionCard({required this.institution, required this.onTap, super.key}); final Institution institution; final VoidCallback onTap; @override Widget build(BuildContext context) { final initials = institution.nameCn.isEmpty ? '研' : institution.nameCn.characters.take(2).toString(); return AppCard( onTap: onTap, child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ CircleAvatar( radius: 25, backgroundColor: WiseColors.secondary200, foregroundColor: WiseColors.primary, child: Text( initials, style: const TextStyle(fontWeight: FontWeight.w800), ), ), const SizedBox(width: WiseSpacing.x3), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( institution.nameCn, style: Theme.of(context).textTheme.titleMedium, ), if (institution.nameEn.isNotEmpty) Text( institution.nameEn, maxLines: 1, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.bodySmall, ), const SizedBox(height: WiseSpacing.x2), Wrap( spacing: WiseSpacing.x2, runSpacing: WiseSpacing.x2, children: [ if (institution.institutionType.isNotEmpty) AppBadge(text: institution.institutionType), for (final topic in institution.coveredTopics.take(3)) AppBadge(text: topic, kind: BadgeKind.brand), ], ), ], ), ), const SizedBox(width: WiseSpacing.x2), Column( children: [ Text( '${institution.reportCount}', style: Theme.of(context).textTheme.titleMedium?.copyWith( color: WiseColors.primary, ), ), Text('份研报', style: Theme.of(context).textTheme.bodySmall), ], ), ], ), ); } }