Add freemium variant C: archetype persistence, dashboard banner, lesson gate
- User.archetype/utmSource/utmMedium/utmCampaign fields + migration - register flow reads ?archetype/?utm_* and saves them on the User row - dashboard ArchetypeBanner: per-archetype 'твой путь' block - lesson gate after wow-moment lesson (WOW_MOMENT_LESSON_ID=obs-start-l2-006) → tripwire + full-course offer Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import { HomeworkSection } from "@/components/student/homework-section";
|
||||
import { QuizSection } from "@/components/student/quiz-section";
|
||||
import { LessonComments } from "@/components/student/lesson-comments";
|
||||
import { FileFormatBadge } from "@/components/shared/file-format-badge";
|
||||
import { TripwireGateBanner } from "@/components/student/tripwire-gate-banner";
|
||||
|
||||
interface Props {
|
||||
params: Promise<{ slug: string; lessonId: string }>;
|
||||
@@ -90,6 +91,8 @@ export default async function LessonPage({ params }: Props) {
|
||||
if (!lesson || lesson.module.course.slug !== slug) notFound();
|
||||
|
||||
const isCompleted = !!progress;
|
||||
const showTripwireGate =
|
||||
!isAdmin && isCompleted && lessonId === process.env.WOW_MOMENT_LESSON_ID;
|
||||
|
||||
// Build ordered flat list of all lessons for prev/next
|
||||
const allLessons = lesson.module.course.modules.flatMap((m) => m.lessons);
|
||||
@@ -267,6 +270,8 @@ export default async function LessonPage({ params }: Props) {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{showTripwireGate && <TripwireGateBanner />}
|
||||
|
||||
{/* Comments */}
|
||||
{session && (
|
||||
<div
|
||||
|
||||
@@ -3,6 +3,7 @@ import { auth } from "@/lib/auth";
|
||||
import { redirect } from "next/navigation";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import Link from "next/link";
|
||||
import { ArchetypeBanner } from "@/components/student/archetype-banner";
|
||||
|
||||
// Продаваемая линейка курсов → лендинг продукта. Курсы из этого списка,
|
||||
// которых нет у студента, показываются на дашборде заблюренными карточками
|
||||
@@ -19,6 +20,11 @@ export default async function StudentDashboard() {
|
||||
const session = await auth.api.getSession({ headers: await headers() });
|
||||
if (!session) redirect("/login");
|
||||
|
||||
const dbUser = await prisma.user.findUnique({
|
||||
where: { id: session.user.id },
|
||||
select: { archetype: true },
|
||||
});
|
||||
|
||||
const enrollments = await prisma.courseEnrollment.findMany({
|
||||
where: { userId: session.user.id },
|
||||
include: {
|
||||
@@ -79,6 +85,8 @@ export default async function StudentDashboard() {
|
||||
{active.length} активных курсов
|
||||
</p>
|
||||
|
||||
{dbUser?.archetype && <ArchetypeBanner archetype={dbUser.archetype} />}
|
||||
|
||||
{active.length === 0 ? (
|
||||
<div className="card-aubade p-12 text-center">
|
||||
<p className="text-4xl mb-3">📚</p>
|
||||
|
||||
Reference in New Issue
Block a user