Files
dataroom/pages/welcome.tsx
zeekay 9dff9e667e rip: enterprise dirs + paywalls — full AGPL, no commercial-license code
Drop the dual-licensed `ee/` tree entirely. All features previously
locked behind the Hanzo Dataroom Commercial License are now part of the
AGPL-3.0 core and freely available — custom domains, branded viewing,
advanced analytics, watermarks, access controls, Q&A, AI vector stores,
workflows, SAML SSO, dataroom invitations, conversations, templates.

Layout changes:
* `ee/features/{ai,conversations,workflows,permissions,storage,templates,
  dataroom-invitations,access-notifications,security,conversions}/` →
  `features/<name>/` (AGPL).
* `ee/limits/` → `lib/billing/limits/` with every plan resolving to an
  unlimited profile (no users/links/documents/domains/datarooms cap,
  conversations and watermarks always on).
* `ee/stripe/` → `lib/billing/legacy/` (already a compat shim over
  `@hanzoai/commerce`; renewal-reminder webhook is now a no-op).
* `ee/features/billing/cancellation/` deleted. Pause/unpause/cancel/
  retention routes now compile against `lib/billing/cancellation.ts`
  stubs that return 410 Gone; `isTeamPaused`/`isTeamPausedById` in
  `lib/billing/paused.ts` always report active. `CancellationModal` is
  a no-op shim in `components/billing/`.
* `app/(ee)/api/*` route group folded into `app/api/*` (SAML auth,
  SCIM, AI chat, workflows, FAQ, link-upload).

Build: `npm run build` green.
2026-06-07 11:46:48 -07:00

141 lines
5.3 KiB
TypeScript

import { useRouter } from "next/router";
import { useEffect, useRef } from "react";
import { useState } from "react";
import DataroomTemplates from "@/features/templates/components/dataroom-templates";
import { sendGTMEvent } from "@next/third-parties/google";
import { ArrowLeft as ArrowLeftIcon } from "lucide-react";
import { AnimatePresence } from "motion/react";
import { useSession } from "next-auth/react";
import { CustomUser } from "@/lib/types";
import { cn } from "@/lib/utils";
import { GTMComponent } from "@/components/gtm-component";
import { Button } from "@/components/ui/button";
import Dataroom from "@/components/welcome/dataroom";
import DataroomAIGenerate from "@/components/welcome/dataroom-ai-generate";
import DataroomChoice from "@/components/welcome/dataroom-choice";
import DataroomTrial from "@/components/welcome/dataroom-trial";
import DataroomUpload from "@/components/welcome/dataroom-upload";
import Intro from "@/components/welcome/intro";
import Next from "@/components/welcome/next";
import NotionForm from "@/components/welcome/notion-form";
import Select from "@/components/welcome/select";
import Upload from "@/components/welcome/upload";
export default function Welcome() {
const router = useRouter();
const [showSkipButtons, setShowSkipButtons] = useState(false);
const { data: session } = useSession();
const signupEventSent = useRef(false);
useEffect(() => {
const timer = setTimeout(() => {
setShowSkipButtons(true);
}, 10000);
return () => clearTimeout(timer);
}, []);
// Track signup for new users when welcome page loads (with deduplication)
useEffect(() => {
const user = session?.user as CustomUser;
if (user?.createdAt && !signupEventSent.current) {
// Check if user was created within the last 10 seconds (indicating new signup)
const isNewUser = new Date(user.createdAt).getTime() > Date.now() - 10000;
if (isNewUser) {
sendGTMEvent({ event: "signup" });
signupEventSent.current = true;
}
}
}, [session]);
const isDataroomUpload = router.query.type === "dataroom-upload";
const isDataroomChoice = router.query.type === "dataroom-choice";
const isDataroomTemplates = router.query.type === "dataroom-templates";
const isDataroomAIGenerate = router.query.type === "dataroom-ai-generate";
const skipButtonText =
isDataroomUpload || isDataroomChoice || isDataroomTemplates || isDataroomAIGenerate
? "Skip to dataroom"
: "Skip to dashboard";
const skipButtonPath =
(isDataroomUpload || isDataroomChoice || isDataroomTemplates) &&
router.query.dataroomId
? `/datarooms/${router.query.dataroomId}`
: "/documents";
return (
<>
<GTMComponent />
<div className="mx-auto flex h-screen max-w-3xl flex-col items-center justify-center overflow-x-hidden">
<AnimatePresence mode="wait">
{router.query.type ? (
<>
<button
className="group absolute left-2 top-10 z-40 rounded-full p-2 transition-all hover:bg-gray-400 sm:left-10"
onClick={() => router.back()}
>
<ArrowLeftIcon className="h-8 w-8 text-gray-500 group-hover:text-gray-800 group-active:scale-90" />
</button>
<Button
variant={"link"}
onClick={() => router.push(skipButtonPath)}
className={cn(
"absolute right-2 top-10 z-40 p-2 text-muted-foreground sm:right-10",
showSkipButtons ? "block" : "hidden",
)}
>
{skipButtonText}
</Button>
</>
) : (
<Intro key="intro" />
)}
{router.query.type === "next" && <Next key="next" />}
{router.query.type === "select" && <Select key="select" />}
{router.query.type === "pitchdeck" && <Upload key="pitchdeck" />}
{router.query.type === "document" && <Upload key="document" />}
{router.query.type === "sales-document" && (
<Upload key="sales-document" />
)}
{router.query.type === "notion" && <NotionForm key="notion" />}
{router.query.type === "dataroom" && <Dataroom key="dataroom" />}
{router.query.type === "dataroom-trial" && (
<DataroomTrial key="dataroom-trial" />
)}
{router.query.type === "dataroom-choice" &&
router.query.dataroomId && (
<DataroomChoice
key="dataroom-choice"
dataroomId={router.query.dataroomId as string}
/>
)}
{router.query.type === "dataroom-templates" &&
router.query.dataroomId && (
<DataroomTemplates
key="dataroom-templates"
dataroomId={router.query.dataroomId as string}
/>
)}
{router.query.type === "dataroom-upload" &&
router.query.dataroomId && (
<DataroomUpload
key="dataroom-upload"
dataroomId={router.query.dataroomId as string}
/>
)}
{router.query.type === "dataroom-ai-generate" && (
<DataroomAIGenerate key="dataroom-ai-generate" />
)}
</AnimatePresence>
</div>
</>
);
}