feat: dashboard Second Brain, essai 7 jours et vérification e-mail
All checks were successful
CI / Lint, Unit Tests & Build (push) Successful in 7m14s
CI / Deploy production (on server) (push) Successful in 1m25s

Rendre le dashboard actionnable (inbox, peek, carte mentale), aligner la facturation sur l’essai 7 jours, et bloquer le login e-mail tant que l’adresse n’est pas confirmée.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Antigravity
2026-08-30 07:19:36 +00:00
parent 69c99e4f4f
commit 80ccc1f6de
95 changed files with 4158 additions and 618 deletions

View File

@@ -50,8 +50,10 @@ function elementOpacity(
state: StepResolvedState,
dim: number
): number {
// Overview = full scene at full brightness (matches edges behavior)
if (state.overview) return 1
if (!(id in state.revealed)) return 0
if (state.overview || state.spotlight.length === 0) return 1
if (state.spotlight.length === 0) return 1
return state.spotlight.includes(id) ? 1 : dim
}
@@ -750,6 +752,11 @@ function HeatmapPanel({
const dim = dimOpacity(dark)
const fillIntent = spotlightColor(dark)
const ghostStroke = dark ? 'rgba(255,255,255,0.2)' : 'rgba(0,0,0,0.16)'
// Intensity ∝ value — normalized so real-world scales (not just [0,1]) work
const maxAbsV = Math.max(
1e-9,
...values.flat().map((v) => Math.abs(v))
)
const cellRect = (r: number, c: number) => ({
x: labelW + (c - 1) * cell,
@@ -778,8 +785,23 @@ function HeatmapPanel({
return map
}, [rows, cols, triangular])
const uid = useId().replace(/:/g, '')
const markerId = `demo-arrowhead-hm-${uid}`
return (
<svg viewBox={`0 0 ${w} ${h}`} className="w-full h-auto max-w-lg mx-auto">
<defs>
<marker
id={markerId}
markerWidth="9"
markerHeight="9"
refX="7"
refY="3.5"
orient="auto"
>
<path d="M0,0 L7,3.5 L0,7 Z" fill={fillIntent} />
</marker>
</defs>
{colLabels?.map((lab, i) => (
<text
key={`c-${i}`}
@@ -839,9 +861,10 @@ function HeatmapPanel({
)
}
const fillOpacity = 0.14 + v * 0.78
const vNorm = Math.min(1, Math.abs(v) / maxAbsV)
const fillOpacity = 0.14 + vNorm * 0.78
const textFill =
v > 0.45 ? (dark ? '#0a0a0a' : '#fff') : dark ? '#eee' : '#111'
vNorm > 0.45 ? (dark ? '#0a0a0a' : '#fff') : dark ? '#eee' : '#111'
return (
<g key={id} opacity={op} style={{ transition }}>
@@ -874,7 +897,7 @@ function HeatmapPanel({
<AnnotationsOverlay
annotations={state.annotations}
dark={dark}
markerId="demo-arrowhead-hm"
markerId={markerId}
getAnchor={(id, kind) => {
const p = positions.get(id)
if (!p) return null