feat: self-serve signup Phase 2 (frontend cutover) (#162)
Co-authored-by: Michael Chihlas <michael@resolutionflow.com> Co-committed-by: Michael Chihlas <michael@resolutionflow.com>
This commit was merged in pull request #162.
This commit is contained in:
56
frontend/src/components/common/EmailVerificationGate.tsx
Normal file
56
frontend/src/components/common/EmailVerificationGate.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import type { ReactNode } from 'react'
|
||||
import { useAuthStore } from '@/store/authStore'
|
||||
import { EmailVerificationWall } from './EmailVerificationWall'
|
||||
|
||||
interface EmailVerificationGateProps {
|
||||
children: ReactNode
|
||||
/**
|
||||
* Override the grace period (in days). Day `gracePeriodDays + 1` and beyond
|
||||
* trigger the wall. Defaults to 6 — the spec says Day 1–6 unverified renders
|
||||
* children and Day 7+ renders the wall.
|
||||
*/
|
||||
gracePeriodDays?: number
|
||||
}
|
||||
|
||||
const MS_PER_DAY = 24 * 60 * 60 * 1000
|
||||
|
||||
/** Whole days elapsed between two ISO timestamps (floored). */
|
||||
function daysSince(iso: string, now: number = Date.now()): number {
|
||||
const created = Date.parse(iso)
|
||||
if (Number.isNaN(created)) {
|
||||
// Defensive: bad timestamp — treat as just-signed-up so we don't
|
||||
// accidentally lock anyone out.
|
||||
return 0
|
||||
}
|
||||
return Math.floor((now - created) / MS_PER_DAY)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps protected content. While the current user is past the grace period
|
||||
* without having verified their email, renders `<EmailVerificationWall />`
|
||||
* instead of children.
|
||||
*
|
||||
* Behavior:
|
||||
* - No user (signed out): renders children (let route guards handle auth).
|
||||
* - User has `email_verified_at`: renders children.
|
||||
* - Day 1–6 unverified: renders children (banner is shown elsewhere).
|
||||
* - Day 7+ unverified: renders the wall.
|
||||
*/
|
||||
export function EmailVerificationGate({
|
||||
children,
|
||||
gracePeriodDays = 6,
|
||||
}: EmailVerificationGateProps) {
|
||||
const user = useAuthStore((s) => s.user)
|
||||
|
||||
if (!user) return <>{children}</>
|
||||
if (user.email_verified_at) return <>{children}</>
|
||||
|
||||
const elapsed = daysSince(user.created_at)
|
||||
if (elapsed > gracePeriodDays) {
|
||||
return <EmailVerificationWall />
|
||||
}
|
||||
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
export default EmailVerificationGate
|
||||
Reference in New Issue
Block a user