import 'package:flutter/material.dart'; import '../data/models/models.dart'; import '../theme/yanting_text.dart'; import '../theme/yanting_tokens.dart'; import 'app_card.dart'; import 'badges.dart'; 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, padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 14), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ InstitutionLogo( logoUrl: institution.logoUrl, initials: initials, size: 48, ), const SizedBox(width: 14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( institution.nameCn, maxLines: 1, overflow: TextOverflow.ellipsis, style: YantingText.listTitle.copyWith( fontWeight: FontWeight.w700, ), ), if (institution.nameEn.isNotEmpty) ...[ const SizedBox(height: 3), Text( institution.nameEn, maxLines: 1, overflow: TextOverflow.ellipsis, style: YantingText.meta, ), ], const SizedBox(height: 8), Wrap( spacing: 7, runSpacing: 7, children: [ if (institution.institutionType.isNotEmpty) AppBadge( text: institution.institutionType, kind: BadgeKind.tier, ), for (final topic in institution.coveredTopics.take(3)) AppBadge(text: topic), ], ), ], ), ), const SizedBox(width: 10), Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( '${institution.reportCount}', style: YantingText.sectionTitle.copyWith( fontSize: 20, fontFeatures: YantingTypographyFeatures.tabularNums, ), ), Text('份研报', style: YantingText.meta.copyWith(fontSize: 11)), ], ), ], ), ); } } class InstitutionLogo extends StatelessWidget { const InstitutionLogo({ required this.logoUrl, required this.initials, required this.size, super.key, }); final String logoUrl; final String initials; final double size; @override Widget build(BuildContext context) { final fallback = DecoratedBox( decoration: BoxDecoration( color: YantingColors.secondary, border: Border.all(color: YantingColors.border), borderRadius: BorderRadius.circular(size * 0.25), ), child: Center( child: Text( initials, style: YantingText.meta.copyWith( color: YantingColors.secondaryForeground, fontSize: 14, fontWeight: FontWeight.w700, fontFeatures: null, ), ), ), ); if (logoUrl.isEmpty) { return SizedBox(width: size, height: size, child: fallback); } return ClipRRect( borderRadius: BorderRadius.circular(size * 0.25), child: Image.network( logoUrl, width: size, height: size, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) => fallback, ), ); } }