new plus button

This commit is contained in:
davmar
2026-08-31 09:40:38 +02:00
parent 3b698a3667
commit 92581e6d55
17 changed files with 1336 additions and 152 deletions
+18
View File
@@ -16,5 +16,23 @@ const _months = [
'Dec',
];
const _monthNames = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
];
String formatDate(DateTime date) =>
'${date.day} ${_months[date.month - 1]} ${date.year}';
String formatMonthYear(DateTime date) =>
'${_monthNames[date.month - 1]} ${date.year}';
+48
View File
@@ -0,0 +1,48 @@
/// Month-grid helpers for the shop-log heatmap.
library;
DateTime dateOnly(DateTime date) => DateTime(date.year, date.month, date.day);
DateTime monthStart(DateTime date) => DateTime(date.year, date.month);
bool isSameDay(DateTime a, DateTime b) =>
a.year == b.year && a.month == b.month && a.day == b.day;
bool isSameMonth(DateTime a, DateTime b) =>
a.year == b.year && a.month == b.month;
DateTime addMonths(DateTime month, int delta) =>
DateTime(month.year, month.month + delta);
/// Monday-first calendar cells for [month], padded with nulls to full weeks.
List<DateTime?> monthGrid(DateTime month) {
final start = DateTime(month.year, month.month, 1);
final daysInMonth = DateTime(month.year, month.month + 1, 0).day;
final leading = start.weekday - DateTime.monday;
final cells = <DateTime?>[
...List<DateTime?>.filled(leading, null),
for (var day = 1; day <= daysInMonth; day++)
DateTime(month.year, month.month, day),
];
while (cells.length % 7 != 0) {
cells.add(null);
}
return cells;
}
/// How many trips landed on each calendar day.
Map<DateTime, int> tripCountsByDay(Iterable<DateTime> shoppedAt) {
final counts = <DateTime, int>{};
for (final date in shoppedAt) {
final key = dateOnly(date);
counts[key] = (counts[key] ?? 0) + 1;
}
return counts;
}
/// GitHub-style 0–4 intensity from a trip count.
int heatmapLevel(int count) {
if (count <= 0) return 0;
if (count >= 4) return 4;
return count;
}
+48
View File
@@ -0,0 +1,48 @@
/// Filters shop-log rows by day, tag, and product search.
library;
import '../models/shop.dart';
import 'fuzzy.dart';
import 'shop_calendar.dart';
List<Shop> filterShops({
required List<Shop> shops,
required Map<int, List<String>> productNames,
DateTime? selectedDay,
String? tag,
String query = '',
}) {
final needle = query.trim();
final tagFilter = tag?.trim();
return [
for (final shop in shops)
if (_matches(
shop: shop,
names: productNames[shop.id] ?? const [],
selectedDay: selectedDay,
tag: tagFilter,
query: needle,
))
shop,
];
}
bool _matches({
required Shop shop,
required List<String> names,
required DateTime? selectedDay,
required String? tag,
required String query,
}) {
if (selectedDay != null && !isSameDay(shop.shoppedAt, selectedDay)) {
return false;
}
if (tag != null && tag.isNotEmpty) {
final wanted = tag.toLowerCase();
if (!shop.tags.any((item) => item.toLowerCase() == wanted)) {
return false;
}
}
if (query.isEmpty) return true;
return names.any((name) => fuzzyScore(query, name) != null);
}