mirror of
https://github.com/yusufipk/OpenFrame.git
synced 2026-09-11 17:46:06 +00:00
feat(onboarding): add onboarding wizard flow
- Add `onboardingCompletedAt` field to User model + migration - Add AUDIO/R2_AUDIO enum values to schema - Gate dashboard behind onboarding check; redirect to /onboarding if not completed - Add /onboarding page + layout with 5-step wizard (welcome, workspace, project, video info, notifications) - Add POST /api/onboarding/complete endpoint to mark onboarding done Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
d4f4220520
commit
31fda8a28c
@@ -14,6 +14,14 @@ export default async function DashboardPage({
|
|||||||
redirect('/login');
|
redirect('/login');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const userOnboarding = await db.user.findUnique({
|
||||||
|
where: { id: session.user.id },
|
||||||
|
select: { onboardingCompletedAt: true },
|
||||||
|
});
|
||||||
|
if (!userOnboarding?.onboardingCompletedAt) {
|
||||||
|
redirect('/onboarding');
|
||||||
|
}
|
||||||
|
|
||||||
const resolvedSearchParams = await searchParams;
|
const resolvedSearchParams = await searchParams;
|
||||||
const { ws, sort, page: pageParam } = resolvedSearchParams || {};
|
const { ws, sort, page: pageParam } = resolvedSearchParams || {};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { auth } from '@/lib/auth';
|
||||||
|
import { db } from '@/lib/db';
|
||||||
|
import { apiErrors, successResponse } from '@/lib/api-response';
|
||||||
|
|
||||||
|
export async function POST() {
|
||||||
|
const session = await auth();
|
||||||
|
if (!session?.user?.id) {
|
||||||
|
return apiErrors.unauthorized();
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.user.update({
|
||||||
|
where: { id: session.user.id },
|
||||||
|
data: { onboardingCompletedAt: new Date() },
|
||||||
|
});
|
||||||
|
|
||||||
|
return successResponse({ completed: true });
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
export default function OnboardingLayout({ children }: { children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-background flex items-center justify-center p-4">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { auth } from '@/lib/auth';
|
||||||
|
import { db } from '@/lib/db';
|
||||||
|
import { redirect } from 'next/navigation';
|
||||||
|
import { OnboardingWizard } from './onboarding-wizard';
|
||||||
|
|
||||||
|
export default async function OnboardingPage() {
|
||||||
|
const session = await auth();
|
||||||
|
if (!session?.user?.id) {
|
||||||
|
redirect('/login');
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await db.user.findUnique({
|
||||||
|
where: { id: session.user.id },
|
||||||
|
select: { onboardingCompletedAt: true, name: true, email: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (user?.onboardingCompletedAt) {
|
||||||
|
redirect('/dashboard');
|
||||||
|
}
|
||||||
|
|
||||||
|
const userName = user?.name || user?.email?.split('@')[0] || 'there';
|
||||||
|
|
||||||
|
return <OnboardingWizard userName={userName} />;
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS "onboardingCompletedAt" TIMESTAMP;
|
||||||
@@ -21,6 +21,7 @@ model User {
|
|||||||
password String? // Hashed password for email/password auth
|
password String? // Hashed password for email/password auth
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
onboardingCompletedAt DateTime?
|
||||||
|
|
||||||
// Relations
|
// Relations
|
||||||
accounts Account[]
|
accounts Account[]
|
||||||
@@ -70,12 +71,14 @@ enum DownloadEgressSource {
|
|||||||
enum VideoAssetKind {
|
enum VideoAssetKind {
|
||||||
IMAGE
|
IMAGE
|
||||||
VIDEO
|
VIDEO
|
||||||
|
AUDIO
|
||||||
}
|
}
|
||||||
|
|
||||||
enum VideoAssetProvider {
|
enum VideoAssetProvider {
|
||||||
R2_IMAGE
|
R2_IMAGE
|
||||||
YOUTUBE
|
YOUTUBE
|
||||||
BUNNY
|
BUNNY
|
||||||
|
R2_AUDIO
|
||||||
}
|
}
|
||||||
|
|
||||||
model DownloadEgressEvent {
|
model DownloadEgressEvent {
|
||||||
|
|||||||
Reference in New Issue
Block a user