Audit fixes: VIP self-grant, draft leak, onboarding flag, hero personalization, gated downloads
Deploy GitHub Pages / deploy (push) Canceled after 0s
Deploy GitHub Pages / deploy (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import Topnav from '@/components/topnav'
|
||||
import Footer from '@/components/footer'
|
||||
import { getPayload } from 'payload'
|
||||
import { headers } from 'next/headers'
|
||||
import configPromise from '@payload-config'
|
||||
import Link from 'next/link'
|
||||
import { redirect } from 'next/navigation'
|
||||
import OnboardingWizard from './client'
|
||||
import '../styles/member-onboarding.css'
|
||||
|
||||
export const dynamic = 'force-dynamic'
|
||||
export const metadata = { title: 'إعداد حسابك' }
|
||||
|
||||
/* Signup onboarding — design from member-onboarding.html. Interest + level
|
||||
persist to the user record (backend-aware, per locked decision). */
|
||||
export default async function OnboardingPage() {
|
||||
let viewer: { id: number; email: string; interest: string | null; level: string | null; onboarded: boolean } | null = null
|
||||
try {
|
||||
const payload = await getPayload({ config: configPromise })
|
||||
const { user } = await payload.auth({ headers: await headers() })
|
||||
if (user) {
|
||||
viewer = {
|
||||
id: user.id,
|
||||
email: user.email,
|
||||
interest: (user.interest as string | null) ?? null,
|
||||
level: (user.level as string | null) ?? null,
|
||||
onboarded: !!user.onboarded,
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
/* render wizard without persistence */
|
||||
}
|
||||
|
||||
if (!viewer) redirect('/login?next=%2Fonboarding')
|
||||
|
||||
return (
|
||||
<div id="site" className="site-page page-onboarding">
|
||||
<Topnav viewer={viewer} />
|
||||
<main id="content">
|
||||
<section className="head" data-od-id="onboarding-hero">
|
||||
<div className="container">
|
||||
<p className="eyebrow">حسابك جاهز · إعداد سريع</p>
|
||||
<h1 data-od-id="onboarding-title">اختر ما تريد تعلّمه أولاً.</h1>
|
||||
<p className="lead">سؤالان فقط لترتيب المكتبة حول هدفك، ثم نوضح الفرق بين الحساب المجاني والعضوية المدفوعة.</p>
|
||||
<div className="progress" aria-label="تقدم الإعداد">
|
||||
<div className="progress-copy"><span id="progressLabel">الخطوة 1 من 3</span><span id="progressPercent">33٪</span></div>
|
||||
<div className="progress-track"><div className="progress-bar" id="progressBar"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<OnboardingWizard viewer={viewer} />
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user