import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import '../../data/api/report_data_source.dart'; import '../../data/models/models.dart'; import '../../routing/app_routes.dart'; import '../../theme/wise_tokens.dart'; import '../../widgets/app_buttons.dart'; import '../../widgets/app_card.dart'; import '../../widgets/badges.dart'; import '../../widgets/sheets.dart'; import '../../widgets/states.dart'; import '../shared/report_card_widget.dart'; class InstitutionDetailPage extends HookConsumerWidget { const InstitutionDetailPage({ required this.institutionId, required this.dataSource, super.key, }); final String institutionId; final ReportDataSource dataSource; @override Widget build(BuildContext context, WidgetRef ref) { final retryCount = useState(0); final future = useMemoized( () => dataSource.institutionDetail(institutionId), [dataSource, institutionId, retryCount.value], ); final snapshot = useFuture(future); return Scaffold( appBar: AppBar(title: const Text('机构主页')), body: snapshot.connectionState != ConnectionState.done ? const LoadingState() : snapshot.hasError ? ErrorState( message: snapshot.error.toString(), onRetry: () => retryCount.value++, ) : _InstitutionDetailContent( item: snapshot.data!, dataSource: dataSource, ), ); } } class _InstitutionDetailContent extends StatelessWidget { const _InstitutionDetailContent({ required this.item, required this.dataSource, }); final Institution item; final ReportDataSource dataSource; @override Widget build(BuildContext context) { return ListView( padding: const EdgeInsets.all(WiseSpacing.x4), children: [ AppCard( color: WiseColors.secondary200, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(item.nameCn, style: Theme.of(context).textTheme.headlineSmall), if (item.nameEn.isNotEmpty) Text(item.nameEn, style: Theme.of(context).textTheme.bodyMedium), const SizedBox(height: WiseSpacing.x3), Wrap( spacing: WiseSpacing.x2, runSpacing: WiseSpacing.x2, children: [ AppBadge( text: item.sourceTier, icon: Icons.verified_outlined, kind: BadgeKind.tier, ), AppBadge( text: '${item.reportCount} 份研报', kind: BadgeKind.brand, ), for (final topic in item.coveredTopics) AppBadge(text: topic), ], ), ], ), ), const SizedBox(height: WiseSpacing.x3), if (item.introCn.isNotEmpty) AppCard( child: Text(item.introCn, style: Theme.of(context).textTheme.bodyMedium), ), const SizedBox(height: WiseSpacing.x3), if (item.credibilityNote.isNotEmpty) AppCard( child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Icon(Icons.verified_user_outlined, color: WiseColors.positive), const SizedBox(width: WiseSpacing.x2), Expanded( child: Text( item.credibilityNote, style: Theme.of(context).textTheme.bodyMedium, ), ), ], ), ), const SizedBox(height: WiseSpacing.x5), Text('最新研报', style: Theme.of(context).textTheme.titleMedium), const SizedBox(height: WiseSpacing.x3), if (item.recentReports.isEmpty) const EmptyState( title: '机构暂无研报', message: '稍后再试', icon: Icons.article_outlined, ) else for (final report in item.recentReports) ...[ ReportCardWidget( report: report, onTap: () => openReportDetail(context, dataSource, report), ), const SizedBox(height: WiseSpacing.x3), ], AppButton( label: '了解相关服务', icon: Icons.open_in_new, kind: AppButtonKind.ghost, expand: true, onPressed: () => showOutboundSheet(context, title: item.nameCn), ), ], ); } }