feat(knowledge): add KnowledgeItemCard widget
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
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<String> 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,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user