feat: Memento avec dates, Markdown, reminders et auth

Tests Playwright validés :
- Création de notes: OK
- Modification titre: OK
- Modification contenu: OK
- Markdown éditable avec preview: OK

Fonctionnalités:
- date-fns: dates relatives sur cards
- react-markdown + remark-gfm
- Markdown avec toggle edit/preview
- Recherche améliorée (titre/contenu/labels/checkItems)
- Reminder recurrence/location (schema)
- NextAuth.js + User/Account/Session
- userId dans Note (optionnel)
- 4 migrations créées

Ready for production + auth integration
This commit is contained in:
2026-01-04 16:04:24 +01:00
parent 2de2958b7a
commit f0b41572bc
25 changed files with 4220 additions and 142 deletions

View File

@@ -58,8 +58,10 @@ export async function searchNotes(query: string) {
where: {
isArchived: false,
OR: [
{ title: { contains: query, mode: 'insensitive' } },
{ content: { contains: query, mode: 'insensitive' } }
{ title: { contains: query } },
{ content: { contains: query } },
{ labels: { contains: query } },
{ checkItems: { contains: query } }
]
},
orderBy: [
@@ -68,7 +70,38 @@ export async function searchNotes(query: string) {
]
})
return notes.map(parseNote)
// Enhanced ranking: prioritize title matches
const rankedNotes = notes.map(note => {
const parsedNote = parseNote(note)
let score = 0
// Title match gets highest score
if (parsedNote.title?.toLowerCase().includes(query.toLowerCase())) {
score += 10
}
// Content match
if (parsedNote.content.toLowerCase().includes(query.toLowerCase())) {
score += 5
}
// Label match
if (parsedNote.labels?.some(label => label.toLowerCase().includes(query.toLowerCase()))) {
score += 3
}
// CheckItems match
if (parsedNote.checkItems?.some(item => item.text.toLowerCase().includes(query.toLowerCase()))) {
score += 2
}
return { note: parsedNote, score }
})
// Sort by score descending, then by existing order (pinned/updated)
return rankedNotes
.sort((a, b) => b.score - a.score)
.map(item => item.note)
} catch (error) {
console.error('Error searching notes:', error)
return []
@@ -85,6 +118,8 @@ export async function createNote(data: {
labels?: string[]
images?: string[]
isArchived?: boolean
reminder?: Date | null
isMarkdown?: boolean
}) {
try {
const note = await prisma.note.create({
@@ -97,6 +132,8 @@ export async function createNote(data: {
labels: data.labels ? JSON.stringify(data.labels) : null,
images: data.images ? JSON.stringify(data.images) : null,
isArchived: data.isArchived || false,
reminder: data.reminder || null,
isMarkdown: data.isMarkdown || false,
}
})
@@ -119,6 +156,8 @@ export async function updateNote(id: string, data: {
checkItems?: CheckItem[] | null
labels?: string[] | null
images?: string[] | null
reminder?: Date | null
isMarkdown?: boolean
}) {
try {
// Stringify JSON fields if they exist