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

@@ -0,0 +1,55 @@
import { sendEmail } from '@/lib/mail'
function formatTrialEnd(date: Date, locale: string): string {
try {
return new Intl.DateTimeFormat(locale, {
day: 'numeric',
month: 'long',
year: 'numeric',
}).format(date)
} catch {
return date.toISOString().slice(0, 10)
}
}
/**
* Best-effort reminder ~3 days before Stripe ends a trial.
* Failures are logged by the caller; never throw to the webhook.
*/
export async function sendTrialEndingReminder(opts: {
to: string
name?: string | null
trialEndsAt: Date
billingUrl: string
locale?: string
}): Promise<{ success: boolean; error?: string }> {
const locale = opts.locale?.startsWith('fr') ? 'fr' : 'en'
const endLabel = formatTrialEnd(opts.trialEndsAt, locale === 'fr' ? 'fr-FR' : 'en-US')
const greet = opts.name?.trim() ? opts.name.trim() : locale === 'fr' ? 'Bonjour' : 'Hi'
const subject =
locale === 'fr'
? 'Votre essai Memento se termine bientôt'
: 'Your Memento trial is ending soon'
const html =
locale === 'fr'
? `
<p>${greet},</p>
<p>Votre période d'essai Memento se termine le <strong>${endLabel}</strong>.</p>
<p>Après cette date, votre abonnement démarrera automatiquement avec le moyen de paiement enregistré.</p>
<p>Pour gérer votre abonnement ou votre carte&nbsp;:</p>
<p><a href="${opts.billingUrl}">Ouvrir la facturation</a></p>
<p>— L'équipe Memento</p>
`
: `
<p>${greet},</p>
<p>Your Memento trial ends on <strong>${endLabel}</strong>.</p>
<p>After that date, your subscription will start automatically using the payment method on file.</p>
<p>To manage your subscription or card:</p>
<p><a href="${opts.billingUrl}">Open billing settings</a></p>
<p>— The Memento team</p>
`
return sendEmail({ to: opts.to, subject, html })
}