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:
@@ -24,10 +24,19 @@ interface NoteEditorPeekHostProps {
|
||||
export function NoteEditorPeekHost({ noteId, fullPage, children }: NoteEditorPeekHostProps) {
|
||||
const router = useRouter()
|
||||
const searchParams = useSearchParams()
|
||||
const peekNoteId = searchParams.get('peekNote')
|
||||
const { t, language } = useLanguage()
|
||||
const isRtl = language === 'fa' || language === 'ar'
|
||||
const [peekState, setPeekState] = useState<{ note: Note; blockId?: string } | null>(null)
|
||||
|
||||
const stripPeekFromUrl = useCallback(() => {
|
||||
if (!searchParams.get('peekNote')) return
|
||||
const params = new URLSearchParams(searchParams.toString())
|
||||
params.delete('peekNote')
|
||||
const qs = params.toString()
|
||||
router.replace(qs ? `/home?${qs}` : '/home', { scroll: false })
|
||||
}, [router, searchParams])
|
||||
|
||||
useEffect(() => {
|
||||
const onOpenPeek = (event: Event) => {
|
||||
const detail = (event as CustomEvent<NotePeekOpenDetail>).detail
|
||||
@@ -52,9 +61,25 @@ export function NoteEditorPeekHost({ noteId, fullPage, children }: NoteEditorPee
|
||||
}
|
||||
}, [noteId, t])
|
||||
|
||||
// Dashboard « Comparer / Lier » : ouvrir la note liée à droite dès que l’éditeur est monté.
|
||||
useEffect(() => {
|
||||
if (!peekNoteId || peekNoteId === noteId) return
|
||||
let cancelled = false
|
||||
void getNoteById(peekNoteId).then((fetched) => {
|
||||
if (cancelled) return
|
||||
if (fetched) {
|
||||
setPeekState(prev => (prev?.note.id === fetched.id ? prev : { note: fetched }))
|
||||
} else {
|
||||
toast.error(t('notePeek.loadFailed'))
|
||||
}
|
||||
})
|
||||
return () => { cancelled = true }
|
||||
}, [peekNoteId, noteId, t])
|
||||
|
||||
const handleClosePeek = useCallback(() => {
|
||||
setPeekState(null)
|
||||
}, [])
|
||||
stripPeekFromUrl()
|
||||
}, [stripPeekFromUrl])
|
||||
|
||||
const handleOpenPeekFully = useCallback(() => {
|
||||
if (!peekState) return
|
||||
@@ -63,6 +88,7 @@ export function NoteEditorPeekHost({ noteId, fullPage, children }: NoteEditorPee
|
||||
}))
|
||||
const params = new URLSearchParams(searchParams.toString())
|
||||
params.set('openNote', peekState.note.id)
|
||||
params.delete('peekNote')
|
||||
router.replace(params.toString() ? `/home?${params.toString()}` : '/home', { scroll: false })
|
||||
setPeekState(null)
|
||||
}, [noteId, peekState, router, searchParams])
|
||||
@@ -82,6 +108,11 @@ export function NoteEditorPeekHost({ noteId, fullPage, children }: NoteEditorPee
|
||||
blockId={peekState.blockId}
|
||||
onClose={handleClosePeek}
|
||||
onOpenFully={handleOpenPeekFully}
|
||||
onBackToDashboard={
|
||||
searchParams.get('from') === 'dashboard'
|
||||
? () => router.replace('/home')
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
Reference in New Issue
Block a user