feat: dashboard Second Brain, essai 7 jours et vérification e-mail
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:
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user