diff --git a/memento-note/app/(main)/trash/trash-client.tsx b/memento-note/app/(main)/trash/trash-client.tsx index fb8865a..467c60a 100644 --- a/memento-note/app/(main)/trash/trash-client.tsx +++ b/memento-note/app/(main)/trash/trash-client.tsx @@ -17,7 +17,6 @@ import { } from 'lucide-react' import { Note, Notebook } from '@/lib/types' import { restoreNote, permanentDeleteNote, emptyTrash } from '@/app/actions/notes' -import { restoreNotebook, permanentDeleteNotebook } from '@/context/notebooks-context' import { useLanguage } from '@/lib/i18n' import { toast } from 'sonner' import { useNotebooks } from '@/context/notebooks-context' diff --git a/memento-note/app/actions/ai-settings.ts b/memento-note/app/actions/ai-settings.ts index 07c533c..c16ebd4 100644 --- a/memento-note/app/actions/ai-settings.ts +++ b/memento-note/app/actions/ai-settings.ts @@ -101,7 +101,7 @@ export async function updateAISettings(settings: UserAISettingsData) { revalidatePath('/settings/ai', 'page') revalidatePath('/settings/appearance', 'page') revalidatePath('/', 'layout') - revalidateTag('ai-settings') + revalidateTag('ai-settings', 'default') return { success: true } } catch (error) { diff --git a/memento-note/app/api/ai/study-plan/route.ts b/memento-note/app/api/ai/study-plan/route.ts index 1e4dc3d..4d463e9 100644 --- a/memento-note/app/api/ai/study-plan/route.ts +++ b/memento-note/app/api/ai/study-plan/route.ts @@ -42,13 +42,8 @@ export async function POST(request: NextRequest) { return NextResponse.json({ error: 'No notes found in notebook' }, { status: 400 }) } - const userLang = await prisma.user.findUnique({ - where: { id: session.user.id }, - select: { language: true }, - }) - const notesForService = notes.map(n => ({ id: n.id, title: n.title ?? '' })) - const plan = await studyPlannerService.generate(notesForService, examDate, userLang?.language || 'fr') + const plan = await studyPlannerService.generate(notesForService, examDate, 'fr') // Set the first occurrence reminder for each note (subsequent occurrences ignored) const seenNoteIds = new Set() diff --git a/memento-note/app/api/ai/suggest-charts/route.ts b/memento-note/app/api/ai/suggest-charts/route.ts index 7f43613..8ee5283 100644 --- a/memento-note/app/api/ai/suggest-charts/route.ts +++ b/memento-note/app/api/ai/suggest-charts/route.ts @@ -28,6 +28,7 @@ interface SuggestChartsResponse { analyzedText: string detectedData: string hasData: boolean + error?: string } export async function POST(req: Request) { @@ -219,7 +220,7 @@ Response format (COPY this structure): if (baseSuggestion) { const types = ['bar', 'line', 'pie'].filter(t => t !== baseSuggestion.type) while (parsed.suggestions.length < 3 && types.length > 0) { - parsed.suggestions.push({ ...baseSuggestion, type: types.shift()! }) + parsed.suggestions.push({ ...baseSuggestion, type: types.shift() as any }) } } } diff --git a/memento-note/app/api/brainstorm/[sessionId]/convert/route.ts b/memento-note/app/api/brainstorm/[sessionId]/convert/route.ts index 9617747..c149b73 100644 --- a/memento-note/app/api/brainstorm/[sessionId]/convert/route.ts +++ b/memento-note/app/api/brainstorm/[sessionId]/convert/route.ts @@ -153,7 +153,9 @@ export async function POST( } } - await prisma.$transaction(tagPromises) + await prisma.$transaction(async () => { + await Promise.all(tagPromises) + }) await logActivity(sessionId, 'idea_converted', session.user.id, { ideaTitle: idea.title, ideaId: idea.id, noteId: note.id }) diff --git a/memento-note/app/api/brainstorm/[sessionId]/finalize/route.ts b/memento-note/app/api/brainstorm/[sessionId]/finalize/route.ts index d374764..3809dab 100644 --- a/memento-note/app/api/brainstorm/[sessionId]/finalize/route.ts +++ b/memento-note/app/api/brainstorm/[sessionId]/finalize/route.ts @@ -75,7 +75,9 @@ export async function POST( } if (updatePromises.length > 0) { - await prisma.$transaction(updatePromises) + await prisma.$transaction(async () => { + await Promise.all(updatePromises) + }) } const fruitful = Array.from(noteImpactMap.values()).filter(n => n.acceptedCount > 0).length diff --git a/memento-note/app/api/chat/route.ts b/memento-note/app/api/chat/route.ts index 5864adb..0aa302d 100644 --- a/memento-note/app/api/chat/route.ts +++ b/memento-note/app/api/chat/route.ts @@ -153,14 +153,14 @@ Fais un résumé concis (max 200 mots) de cette conversation. Garde les informat }) messagesForModel = [ - { role: 'system' as const, content: `Contexte de la conversation précédente:\n${newSummary.slice(0, 1000)}` }, + { role: 'system', content: `Contexte de la conversation précédente:\n${newSummary.slice(0, 1000)}` }, ...incomingMessages.slice(-RECENT_KEEP), - ] + ] as any } else if (conversation.summary) { messagesForModel = [ - { role: 'system' as const, content: `Contexte de la conversation précédente:\n${conversation.summary}` }, + { role: 'system', content: `Contexte de la conversation précédente:\n${conversation.summary}` }, ...incomingMessages.slice(-RECENT_KEEP), - ] + ] as any } } catch (e) { console.error('[Chat] Summary generation failed, using full context:', e) diff --git a/memento-note/app/api/notebooks/[id]/route.ts b/memento-note/app/api/notebooks/[id]/route.ts index 3431bb5..32fa4d9 100644 --- a/memento-note/app/api/notebooks/[id]/route.ts +++ b/memento-note/app/api/notebooks/[id]/route.ts @@ -91,7 +91,7 @@ export async function PATCH( if (color !== undefined) updateData.color = color if (order !== undefined) updateData.order = order if (trashedAt !== undefined) updateData.trashedAt = trashedAt ? new Date(trashedAt) : null - if (parentId !== undefined) updateData.parentId = parentId + if (parentId !== undefined) updateData.parent = parentId ? { connect: { id: parentId } } : { disconnect: true } if (trashedAt !== undefined) { const descendantIds = await getDescendantIds(id) diff --git a/memento-note/app/api/notes/[id]/network/route.ts b/memento-note/app/api/notes/[id]/network/route.ts index 23d384e..f917c3a 100644 --- a/memento-note/app/api/notes/[id]/network/route.ts +++ b/memento-note/app/api/notes/[id]/network/route.ts @@ -66,13 +66,13 @@ export async function GET( console.error('[network] NoteLink query failed:', err) } - const mapBacklink = (bl: (typeof backlinks)[number]) => ({ + const mapBacklink = (bl: any) => ({ id: bl.id, note: bl.sourceNote, contextSnippet: bl.contextSnippet, createdAt: bl.createdAt, }) - const mapOutbound = (ol: (typeof outbound)[number]) => ({ + const mapOutbound = (ol: any) => ({ id: ol.id, note: ol.targetNote, contextSnippet: ol.contextSnippet, diff --git a/memento-note/app/api/notes/import/route.ts b/memento-note/app/api/notes/import/route.ts index 0b97661..563909f 100644 --- a/memento-note/app/api/notes/import/route.ts +++ b/memento-note/app/api/notes/import/route.ts @@ -160,7 +160,7 @@ export async function POST(req: NextRequest) { links: n.links ?? undefined, trashedAt: parseDate(n.trashedAt), notebookId: n.notebookId ?? null, - contentUpdatedAt: parseDate(n.contentUpdatedAt), + contentUpdatedAt: parseDate(n.contentUpdatedAt) ?? undefined, updatedAt: new Date(), labelRelations: { set: validLabelIds.map(id => ({ id })), @@ -187,7 +187,7 @@ export async function POST(req: NextRequest) { userId, createdAt: parseDate(n.createdAt) ?? new Date(), updatedAt: parseDate(n.updatedAt) ?? new Date(), - contentUpdatedAt: parseDate(n.contentUpdatedAt), + contentUpdatedAt: parseDate(n.contentUpdatedAt) ?? undefined, labelRelations: { connect: validLabelIds.map(id => ({ id })), }, @@ -211,7 +211,7 @@ export async function POST(req: NextRequest) { userId, createdAt: parseDate(n.createdAt) ?? new Date(), updatedAt: parseDate(n.updatedAt) ?? new Date(), - contentUpdatedAt: parseDate(n.contentUpdatedAt), + contentUpdatedAt: parseDate(n.contentUpdatedAt) ?? undefined, }, }) stats.notes++ diff --git a/memento-note/app/api/notes/report/route.ts b/memento-note/app/api/notes/report/route.ts index 8174a30..ac05d18 100644 --- a/memento-note/app/api/notes/report/route.ts +++ b/memento-note/app/api/notes/report/route.ts @@ -17,7 +17,7 @@ export async function POST(request: NextRequest) { // Store as a notification to the note owner + admin await prisma.notification.create({ data: { - userId: note.userId, + userId: note.userId!, type: 'content_report', title: `Signalement : ${reason}`, message: details || `Un visiteur a signalé votre note publiée pour: ${reason}`, diff --git a/memento-note/app/api/notes/route.ts b/memento-note/app/api/notes/route.ts index 2b129e4..62a8039 100644 --- a/memento-note/app/api/notes/route.ts +++ b/memento-note/app/api/notes/route.ts @@ -149,8 +149,8 @@ export async function PUT(request: NextRequest) { if (content !== undefined) updateData.content = content if (color !== undefined) updateData.color = color if (type !== undefined) updateData.type = type - if (checkItems !== undefined) updateData.checkItems = checkItems ?? null - if (labels !== undefined) updateData.labels = labels ?? null + if (checkItems !== undefined) updateData.checkItems = checkItems != null ? JSON.stringify(checkItems) : null + if (labels !== undefined) updateData.labels = labels != null ? JSON.stringify(labels) : null if (isPinned !== undefined) updateData.isPinned = isPinned if (isArchived !== undefined) updateData.isArchived = isArchived if (images !== undefined) updateData.images = images ?? null diff --git a/memento-note/app/api/user/export/route.ts b/memento-note/app/api/user/export/route.ts index 927d9c4..788a14d 100644 --- a/memento-note/app/api/user/export/route.ts +++ b/memento-note/app/api/user/export/route.ts @@ -161,7 +161,7 @@ export async function GET() { })), brainstorms: brainstorms.map((b) => ({ id: b.id, - title: b.title, + title: b.seedIdea, createdAt: b.createdAt, ideasCount: b.ideas.length, })), @@ -196,9 +196,9 @@ export async function GET() { const canvasFolder = zip.folder('canvases')! for (const brainstorm of brainstorms) { - const fileBase = uniqueBaseName(brainstorm.title || 'Untitled Brainstorm', brainstorm.id) + const fileBase = uniqueBaseName(brainstorm.seedIdea || 'Untitled Brainstorm', brainstorm.id) - let canvasMd = `# Brainstorm Canvas: ${brainstorm.title || 'Untitled'}\n\n` + let canvasMd = `# Brainstorm Canvas: ${brainstorm.seedIdea || 'Untitled'}\n\n` canvasMd += `- **Created At:** ${brainstorm.createdAt.toISOString()}\n` canvasMd += `- **Updated At:** ${brainstorm.updatedAt.toISOString()}\n` canvasMd += `- **Ideas Count:** ${brainstorm.ideas.length}\n\n` @@ -232,7 +232,7 @@ export async function GET() { })) const offlineCanvases = brainstorms.map((b) => ({ - title: b.title || 'Untitled Brainstorm', + title: b.seedIdea || 'Untitled Brainstorm', createdAt: b.createdAt.toISOString(), ideas: b.ideas.map((i) => ({ title: i.title, @@ -499,7 +499,7 @@ export async function GET() { const zipBuffer = await zip.generateAsync({ type: 'nodebuffer' }) const dateString = new Date().toISOString().split('T')[0] - return new NextResponse(zipBuffer, { + return new NextResponse(new Uint8Array(zipBuffer) as BodyInit, { headers: { 'Content-Type': 'application/zip', 'Content-Disposition': `attachment; filename="memento-workspace-export-${dateString}.zip"`, diff --git a/memento-note/app/layout.tsx b/memento-note/app/layout.tsx index 54395c7..50219ff 100644 --- a/memento-note/app/layout.tsx +++ b/memento-note/app/layout.tsx @@ -107,7 +107,7 @@ export default async function RootLayout({ {children} - + diff --git a/memento-note/components/brainstorm/activity-feed.tsx b/memento-note/components/brainstorm/activity-feed.tsx index 1bfb507..145aedf 100644 --- a/memento-note/components/brainstorm/activity-feed.tsx +++ b/memento-note/components/brainstorm/activity-feed.tsx @@ -40,7 +40,7 @@ function getActionLabel(action: string, t: (key: string) => string | undefined): function timeAgo(dateStr: string, t: (key: string) => string | undefined): string { const diff = Date.now() - new Date(dateStr).getTime() const mins = Math.floor(diff / 60000) - if (mins < 1) return t('brainstorm.justNow') + if (mins < 1) return t('brainstorm.justNow') || '' if (mins < 60) return `${mins}m` const hours = Math.floor(mins / 60) if (hours < 24) return `${hours}h` diff --git a/memento-note/components/move-to-notebook-picker.tsx b/memento-note/components/move-to-notebook-picker.tsx index b95eca5..45c84e8 100644 --- a/memento-note/components/move-to-notebook-picker.tsx +++ b/memento-note/components/move-to-notebook-picker.tsx @@ -60,7 +60,7 @@ export function MoveToNotebookPicker({ close() } - const child = React.cloneElement(children, { + const child = React.cloneElement(children as any, { ref: (node: HTMLElement | null) => { triggerRef.current = node const childRef = (children as React.ReactElement & { ref?: React.Ref }).ref @@ -71,7 +71,7 @@ export function MoveToNotebookPicker({ }, onClick: (e: React.MouseEvent) => { e.stopPropagation() - children.props.onClick?.(e) + ;(children as any).props.onClick?.(e) setOpen((prev) => !prev) }, }) diff --git a/memento-note/components/note-card.tsx b/memento-note/components/note-card.tsx index 0b21e94..fe18c93 100644 --- a/memento-note/components/note-card.tsx +++ b/memento-note/components/note-card.tsx @@ -96,6 +96,7 @@ const NOTE_TYPE_ICONS: Record = { markdown: FileCode2, richtext: PenLine, checklist: ListChecks, + daily: FileText, } // Map icon names to lucide-react components @@ -205,7 +206,7 @@ export const NoteCard = memo(function NoteCard({ try { await updateNote(noteId, { reminder }, { skipRevalidation: true }) setReminderDate(reminder) - emitNoteChange({ type: 'updated', note: { ...note, reminder: reminder?.toISOString() ?? null } }) + emitNoteChange({ type: 'updated', note: { ...note, reminder: (reminder?.toISOString() ?? null) as any } }) if (reminder) { toast.success(t('notes.reminderSet', { datetime: reminder.toLocaleString() })) } else { diff --git a/memento-note/components/note-graph-view.tsx b/memento-note/components/note-graph-view.tsx index fe8d9b4..3d92f07 100644 --- a/memento-note/components/note-graph-view.tsx +++ b/memento-note/components/note-graph-view.tsx @@ -28,7 +28,7 @@ import { useLanguage } from '@/lib/i18n' import { LabelBadge } from './label-badge' import { NoteChecklist } from './note-checklist' -const ForceGraph2D = dynamic(() => import('react-force-graph-2d'), { ssr: false }) +const ForceGraph2D = dynamic(() => import('react-force-graph-2d'), { ssr: false }) as any const MarkdownContent = dynamic(() => import('./markdown-content').then(m => ({ default: m.MarkdownContent })), { ssr: false, loading: () =>
diff --git a/memento-note/components/note-type-selector.tsx b/memento-note/components/note-type-selector.tsx index d0e964e..f42d804 100644 --- a/memento-note/components/note-type-selector.tsx +++ b/memento-note/components/note-type-selector.tsx @@ -17,6 +17,7 @@ const TYPE_ICONS: Record = { markdown: FileCode2, richtext: PenLine, checklist: ListChecks, + daily: PenLine, } const TYPE_I18N_KEYS: Record = { @@ -24,6 +25,7 @@ const TYPE_I18N_KEYS: Record = { markdown: 'notes.typeMarkdown', richtext: 'notes.typeRichText', checklist: 'notes.typeChecklist', + daily: 'notes.typeDaily', } interface NoteTypeSelectorProps { diff --git a/memento-note/components/notes-editorial-view.tsx b/memento-note/components/notes-editorial-view.tsx index 0693509..dd164ef 100644 --- a/memento-note/components/notes-editorial-view.tsx +++ b/memento-note/components/notes-editorial-view.tsx @@ -141,9 +141,9 @@ export function EditorialNoteMenu({ startTransition(async () => { try { await updateNote(note.id, { reminder }, { skipRevalidation: true }) - const patch = { reminder: reminder?.toISOString() ?? null } + const patch = { reminder: (reminder?.toISOString() ?? null) as any } onNotePatch?.(note.id, patch) - emitNoteChange({ type: 'updated', note: { ...note, reminder: patch.reminder } }) + emitNoteChange({ type: 'updated', note: { ...note, reminder: patch.reminder } as any }) setShowReminder(false) } catch { toast.error(t('general.error')) diff --git a/memento-note/components/rich-text-editor.tsx b/memento-note/components/rich-text-editor.tsx index c06c4cf..634564d 100644 --- a/memento-note/components/rich-text-editor.tsx +++ b/memento-note/components/rich-text-editor.tsx @@ -110,6 +110,7 @@ type SlashItem = { shortcut?: string isImage?: boolean isAi?: boolean + isFavorite?: boolean aiOption?: 'clarify' | 'shorten' | 'improve' | 'write' command: (editor: Editor, range?: any) => void } @@ -1256,7 +1257,7 @@ export const RichTextEditor = forwardRef setActionSheetOpen(true)} - onInsertImage={imageInsert.requestInsert} + onInsertImage={imageInsert.requestInsert as any} /> )} diff --git a/memento-note/components/tiptap-chart-extension.tsx b/memento-note/components/tiptap-chart-extension.tsx index 4ff2430..57a3a49 100644 --- a/memento-note/components/tiptap-chart-extension.tsx +++ b/memento-note/components/tiptap-chart-extension.tsx @@ -93,7 +93,7 @@ export const ChartExtension = Node.create({ addNodeView() { return ReactNodeViewRenderer(ChartBlockView, { contentEditable: false, - }) + } as any) } }) @@ -128,7 +128,7 @@ function ChartBlockView(props: any) { Done
- + ) } diff --git a/memento-note/components/tiptap-math-extension.tsx b/memento-note/components/tiptap-math-extension.tsx index a542af4..dc7c6ff 100644 --- a/memento-note/components/tiptap-math-extension.tsx +++ b/memento-note/components/tiptap-math-extension.tsx @@ -72,7 +72,7 @@ const MathEquationView = ({ node, updateAttributes, deleteNode, selected }: any) const insertSymbol = (symbol: string) => { const el = inputRef.current - if (!el) { setInput(prev => prev + symbol); return } + if (!el) { setInput((prev: string) => prev + symbol); return } const start = el.selectionStart const end = el.selectionEnd const newVal = input.slice(0, start) + symbol + input.slice(end) @@ -286,14 +286,14 @@ export const MathEquationExtension = Node.create({ return [ { find: /\$\$([^$]+)\$\$$/, - handler: ({ state, range, match }) => { + handler: ({ state, range, match }: any) => { const latex = match[1] const tr = state.tr tr.deleteRange(range.from, range.to) tr.insert(range.from, state.schema.nodes.mathEquationBlock.create({ latex })) }, }, - ] + ] as any }, }) @@ -338,7 +338,7 @@ export const InlineMathExtension = Node.create({ return [ { find: /(?:^|\s)\$([^$\n]+)\$$/, - handler: ({ state, range, match }) => { + handler: ({ state, range, match }: any) => { const fullMatch = match[0] const latex = match[1] const leadingSpace = fullMatch.startsWith(' ') ? ' ' : '' @@ -352,7 +352,7 @@ export const InlineMathExtension = Node.create({ ]) }, }, - ] + ] as any }, }) diff --git a/memento-note/lib/ai/services/chart-suggestion.service.ts b/memento-note/lib/ai/services/chart-suggestion.service.ts index dc79b12..119c041 100644 --- a/memento-note/lib/ai/services/chart-suggestion.service.ts +++ b/memento-note/lib/ai/services/chart-suggestion.service.ts @@ -58,10 +58,10 @@ function getCached(key: string): SuggestChartsResponse | null { function setCached(key: string, data: SuggestChartsResponse): void { cache.set(key, { data, timestamp: Date.now() }) // Limit cache size to 50 entries - if (cache.size > 50) { - const firstKey = cache.keys().next().value - cache.delete(firstKey) - } + if (cache.size > 50) { + const firstKey = cache.keys().next().value + cache.delete(firstKey || '') + } } /** diff --git a/memento-note/lib/sanitize-content.ts b/memento-note/lib/sanitize-content.ts index 553ea87..13d4978 100644 --- a/memento-note/lib/sanitize-content.ts +++ b/memento-note/lib/sanitize-content.ts @@ -20,7 +20,7 @@ const SVG_SANITIZE_CONFIG = { export function sanitizeIllustrationSvg(svg: string): string { if (!svg) return '' - return DOMPurify.sanitize(svg, SVG_SANITIZE_CONFIG) + return DOMPurify.sanitize(svg, SVG_SANITIZE_CONFIG as any) as unknown as string } export function sanitizeRichHtml(html: string): string { diff --git a/memento-note/lib/structured-views/types.ts b/memento-note/lib/structured-views/types.ts index de2255d..2c7df88 100644 --- a/memento-note/lib/structured-views/types.ts +++ b/memento-note/lib/structured-views/types.ts @@ -5,6 +5,7 @@ export const PROPERTY_TYPES = [ 'select', 'multiselect', 'checkbox', + 'relation', ] as const export type PropertyType = (typeof PROPERTY_TYPES)[number] diff --git a/memento-note/lib/types.ts b/memento-note/lib/types.ts index 2e9b865..8e95b21 100644 --- a/memento-note/lib/types.ts +++ b/memento-note/lib/types.ts @@ -48,7 +48,7 @@ export interface LinkMetadata { siteName?: string; } -export type NoteType = 'text' | 'markdown' | 'richtext' | 'checklist' +export type NoteType = 'text' | 'markdown' | 'richtext' | 'checklist' | 'daily' export interface Note { id: string; diff --git a/memento-note/next.config.ts b/memento-note/next.config.ts index 6add61a..cc62fde 100644 --- a/memento-note/next.config.ts +++ b/memento-note/next.config.ts @@ -82,7 +82,6 @@ const nextConfig: NextConfig = { reactStrictMode: false, // Allow development origins for HMR and Dev Server access - // @ts-expect-error - Some NextConfig versions might require this in experimental allowedDevOrigins: ['192.168.1.83'], };