epic-ux-design #1

Open
sepehr wants to merge 31 commits from epic-ux-design into main

31 Commits

Author SHA1 Message Date
Sepehr Ramezani
402e88b788 feat(ux): epic UX design improvements across agents, chat, notes, and i18n
Comprehensive UI/UX updates including agent card redesign, chat container
improvements, note editor enhancements, memory echo notifications, and
updated translations for all 15 locales.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-19 23:01:04 +02:00
Sepehr Ramezani
c2a4c22e5f fix(ui): remove unreliable "Fusionné" badge from note cards
The autoGenerated flag is set by both fusion AND agent-created notes,
making the "Fusionné" badge appear on notes that were never actually
fused. Remove the badge entirely.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-19 22:37:45 +02:00
Sepehr Ramezani
2ef16f8a2c fix(memory-echo): fix fusion route config and single close button on comparison modal
- Fix fusion route using same broken prisma.systemConfig.findFirst()
  instead of getSystemConfig() — this caused all fusion requests to fail
- Replace duplicate close buttons (Radix auto + custom) with single
  styled close button in comparison modal header

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-19 22:26:20 +02:00
Sepehr Ramezani
c4c8f6a417 fix(memory-echo): feedback-adjusted thresholds and remove duplicate close button
- Thumbs down now increases the similarity threshold by +0.15 for the
  notes involved, making it harder for irrelevant connections to reappear
- Thumbs up slightly lowers the threshold by -0.05, boosting similar
  future connections
- Remove duplicate close button in ComparisonModal (kept only the
  native Dialog close button)
- Normalize all embeddings to same model/dimension (2560) to fix
  random similarity scores caused by mixed embedding models

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-19 22:23:29 +02:00
Sepehr Ramezani
389f85937a fix(memory-echo): fix broken AI provider config and auto-generate missing embeddings
- Fix critical bug: used prisma.systemConfig.findFirst() which returned
  a single {key,value} record instead of the full config object needed
  by getAIProvider(). Replaced with getSystemConfig() that returns all
  config as a proper Record<string,string>.
- Add ensureEmbeddings() to auto-generate embeddings for notes that
  lack them before searching for connections. This fixes the case where
  notes created without an AI provider configured never got embeddings,
  making Memory Echo silently return zero connections.
- Restore demo mode polling (15s interval after dismiss) in the
  notification component.
- Integrate ComparisonModal and FusionModal in the notification card
  with merge button for direct note fusion from the notification.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-19 22:05:19 +02:00
Sepehr Ramezani
25529a24b8 refactor(ux): consolidate BMAD skills, update design system, and clean up Prisma generated client 2026-04-19 19:21:27 +02:00
Sepehr Ramezani
5296c4da2c fix(agents): badge "Nouveau" disparaît après modification de l'agent
Compare createdAt et updatedAt au lieu du seuil de 24h.
Prisma met à jour updatedAt automatiquement à chaque édition.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-19 15:13:43 +02:00
Sepehr Ramezani
5c63dfdd0c feat(agents): add search/filter, "New" badge, and duplicate name resolution
- Add search bar with real-time filtering on agent name and description
- Add type filter chips (All, Veilleur, Chercheur, Surveillant, Personnalisé)
- Add "New" badge on agents created within the last 24h (hydration-safe)
- Auto-increment template names on duplicate install (e.g. "Veille Tech 2")
- Add i18n keys for new UI elements in both fr and en locales

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-19 15:11:32 +02:00
Sepehr Ramezani
08ab0d1a1e fix(rtl): remplacer les propriétés physiques par logiques pour le support RTL
La sidebar et le lab header utilisaient border-r, pr-4, ml-2, ml-auto
au lieu des propriétés logiques CSS (border-e, pe-4, ms-2, ms-auto).
En mode RTL (persan/arabe), ces propriétés physiques ne s'inversent pas,
ce qui causait la sidebar à basculer du mauvais côté lors de la
navigation vers Lab/Excalidraw.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-19 10:01:10 +02:00
Sepehr Ramezani
c5b495c03f fix(agents): empêcher le déplacement des cartes lors du toggle
Le tri par `updatedAt` provoquait un saut de position quand on toggait
un agent car Prisma mettait à jour `updatedAt` automatiquement.

- Tri stable par `createdAt` au lieu de `updatedAt`
- Mise à jour optimiste locale via `onToggle` au lieu d'un re-fetch complet
- Rollback automatique en cas d'erreur serveur
- Désactivation du bouton toggle pendant l'opération (anti double-clic)
- Suppression du `revalidatePath` superflu dans `toggleAgent`

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-18 19:18:49 +02:00
Sepehr Ramezani
3ef5915062 feat(db): extraction des embeddings + mode WAL + config DB provider-agnostic
- Ajout de la table de relation 1-1 NoteEmbedding pour alléger Model Note
- Refactor complet des actions IA sémantique et Memory Echo pour utiliser la jointure
- Migration propre des 85 embeddings locaux existants
- Ajout PRAGMA journal_mode=WAL pour la concurrence au sein de lib/prisma
- Ajout npm run db:switch pour configuration auto SQLite / PostgreSQL
- Fix du compilateur Turbopack et Next-PWA
2026-04-17 22:05:19 +02:00
Sepehr Ramezani
a57c277168 chore: clean complet du projet et ajout d'un README avec licence personnelle
- Suppression de tous les scripts de migration temporaires (fix_*.py, update_*.py, etc)
- Suppression des fichiers d'expérimentation html/json et .txt
- Modification du README: ajout d'une section licence usage non-commercial
- Modification du README: ajout d'une roadmap pour un déploiement public SaaS avec PostgreSQL et gestion de micro-services IO/Abonnement.
2026-04-17 21:53:10 +02:00
Sepehr Ramezani
f822a6eb18 fix: corriger 4 erreurs console post-migration RSC
- Hydration mismatch @dnd-kit: ajouter id="notes-tabs-dnd" et id="masonry-dnd"
  aux DndContext pour éviter les IDs auto-incrémentaux non-déterministes
  (DndDescribedBy-0 server vs DndDescribedBy-3 client)
- setState in render: refactorer handleDragEnd dans MasonryGrid — remplacer
  le double setLocalNotes() par arrayMove direct + ref pour la persistance
  (évite Cannot update Router while rendering MasonryGrid)
- DialogTitle manquant: ajouter DialogHeader+DialogTitle sr-only dans le
  loading state de AutoLabelSuggestionDialog (Radix accessibility requirement)
- Ajouter useRef pour tracker localNotes sans capturer de stale closure
2026-04-17 21:49:13 +02:00
Sepehr Ramezani
cb8bcd13ba perf: Phase 1+2+3 — Turbopack, Prisma select, RSC page, CSS masonry + dnd-kit
- Turbopack activé (dev: next dev --turbopack)
- NOTE_LIST_SELECT: exclut embedding (~6KB/note) des requêtes de liste
- getAllNotes/getNotes/getArchivedNotes/getNotesWithReminders optimisés
- searchNotes: filtrage DB-side au lieu de full-scan JS en mémoire
- getAllNotes: requêtes ownNotes + sharedNotes parallélisées avec Promise.all
- syncLabels: upsert en transaction () vs N boucles séquentielles
- app/(main)/page.tsx converti en Server Component (RSC)
- HomeClient: composant client hydraté avec données pré-chargées
- NoteEditor/BatchOrganizationDialog/AutoLabelSuggestionDialog: lazy-loaded avec dynamic()
- MasonryGrid: remplace Muuri par CSS grid auto-fill + @dnd-kit/sortable
- 13 packages supprimés: muuri, web-animations-js, react-masonry-css, react-grid-layout
- next.config.ts nettoyé: suppression webpack override, activation image optimization
2026-04-17 21:39:21 +02:00
Sepehr Ramezani
2eceb32fd4 chore: snapshot before performance optimization 2026-04-17 21:14:43 +02:00
Sepehr Ramezani
b6a548acd8 feat: RTL/i18n, AI translate+undo, no-refresh saves, settings perf
- RTL: force dir=rtl on LabelFilter, NotesViewToggle, LabelManagementDialog
- i18n: add missing keys (notifications, privacy, edit/preview, AI translate/undo)
- Settings pages: convert to Server Components (general, appearance) + loading skeleton
- AI menu: add Translate option (10 languages) + Undo AI button in toolbar
- Fix: saveInline uses REST API instead of Server Action → eliminates all implicit refreshes in list mode
- Fix: NotesTabsView notes sync effect preserves selected note on content changes
- Fix: auto-tag suggestions now filter already-assigned labels
- Fix: color change in card view uses local state (no refresh)
- Fix: nav links use <Link> for prefetching (Settings, Admin)
- Fix: suppress duplicate label suggestions already on note
- Route: add /api/ai/translate endpoint
2026-04-15 23:48:28 +02:00
Sepehr Ramezani
39671c6472 fix(keep-notes): sidebar chevron, labels sync, batch org errors, perf guards
- Notebooks: chevron visible when expanded (remove overflow clip), functional expand state
- Labels: sync/cleanup by notebookId, reconcile after note move
- Settings: refresh notebooks after cleanup; label dialog routing
- ConnectionsBadge lazy-load; reminder check persistence; i18n keys

Made-with: Cursor
2026-04-13 22:07:09 +02:00
Sepehr Ramezani
fa7e166f3e feat: add reminders page, BMad skills upgrade, MCP server refactor
- Add reminders page with navigation support
- Upgrade BMad builder module to skills-based architecture
- Refactor MCP server: extract tools and auth into separate modules
- Add connections cache, custom AI provider support
- Update prisma schema and generated client
- Various UI/UX improvements and i18n updates
- Add service worker for PWA support

Made-with: Cursor
2026-04-13 21:02:53 +02:00
Sepehr Ramezani
18ed116e0d perf: eliminate N+1 getNoteAllUsers calls and merge loadSettings+loadNotes to fix double-render cascade
- Skip getNoteAllUsers server action for for own notes (majority of notes), Only fetch collaborators for shared notes.
- Merge loadSettings and loadNotes into single useEffect to prevent double loadNotes trigger when showRecentNotes state changes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-01 22:27:29 +02:00
Sepehr Ramezani
377f0c739f fix: disable mobile drag, replace window.location.reload with router.refresh, use semantic icons
- Disable Muuri drag on mobile devices to prevent scroll conflicts
- Replace all remaining window.location.reload() with router.refresh() in settings/data, settings/general, and note-editor
- Replace duplicate X icons with semantic icons (Trash2 for fused badge, LogOut for leave share)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-01 21:34:22 +02:00
Sepehr Ramezani
8f35bac56f fix(perf): remove redundant router.refresh() calls from note-card.tsx
Remove 5 unnecessary router.refresh() calls in optimistic update handlers
(togglePin, toggleArchive, handleColorChange, handleCheckItem, handleRemoveFusedBadge).
These handlers already use addOptimisticNote() for instant UI feedback and
the server actions call revalidatePath('/') for cache invalidation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-01 21:13:01 +02:00
Sepehr Ramezani
df088510be fix(sidebar): remove footer links (Privacy, Terms, Open Source)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-29 22:26:10 +02:00
Sepehr Ramezani
806f4c4eeb fix(sidebar): eliminate full page reloads and fix notebook actions visibility
- Fix createNotebookOptimistic to call loadNotebooks() + triggerRefresh()
  after POST, so new notebooks appear immediately without page reload
- Remove window.location.reload() from delete-notebook-dialog (context
  already handles state refresh)
- Rewrite edit-notebook-dialog to use updateNotebook() from context
  instead of raw fetch + full page reload
- Fix NoteRefreshContext: remove refreshKey from useCallback deps to
  prevent unstable triggerRefresh callback cascade
- Fix notebook actions menu visibility: consolidate NotebookActions and
  expand button into single positioned container with proper z-index
- Add actions menu to active/selected notebook (was previously missing)
- Use proper Notebook type instead of any in sidebar components
- Increase button pr-20 to pr-24 to reserve space for actions
- Remove redundant router.refresh() from create-notebook-dialog

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-29 22:23:25 +02:00
Sepehr Ramezani
8daf50ac3f fix: i18n system overhaul and sidebar UI bugs
- Fix LanguageProvider: add RTL support (ar/fa), translation caching,
  prevent blank flash during load, browser language detection
- Fix detect-user-language: extend whitelist from 5 to all 15 languages
- Remove hardcoded initialLanguage="fr" from auth layout
- Complete fr.json translation (all sections translated from English)
- Add missing admin.ai keys to all 13 non-English locales
- Translate ai.autoLabels, ai.batchOrganization, memoryEcho sections
  for all locales
- Remove duplicate top-level autoLabels/batchOrganization from en.json
- Fix notebook creation: replace window.location.reload() with
  createNotebookOptimistic + router.refresh()
- Fix notebook name truncation in sidebar with min-w-0
- Remove redundant router.refresh() after note creation in page.tsx

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-29 22:14:05 +02:00
Sepehr Ramezani
8bf56cd8cd fix(admin): add spacing between AI embeddings section and footer buttons
Add pt-6 to CardFooter for proper visual separation between the last
content section and the action buttons.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-29 13:50:44 +02:00
Sepehr Ramezani
0903597759 fix(admin): prevent model selection reset by using onSubmit instead of form action
Using form action in Next.js triggers automatic router cache revalidation,
causing the server component to re-render and remount the client component,
which resets all useState values. Switching to onSubmit with e.preventDefault()
prevents this behavior while preserving full functionality.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-29 12:34:28 +02:00
Sepehr Ramezani
a9f619be7f fix(admin): remove revalidatePath to prevent combobox reset after save
revalidatePath was causing the server component to re-render and
potentially remount the client component, resetting all useState values.
Since the client component already updates its local state optimistically
after save, revalidatePath is unnecessary here. Also uninstalls agentation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-29 10:51:54 +02:00
Sepehr Ramezani
0d705ee3d6 fix(admin): prevent combobox reset after save by stopping unnecessary Ollama refetch
The Ollama model useEffect hooks were triggering on every config prop
change (including after revalidatePath), causing a model list refetch
that reset the combobox selection. Limited dependencies to provider
state only so fetch only runs on mount and provider switch.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-29 10:30:05 +02:00
Sepehr Ramezani
9a58a729d2 fix(admin): model selection resets after save and provider switch
Three bugs fixed:
- Removed the useEffect that synced state from config prop on every
  re-render, which caused a race condition resetting model state after
  revalidatePath triggered a server re-render.
- Reset selected model to a sensible default when switching providers,
  preventing stale model names from one provider appearing in another
  provider's model list (which made the select show the first option).
- Model select FormData names already fixed in previous commit to match
  provider-specific field names (AI_MODEL_TAGS_OLLAMA etc).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-29 10:12:35 +02:00
Sepehr Ramezani
cb613b86c1 fix(admin): AI provider and model not persisting after save
The model select fields used provider-specific names (AI_MODEL_TAGS_OLLAMA,
AI_MODEL_TAGS_OPENAI, etc.) but handleSaveAI read from non-existent
formData keys (AI_MODEL_TAGS, AI_MODEL_EMBEDDING). This caused model
values to be silently dropped on save, making the provider appear to
revert. Now reads from the correct provider-specific field names.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-29 09:54:49 +02:00
Sepehr Ramezani
789ccfd081 fix(deps): resolve nodemailer peer dependency conflict with next-auth
Add nodemailer override to force v8.0.4+ across the dependency tree,
fixing the ERESOLVE conflict with next-auth@5.0.0-beta.30 and
eliminating the SMTP command injection vulnerability (GHSA-c7w3-x93f-qmm8).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-29 09:51:05 +02:00