initial commit

This commit is contained in:
2026-09-23 11:44:36 +02:00
commit ab3bbb6338
42 changed files with 9595 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
export function formatDate(iso: string): string {
return new Date(`${iso}T00:00:00`).toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' })
}
export function todayIso(): string {
const today = new Date()
const month = String(today.getMonth() + 1).padStart(2, '0')
const day = String(today.getDate()).padStart(2, '0')
return `${today.getFullYear()}-${month}-${day}`
}
+10
View File
@@ -0,0 +1,10 @@
interface FetchErrorLike {
data?: { statusMessage?: string }
statusMessage?: string
message?: string
}
export function errorMessage(error: unknown): string | undefined {
const e = error as FetchErrorLike | null
return e?.data?.statusMessage || e?.statusMessage || e?.message
}
+19
View File
@@ -0,0 +1,19 @@
interface TextPart {
text: string
hit: boolean
}
export function searchTerms(query: string): string[] {
return query.trim().toLowerCase().split(/\s+/).filter(Boolean)
}
export function highlight(text: string, query: string): TextPart[] {
const terms = searchTerms(query)
if (!terms.length) return [{ text, hit: false }]
const escaped = terms.map(term => term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
return text
.split(new RegExp(`(${escaped.join('|')})`, 'gi'))
.map((part, index) => ({ text: part, hit: index % 2 === 1 }))
.filter(part => part.text)
}
+8
View File
@@ -0,0 +1,8 @@
export const NOTE_ICON = 'i-lucide-notebook-pen'
export const REVIEW_ICON = 'i-lucide-star'
export const MEDIUM_ICONS: Record<Medium, string> = {
book: 'i-lucide-book-open',
movie: 'i-lucide-clapperboard',
album: 'i-lucide-disc-3'
}