import type React from "react"
import Link from "next/link"
import { Card, CardContent } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { AuthMethodSelector } from "@/app/components/authMethodSelector"
import { SourcebotLogo } from "@/app/components/sourcebotLogo"
import { auth } from "@/auth";
import { getIdentityProviderMetadata } from "@/lib/identityProviders";
import { OrganizationAccessSettings } from "@/app/components/organizationAccessSettings";
import { CompleteOnboardingButton } from "./components/completeOnboardingButton";
import { getOrgFromDomain } from "@/data/org";
import { SINGLE_TENANT_ORG_DOMAIN } from "@/lib/constants";
import { prisma } from "@/prisma";
import { OrgRole } from "@sourcebot/db";
import { LogoutEscapeHatch } from "@/app/components/logoutEscapeHatch";
import { redirect } from "next/navigation";
import { BetweenHorizontalStart, Brain, GitBranchIcon, LockIcon } from "lucide-react";
import { hasEntitlement } from "@sourcebot/shared";
import { env } from "@/env.mjs";
import { GcpIapAuth } from "@/app/[domain]/components/gcpIapAuth";
interface OnboardingProps {
searchParams?: Promise<{ step?: string }>;
}
interface OnboardingStep {
id: string
title: string
subtitle: React.ReactNode
component: React.ReactNode
}
interface ResourceCard {
id: string
title: string
description: string
href: string
icon?: React.ReactNode
}
export default async function Onboarding(props: OnboardingProps) {
const searchParams = await props.searchParams;
const providers = getIdentityProviderMetadata();
const org = await getOrgFromDomain(SINGLE_TENANT_ORG_DOMAIN);
const session = await auth();
if (!org) {
return
Error loading organization
;
}
if (org && org.isOnboarded) {
redirect('/');
}
// Check if user is authenticated but not the owner
if (session?.user) {
if (org) {
const membership = await prisma.userToOrg.findUnique({
where: {
orgId_userId: {
orgId: org.id,
userId: session.user.id
}
}
});
if (!membership || membership.role !== OrgRole.OWNER) {
return ;
}
}
}
// If we're using an IAP bridge we need to sign them in now and then redirect them back to the onboarding page
const ssoEntitlement = await hasEntitlement("sso");
if (ssoEntitlement && env.AUTH_EE_GCP_IAP_ENABLED && env.AUTH_EE_GCP_IAP_AUDIENCE) {
return ;
}
// Determine current step based on URL parameter and authentication state
const stepParam = searchParams?.step ? parseInt(searchParams.step) : 0;
const currentStep = session?.user ? Math.max(2, stepParam) : Math.max(0, Math.min(stepParam, 1));
const resourceCards: ResourceCard[] = [
{
id: "code-host-connections",
title: "Code Host Connections",
description: "Learn how to index repos across Sourcebot's supported platforms",
href: "https://docs.sourcebot.dev/docs/connections/overview",
icon: ,
},
{
id: "language-models",
title: "Language Models",
description: "Learn how to configure your language model providers to start using Ask Sourcebot",
href: "https://docs.sourcebot.dev/docs/configuration/language-model-providers",
icon: ,
},
{
id: "authentication-system",
title: "Authentication System",
description: "Learn how to setup additional auth providers, invite members, and more",
href: "https://docs.sourcebot.dev/docs/configuration/auth",
icon: ,
},
{
id: "mcp-server",
title: "MCP Server",
description: "Learn how to setup Sourcebot's MCP server to provide code context to your AI agents",
href: "https://docs.sourcebot.dev/docs/features/mcp-server",
icon: ,
}
]
const steps: OnboardingStep[] = [
{
id: "welcome",
title: "Welcome to Sourcebot",
subtitle: "This onboarding flow will guide you through creating your owner account and configuring your organization.",
component: (
),
},
{
id: "owner-signup",
title: "Create Owner Account",
subtitle: (
<>
Use your preferred authentication method to create your owner account. To set up additional authentication providers, check out our{" "}
documentation
.
>
),
component: (
),
},
{
id: "configure-org",
title: "Configure Access Settings",
subtitle: (
<>
Set up your organization's access settings.{" "}
Learn more
>
),
component: (
),
},
{
id: "complete",
title: "You're All Set!",
subtitle: (
<>
Your Sourcebot deployment is ready. Check out these resources to learn how to get the most out of Sourcebot.