completely remove waitlist (#404)

This commit is contained in:
Dhravya 2025-09-01 07:12:37 +00:00
parent 31463406ce
commit 48e23c13ed
5 changed files with 34 additions and 287 deletions

View file

@ -510,7 +510,7 @@ const MemoryGraphPage = () => {
variant="consumer"
>
<div className="absolute inset-0 flex items-center justify-center">
<ConnectAIModal
<ConnectAIModal
onOpenChange={setShowConnectAIModal}
open={showConnectAIModal}
>
@ -566,7 +566,7 @@ const MemoryGraphPage = () => {
totalLoaded={totalLoaded}
>
<div className="absolute inset-0 flex items-center justify-center">
<ConnectAIModal
<ConnectAIModal
onOpenChange={setShowConnectAIModal}
open={showConnectAIModal}
>
@ -714,23 +714,6 @@ export default function Page() {
const router = useRouter();
const { user } = useAuth();
const { data: waitlistStatus, isLoading: isCheckingWaitlist } = useQuery({
queryKey: ["waitlist-status", user?.id],
queryFn: async () => {
try {
const response = await $fetch("@get/waitlist/status");
return response.data;
} catch (error) {
console.error("Error checking waitlist status:", error);
// Return null to indicate error, will handle in useEffect
return null;
}
},
enabled: !!user && !user.isAnonymous,
staleTime: 5 * 60 * 1000, // 5 minutes
retry: 1, // Only retry once on failure
});
useEffect(() => {
// save the token for chrome extension
const url = new URL(window.location.href);
@ -744,14 +727,8 @@ export default function Page() {
}
}, []);
useEffect(() => {
if (waitlistStatus && !waitlistStatus.accessGranted) {
router.push("/waitlist");
}
}, [waitlistStatus, router]);
// Show loading state while checking authentication and waitlist status
if (!user || isCheckingWaitlist) {
if (!user) {
return (
<div className="min-h-screen flex items-center justify-center bg-[#0f1419]">
<div className="flex flex-col items-center gap-4">

View file

@ -20,7 +20,6 @@ export default function ReferralPage() {
const params = useParams();
const referralCode = params.code as string;
const [isJoiningWaitlist, setIsJoiningWaitlist] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [referralData, setReferralData] = useState<{
referrerName?: string;
@ -56,18 +55,7 @@ export default function ReferralPage() {
checkReferral();
}, [referralCode]);
const handleJoinWaitlist = async () => {
setIsJoiningWaitlist(true);
try {
// Redirect to waitlist signup with referral code
router.push(`/waitlist?ref=${referralCode}`);
} catch (error) {
console.error("Error joining waitlist:", error);
toast.error("Failed to join waitlist. Please try again.");
} finally {
setIsJoiningWaitlist(false);
}
};
const handleCopyLink = async () => {
try {
@ -158,17 +146,6 @@ export default function ReferralPage() {
</p>
</div>
<Button
onClick={handleJoinWaitlist}
disabled={isJoiningWaitlist}
className="w-full bg-orange-500 hover:bg-orange-600 text-white"
>
{isJoiningWaitlist ? (
<LoaderIcon className="w-4 h-4 animate-spin" />
) : (
"Join the Waitlist"
)}
</Button>
<div className="text-center">
<Link

View file

@ -40,17 +40,10 @@ export default function ReferralHomePage() {
</p>
</div>
<Button
asChild
className="w-full bg-orange-500 hover:bg-orange-600 text-white"
>
<Link href="/waitlist">Join the Waitlist</Link>
</Button>
<div className="text-center">
<Link
href="https://supermemory.ai"
className="text-orange-500 hover:text-orange-400 text-sm underline"
href="https://supermemory.ai"
>
Learn more about supermemory
</Link>

View file

@ -1,216 +0,0 @@
"use client";
import { $fetch } from "@lib/api";
import { authClient } from "@lib/auth";
import { useAuth } from "@lib/auth-context";
import { fetchConsumerProProduct } from "@lib/queries";
import { Button } from "@ui/components/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@ui/components/card";
import { useCustomer } from "autumn-js/react";
import { Clock, LoaderIcon, LogOut, SkipForwardIcon } from "lucide-react";
import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import { useEffect, useState } from "react";
import { toast } from "sonner";
export default function WaitlistPage() {
const router = useRouter();
const searchParams = useSearchParams();
const referralCode = searchParams.get("ref");
const { user } = useAuth();
const [isChecking, setIsChecking] = useState(true);
const [isSkippingWaitlist, setIsSkippingWaitlist] = useState(false);
const [waitlistStatus, setWaitlistStatus] = useState<{
inWaitlist: boolean;
accessGranted: boolean;
createdAt: string;
} | null>(null);
const autumn = useCustomer();
const { data: earlyAccess } = fetchConsumerProProduct(autumn);
const handleSkipWaitlist = async () => {
setIsSkippingWaitlist(true);
try {
const res = await autumn.attach({
productId: "consumer_pro",
forceCheckout: true,
successUrl: "https://app.supermemory.ai/",
});
if (res.data && "checkout_url" in res.data && res.data.checkout_url) {
router.push(res.data.checkout_url);
}
} catch (error) {
console.error("Error skipping waitlist:", error);
} finally {
setIsSkippingWaitlist(false);
}
};
const handleLogout = async () => {
try {
await authClient.signOut();
router.push("/");
} catch (error) {
console.error("Error signing out:", error);
toast.error("Failed to sign out");
}
};
useEffect(() => {
async function checkAccess() {
if (!user) {
router.push("/");
return;
}
// Anonymous users should sign in first
if (user.isAnonymous) {
authClient.signOut();
router.push("/");
return;
}
try {
// Check waitlist status using the new endpoint
const response = await $fetch("@get/waitlist/status");
if (response.data) {
setWaitlistStatus(response.data);
if (!response.data.inWaitlist) {
authClient.signOut();
router.push("/login");
}
// If user has access, redirect to home
if (response.data.accessGranted) {
router.push("/");
}
}
} catch (error) {
console.error("Error checking waitlist status:", error);
// If there's an error, assume user is on waitlist
setWaitlistStatus({
inWaitlist: true,
accessGranted: false,
createdAt: new Date().toISOString(),
});
} finally {
setIsChecking(false);
}
}
checkAccess();
}, [user, router]);
if (isChecking) {
return (
<div className="min-h-screen flex items-center justify-center p-4 bg-[#0f1419]">
<div className="flex flex-col items-center gap-4">
<LoaderIcon className="w-8 h-8 text-orange-500 animate-spin" />
<p className="text-white/60">Checking access...</p>
</div>
</div>
);
}
return (
<div className="min-h-screen flex items-center justify-center p-4 bg-[#0f1419]">
<Card className="max-w-md w-full bg-[#1a1f2a] border-white/10">
<CardHeader className="text-center">
<div className="mx-auto mb-4 w-16 h-16 rounded-full bg-orange-500/10 flex items-center justify-center">
<Clock className="w-8 h-8 text-orange-500" />
</div>
<CardTitle className="text-2xl font-bold text-white">
You're on the waitlist!
</CardTitle>
<CardDescription className="text-white/60 mt-2">
{referralCode
? "Thanks for joining through a friend's invitation! You've been added to the waitlist with priority access."
: "Thanks for your interest in supermemory. We'll notify you as soon as we're ready for you."}
</CardDescription>
{referralCode && (
<div className="mt-3 px-3 py-2 bg-orange-500/10 rounded-lg border border-orange-500/20">
<p className="text-orange-400 text-sm font-medium">
🎉 Referred by a friend! You'll get priority access.
</p>
</div>
)}
</CardHeader>
<CardContent>
<div className="flex flex-col gap-4">
{!earlyAccess?.allowed && (
<Button
disabled={isSkippingWaitlist}
onClick={handleSkipWaitlist}
>
{isSkippingWaitlist ? (
<LoaderIcon className="w-4 h-4 animate-spin" />
) : (
<SkipForwardIcon className="w-4 h-4" />
)}
{isSkippingWaitlist
? "Processing..."
: "Skip the waitlist for $15"}
</Button>
)}
<div className="pt-4 border-t border-white/10">
<p className="text-white/60 text-sm">
We're working hard to bring you the best experience. In the
meantime, you can:
</p>
<ul className="mt-3 space-y-2 text-sm">
<li className="flex items-center gap-2 text-white/80">
<span className="text-orange-500"></span>
<a
className="hover:text-white transition-colors underline"
href="https://x.com/supermemoryai"
rel="noopener noreferrer"
target="_blank"
>
Follow our X for updates
</a>
</li>
<li className="flex items-center gap-2 text-white/80">
<span className="text-orange-500"></span>
<a
className="hover:text-white transition-colors underline"
href="https://supermemory.link/discord"
rel="noopener noreferrer"
target="_blank"
>
Join our community Discord
</a>
</li>
</ul>
</div>
{user && (
<div className="pt-4 text-center space-y-3">
<p className="text-white/50 text-xs">
Signed in as {user.email}
</p>
<Button
variant="outline"
size="sm"
onClick={handleLogout}
className="border-white/20 hover:bg-white/5"
>
<LogOut className="w-4 h-4 mr-2" />
Sign out
</Button>
</div>
)}
</div>
</CardContent>
</Card>
</div>
);
}

View file

@ -5,7 +5,15 @@ import { cn } from "@lib/utils";
import { Button } from "@ui/components/button";
import { Input } from "@ui/components/input";
import { DefaultChatTransport } from "ai";
import { ArrowUp, Check, Copy, RotateCcw, X, ChevronDown, ChevronRight } from "lucide-react";
import {
ArrowUp,
Check,
ChevronDown,
ChevronRight,
Copy,
RotateCcw,
X,
} from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { toast } from "sonner";
import { Streamdown } from "streamdown";
@ -41,8 +49,9 @@ function ExpandableMemories({ foundCount, results }: ExpandableMemoriesProps) {
return (
<div className="text-sm">
<button
onClick={() => setIsExpanded(!isExpanded)}
className="flex items-center gap-2 text-muted-foreground hover:text-foreground transition-colors"
onClick={() => setIsExpanded(!isExpanded)}
type="button"
>
{isExpanded ? (
<ChevronDown className="size-4" />
@ -52,12 +61,15 @@ function ExpandableMemories({ foundCount, results }: ExpandableMemoriesProps) {
<Check className="size-4" />
Found {foundCount} {foundCount === 1 ? "memory" : "memories"}
</button>
{isExpanded && results.length > 0 && (
<div className="mt-2 ml-6 space-y-2 max-h-48 overflow-y-auto">
{results.map((result, index) => {
const isClickable = result.url && (result.url.startsWith('http://') || result.url.startsWith('https://'));
const isClickable =
result.url &&
(result.url.startsWith("http://") ||
result.url.startsWith("https://"));
const content = (
<>
{result.title && (
@ -86,11 +98,11 @@ function ExpandableMemories({ foundCount, results }: ExpandableMemoriesProps) {
if (isClickable) {
return (
<a
key={result.documentId || index}
href={result.url}
target="_blank"
rel="noopener noreferrer"
className="block p-2 bg-white/5 rounded-md border border-white/10 hover:bg-white/10 hover:border-white/20 transition-colors cursor-pointer"
href={result.url}
key={result.documentId || index}
rel="noopener noreferrer"
target="_blank"
>
{content}
</a>
@ -99,8 +111,8 @@ function ExpandableMemories({ foundCount, results }: ExpandableMemoriesProps) {
return (
<div
key={result.documentId || index}
className="p-2 bg-white/5 rounded-md border border-white/10"
key={result.documentId || index}
>
{content}
</div>
@ -376,12 +388,16 @@ export function ChatMessages() {
"count" in output
? Number(output.count) || 0
: 0;
const results = Array.isArray(output?.results) ? output.results : [];
// @ts-expect-error
const results = Array.isArray(output?.results)
? // @ts-expect-error
output.results
: [];
return (
<ExpandableMemories
key={message.id + part.type}
foundCount={foundCount}
key={message.id + part.type}
results={results}
/>
);