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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user