import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import '../data/models/knowledge_item.dart'; class KnowledgeItemCard extends StatelessWidget { final KnowledgeItem item; const KnowledgeItemCard({super.key, required this.item}); IconData get _icon => switch (item.noteType) { 'person' => Icons.person_outlined, 'place' => Icons.place_outlined, 'list' => Icons.checklist_outlined, 'task' => Icons.task_alt_outlined, _ => Icons.description_outlined, }; Color _statusColor(BuildContext context) { if (item.noteType != 'task') return Theme.of(context).colorScheme.primary; return switch (item.status) { 'done' => Colors.green, 'in_progress' => Colors.orange, 'cancelled' => Colors.grey, _ => Theme.of(context).colorScheme.primary, }; } String? get _subtitle { if (item.noteType == 'task') { if (item.dueDate != null) return 'Due ${item.dueDate}'; return item.status; } if (item.body.trim().isEmpty) return null; final preview = item.body.trim().replaceAll('\n', ' '); return preview.length > 120 ? '${preview.substring(0, 120)}…' : preview; } @override Widget build(BuildContext context) { return ListTile( leading: Icon(_icon, color: _statusColor(context)), title: Text( item.title.isEmpty ? '(untitled)' : item.title, maxLines: 1, overflow: TextOverflow.ellipsis, ), subtitle: _subtitle != null ? Text( _subtitle!, maxLines: 2, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.bodySmall, ) : null, trailing: item.tags.isNotEmpty ? _TagChips(tags: item.tags) : null, onTap: () { if (item.noteType == 'task') { context.push('/tasks/${item.id}/edit'); } else { context.push('/notes/${item.id}'); } }, ); } } class _TagChips extends StatelessWidget { final List tags; const _TagChips({required this.tags}); @override Widget build(BuildContext context) { final shown = tags.take(2).toList(); final extra = tags.length - shown.length; return Wrap( spacing: 4, children: [ for (final t in shown) Chip( label: Text(t, style: const TextStyle(fontSize: 10)), padding: EdgeInsets.zero, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, visualDensity: VisualDensity.compact, ), if (extra > 0) Chip( label: Text('+$extra', style: const TextStyle(fontSize: 10)), padding: EdgeInsets.zero, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, visualDensity: VisualDensity.compact, ), ], ); } }