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

@@ -1,6 +1,6 @@
'use client'
import { useState } from 'react'
import { useState, useRef } from 'react'
import { motion, AnimatePresence } from 'motion/react'
import { Search, Bot, ChevronLeft, ChevronRight, Loader2 } from 'lucide-react'
import { useLanguage } from '@/lib/i18n'
@@ -35,12 +35,22 @@ export function DashboardAgentCarousel({
}: DashboardAgentCarouselProps) {
const { t } = useLanguage()
const [idx, setIdx] = useState(0)
const directionRef = useRef(1)
const goPrev = () => {
directionRef.current = -1
setIdx(i => Math.max(0, i - 1))
}
const goNext = () => {
directionRef.current = 1
setIdx(i => Math.min(suggestions.length - 1, i + 1))
}
const navActions = suggestions.length > 1 ? (
<div className="flex items-center gap-1">
<button
type="button"
onClick={() => setIdx(i => Math.max(0, i - 1))}
onClick={goPrev}
disabled={idx === 0}
className="p-1 rounded border border-border/30 disabled:opacity-25"
aria-label={t('homeDashboard.intelPrev')}
@@ -52,7 +62,7 @@ export function DashboardAgentCarousel({
</span>
<button
type="button"
onClick={() => setIdx(i => Math.min(suggestions.length - 1, i + 1))}
onClick={goNext}
disabled={idx >= suggestions.length - 1}
className="p-1 rounded border border-border/30 disabled:opacity-25"
aria-label={t('homeDashboard.intelNext')}
@@ -84,6 +94,7 @@ export function DashboardAgentCarousel({
) : (
<AgentSlide
current={suggestions[idx]}
direction={directionRef.current}
actingId={actingId}
formatFrequency={formatFrequency}
onAccept={onAccept}
@@ -98,6 +109,7 @@ export function DashboardAgentCarousel({
function AgentSlide({
current,
direction,
actingId,
formatFrequency,
onAccept,
@@ -106,6 +118,7 @@ function AgentSlide({
t,
}: {
current: AgentSuggestion
direction: number
actingId: string | null
formatFrequency: (f: string) => string
onAccept: (id: string) => void
@@ -115,7 +128,11 @@ function AgentSlide({
}) {
const slide = prefersReducedMotion
? { initial: {}, animate: {}, exit: {} }
: { initial: { opacity: 0, y: 8 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: -8 } }
: {
initial: { opacity: 0, x: 14 * direction },
animate: { opacity: 1, x: 0 },
exit: { opacity: 0, x: -14 * direction },
}
return (
<AnimatePresence mode="wait">