feat: design system overhaul — sidebar, AI chats, settings, brainstorm, color cleanup
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 12s
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 12s
- Sidebar: dynamic brand-accent colors, brainstorm section restyled - AI chat general: popup panel with expand/collapse, hides when contextual AI open - AI chat contextual: tabs reordered (Actions first), X close button, height fix - Settings: all tabs restyled, 6 new color presets (sage, terracotta, iron, etc.) - Global color cleanup: emerald/orange hardcoded → brand-accent dynamic - Brainstorm page: orange → brand-accent throughout - PageEntry animation component added to key pages - Floating AI button: bg-brand-accent instead of hardcoded black - i18n: all 15 locales updated with new AI/billing keys - Billing: freemium quota tracking, BYOK, stripe subscription scaffolding - Admin: integrated into new design - AGENTS.md + CLAUDE.md project rules added
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import React, { useEffect, useRef, useState, useCallback } from 'react'
|
||||
import * as d3 from 'd3'
|
||||
import { BrainstormSession } from '@/types/brainstorm'
|
||||
import { useLanguage } from '@/lib/i18n'
|
||||
|
||||
interface WaveCanvasProps {
|
||||
session: BrainstormSession
|
||||
@@ -31,6 +32,7 @@ export const WaveCanvas: React.FC<WaveCanvasProps> = ({
|
||||
manualEditTrigger,
|
||||
playbackIdeas,
|
||||
}) => {
|
||||
const { t, language } = useLanguage()
|
||||
const svgRef = useRef<SVGSVGElement>(null)
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
const nodeRef = useRef<d3.Selection<SVGGElement, any, SVGGElement, unknown> | null>(null)
|
||||
@@ -376,7 +378,7 @@ export const WaveCanvas: React.FC<WaveCanvasProps> = ({
|
||||
)
|
||||
.text((d) =>
|
||||
d.type === 'root'
|
||||
? 'SEED'
|
||||
? t('brainstorm.seedNodeBadge')
|
||||
: d.title.length > 18
|
||||
? d.title.substring(0, 18) + '...'
|
||||
: d.title
|
||||
@@ -476,7 +478,7 @@ export const WaveCanvas: React.FC<WaveCanvasProps> = ({
|
||||
return () => {
|
||||
simulation.stop()
|
||||
}
|
||||
}, [sessionId, ideasKey, isDark, toSvgCoords, toScreenCoords, playbackIdeas])
|
||||
}, [sessionId, ideasKey, isDark, toSvgCoords, toScreenCoords, playbackIdeas, language, t])
|
||||
|
||||
useEffect(() => {
|
||||
if (!nodeRef.current) return
|
||||
@@ -533,13 +535,13 @@ export const WaveCanvas: React.FC<WaveCanvasProps> = ({
|
||||
>
|
||||
<div className="w-[260px] bg-white dark:bg-[#1A1A1A] rounded-2xl shadow-2xl border border-black/10 dark:border-white/10 overflow-hidden">
|
||||
<div className="px-3.5 pt-3 pb-1 flex items-center gap-2">
|
||||
<div className="w-5 h-5 rounded-md bg-memento-blue/10 flex items-center justify-center">
|
||||
<div className="w-5 h-5 rounded-md bg-brand-accent/10 flex items-center justify-center">
|
||||
<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="#3b82f6" strokeWidth="2.5" strokeLinecap="round">
|
||||
<path d="M12 5v14M5 12h14" />
|
||||
</svg>
|
||||
</div>
|
||||
<span className="text-[10px] font-bold uppercase tracking-[0.15em] text-foreground/50">
|
||||
{editingNode.parentId ? 'Réponse' : 'Nouvelle idée'}
|
||||
{editingNode.parentId ? t('brainstorm.canvasEditTitleReply') : t('brainstorm.canvasEditTitleNewIdea')}
|
||||
</span>
|
||||
</div>
|
||||
<div className="px-3.5 pb-3">
|
||||
@@ -551,19 +553,19 @@ export const WaveCanvas: React.FC<WaveCanvasProps> = ({
|
||||
if (e.key === 'Enter' && editText.trim()) handleSubmitIdea()
|
||||
if (e.key === 'Escape') { setEditingNode(null); setEditText('') }
|
||||
}}
|
||||
placeholder={editingNode.parentId ? 'Votre réponse…' : 'Votre idée…'}
|
||||
className="w-full px-3 py-2.5 text-sm font-serif bg-black/[0.03] dark:bg-white/[0.06] border border-black/[0.06] dark:border-white/[0.12] rounded-xl outline-none focus:border-memento-blue/50 focus:bg-white dark:focus:bg-white/[0.08] transition-all placeholder:text-foreground/25 text-foreground"
|
||||
placeholder={editingNode.parentId ? t('brainstorm.canvasPlaceholderReply') : t('brainstorm.canvasPlaceholderIdea')}
|
||||
className="w-full px-3 py-2.5 text-sm font-serif bg-black/[0.03] dark:bg-white/[0.06] border border-black/[0.06] dark:border-white/[0.12] rounded-xl outline-none focus:border-brand-accent/50 focus:bg-white dark:focus:bg-white/[0.08] transition-all placeholder:text-foreground/25 text-foreground"
|
||||
/>
|
||||
<div className="flex items-center justify-between mt-1.5 px-0.5">
|
||||
<div className="flex items-center gap-2.5">
|
||||
<kbd className="text-[9px] text-foreground/30 font-mono bg-black/[0.04] px-1.5 py-0.5 rounded">↵</kbd>
|
||||
<span className="text-[9px] text-foreground/25">enregistrer</span>
|
||||
<span className="text-[9px] text-foreground/25">{t('brainstorm.canvasShortcutSave')}</span>
|
||||
<kbd className="text-[9px] text-foreground/30 font-mono bg-black/[0.04] px-1.5 py-0.5 rounded">esc</kbd>
|
||||
<span className="text-[9px] text-foreground/25">annuler</span>
|
||||
<span className="text-[9px] text-foreground/25">{t('brainstorm.canvasShortcutCancel')}</span>
|
||||
</div>
|
||||
{editingNode.parentId && (
|
||||
<span className="text-[9px] font-medium text-memento-blue/60 flex items-center gap-0.5">
|
||||
→ enfant
|
||||
<span className="text-[9px] font-medium text-brand-accent/60 flex items-center gap-0.5">
|
||||
→ {t('brainstorm.canvasChildBranch')}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@@ -577,7 +579,7 @@ export const WaveCanvas: React.FC<WaveCanvasProps> = ({
|
||||
|
||||
<div className="absolute bottom-6 left-6 pointer-events-none">
|
||||
<p className="text-[10px] font-bold tracking-[0.3em] uppercase text-gray-400 dark:text-gray-600 opacity-60">
|
||||
Double-clic pour ajouter une idée
|
||||
{t('brainstorm.canvasDoubleClickHint')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user