import 'package:flutter/material.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; import '../../data/models/models.dart'; import '../../theme/app_icons.dart'; import '../../theme/yanting_text.dart'; import '../../theme/wise_tokens.dart'; import '../../widgets/app_buttons.dart'; import '../../widgets/app_card.dart'; import '../../widgets/badges.dart'; class ReportCardWidget extends StatelessWidget { const ReportCardWidget({ required this.report, required this.onTap, this.hero = false, this.onInstitutionTap, this.onPlayTap, super.key, }); final ReportCardModel report; final VoidCallback onTap; final bool hero; final VoidCallback? onInstitutionTap; final VoidCallback? onPlayTap; @override Widget build(BuildContext context) { final colors = ShadTheme.of(context).colorScheme; final child = Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Wrap( spacing: hero ? WiseSpacing.x2 : 7, runSpacing: hero ? WiseSpacing.x2 : 7, children: [ AppBadge(text: report.interpretationLabel, kind: BadgeKind.brand), if (report.hasAudio) const AppBadge( text: '音频', icon: AppIcons.play, kind: BadgeKind.audio, ), if (report.sourceTier.isNotEmpty) AppBadge(text: report.sourceTier, kind: BadgeKind.tier), for (final topic in report.topics.take(3)) AppBadge(text: topic), ], ), SizedBox(height: hero ? WiseSpacing.x3 : 10), Text( report.titleCn, maxLines: hero ? 3 : 2, overflow: TextOverflow.ellipsis, style: hero ? YantingText.sectionTitle.copyWith(fontSize: 21, height: 1.4) : YantingText.listTitle.copyWith( fontSize: 17.5, height: 1.38, fontWeight: FontWeight.w700, ), ), if (report.oneLiner.isNotEmpty) ...[ SizedBox(height: hero ? WiseSpacing.x2 : 7), Text( report.oneLiner, maxLines: 2, overflow: TextOverflow.ellipsis, style: YantingText.body.copyWith( color: colors.mutedForeground, fontSize: hero ? null : 14, ), ), ], SizedBox(height: hero ? WiseSpacing.x3 : 10), Wrap( crossAxisAlignment: WrapCrossAlignment.center, spacing: 8, runSpacing: 8, children: [ InkWell( onTap: onInstitutionTap, child: Text( report.institution.nameCn, maxLines: 1, overflow: TextOverflow.ellipsis, style: YantingText.meta.copyWith( color: colors.foreground, fontWeight: FontWeight.w500, ), ), ), if (report.releasedAt != null) ...[ const _MetaDot(), Text(formatDate(report.releasedAt), style: YantingText.meta), ], ], ), if (report.hasAudio) ...[ const SizedBox(height: 14), AppButton( label: '听研报', icon: AppIcons.play, kind: hero ? AppButtonKind.primary : AppButtonKind.accent, compact: !hero, onPressed: onPlayTap, ), ], ], ); return hero ? HeroReportCard(onTap: onTap, child: child) : AppCard( onTap: onTap, padding: const EdgeInsets.all(16), child: child, ); } } class _MetaDot extends StatelessWidget { const _MetaDot(); @override Widget build(BuildContext context) { final colors = ShadTheme.of(context).colorScheme; return Container( width: 3, height: 3, decoration: BoxDecoration( color: colors.mutedForeground, shape: BoxShape.circle, ), ); } }