feat(05-02): create filterEntries utility function

- Add SearchFilters type and utilities (search.ts)
- Implement filterEntries with query, tags, type, dateRange filters
- Case-insensitive text search with 2-character minimum
- AND logic for tag filtering
- Date range inclusive of end date
This commit is contained in:
Thomas Richter
2026-01-31 17:11:53 +01:00
parent b1e62a4658
commit 8f544a9989

View File

@@ -0,0 +1,55 @@
import type { SearchFilters } from '$lib/types/search';
import type { Entry, Tag } from '$lib/server/db/schema';
interface EntryWithTags extends Entry {
tags: Tag[];
}
/**
* Filters entries based on search criteria.
*
* @param entries - Array of entries with their tags
* @param filters - SearchFilters object containing filter criteria
* @returns Filtered array of entries
*/
export function filterEntries(
entries: EntryWithTags[],
filters: SearchFilters
): EntryWithTags[] {
let result = entries;
// Text search (title + content) - minimum 2 characters
if (filters.query.length >= 2) {
const query = filters.query.toLowerCase();
result = result.filter(
(e) =>
e.title?.toLowerCase().includes(query) || e.content.toLowerCase().includes(query)
);
}
// Tag filter - AND logic (must have ALL selected tags)
if (filters.tags.length > 0) {
result = result.filter((e) =>
filters.tags.every((tagName) =>
e.tags.some((t) => t.name.toLowerCase() === tagName.toLowerCase())
)
);
}
// Type filter
if (filters.type !== 'all') {
result = result.filter((e) => e.type === filters.type);
}
// Date range filter (using createdAt)
if (filters.dateRange.start) {
result = result.filter((e) => e.createdAt >= filters.dateRange.start!);
}
if (filters.dateRange.end) {
// Include the end date by comparing to end of day
const endOfDay = filters.dateRange.end + 'T23:59:59';
result = result.filter((e) => e.createdAt <= endOfDay);
}
return result;
}