-
+
More integrations are coming soon! Have a suggestion? Share it with us
on{" "}
X
@@ -566,9 +566,9 @@ export function IntegrationsView() {
{/* API Key Modal */}
-
+
-
+
Setup{" "}
{selectedShortcutType === "add"
? "Add Memory"
@@ -584,7 +584,7 @@ export function IntegrationsView() {
Your API Key
@@ -594,16 +594,16 @@ export function IntegrationsView() {
type="text"
value={apiKey}
readOnly
- className="flex-1 bg-white/5 border border-white/20 rounded-lg px-3 py-2 text-sm text-white font-mono"
+ className="flex-1 bg-muted border border-border rounded-lg px-3 py-2 text-sm text-foreground font-mono"
/>
{copied ? (
-
+
) : (
)}
@@ -613,31 +613,31 @@ export function IntegrationsView() {
{/* Steps */}
-
+
Follow these steps:
-
+
1
-
+
Click "Add to Shortcuts" below to open the shortcut
-
+
2
-
+
Paste your API key when prompted
-
+
3
-
+
Start using your shortcut!
diff --git a/apps/web/components/views/profile.tsx b/apps/web/components/views/profile.tsx
index 336b9416..7a6699c4 100644
--- a/apps/web/components/views/profile.tsx
+++ b/apps/web/components/views/profile.tsx
@@ -1,80 +1,64 @@
-"use client";
+"use client"
-import { authClient } from "@lib/auth";
-import { useAuth } from "@lib/auth-context";
+import { useAuth } from "@lib/auth-context"
import {
fetchConnectionsFeature,
fetchMemoriesFeature,
fetchSubscriptionStatus,
-} from "@lib/queries";
-import { Button } from "@repo/ui/components/button";
-import { HeadingH3Bold } from "@repo/ui/text/heading/heading-h3-bold";
-import { useCustomer } from "autumn-js/react";
-import {
- CheckCircle,
- CreditCard,
- LoaderIcon,
- LogOut,
- User,
- X,
-} from "lucide-react";
-import { motion } from "motion/react";
-import Link from "next/link";
-import { usePathname, useRouter } from "next/navigation";
-import { useState } from "react";
-import { analytics } from "@/lib/analytics";
+} from "@lib/queries"
+import { Button } from "@repo/ui/components/button"
+import { Skeleton } from "@repo/ui/components/skeleton"
+import { HeadingH3Bold } from "@repo/ui/text/heading/heading-h3-bold"
+import { useCustomer } from "autumn-js/react"
+import { CheckCircle, CreditCard, LoaderIcon, User, X } from "lucide-react"
+import { motion } from "motion/react"
+import Link from "next/link"
+import { useState } from "react"
export function ProfileView() {
- const router = useRouter();
- const pathname = usePathname();
- const { user: session, org } = useAuth();
- const organizations = org;
- const autumn = useCustomer();
- const [isLoading, setIsLoading] = useState(false);
+ const { user: session, org } = useAuth()
+ const organizations = org
+ const autumn = useCustomer()
+ const [isLoading, setIsLoading] = useState(false)
- const { data: memoriesCheck } = fetchMemoriesFeature(autumn as any);
- const memoriesUsed = memoriesCheck?.usage ?? 0;
- const memoriesLimit = memoriesCheck?.included_usage ?? 0;
-
- const { data: connectionsCheck } = fetchConnectionsFeature(autumn as any);
- const connectionsUsed = connectionsCheck?.usage ?? 0;
-
- // Fetch subscription status with React Query
const {
data: status = {
consumer_pro: null,
},
isLoading: isCheckingStatus,
- } = fetchSubscriptionStatus(autumn as any);
+ } = fetchSubscriptionStatus(autumn, !autumn.isLoading)
- const isPro = status.consumer_pro;
+ const isPro = status.consumer_pro
- const handleLogout = () => {
- analytics.userSignedOut();
- authClient.signOut();
- router.push("/login");
- };
+ const { data: memoriesCheck } = fetchMemoriesFeature(
+ autumn,
+ !isCheckingStatus && !autumn.isLoading,
+ )
+ const memoriesUsed = memoriesCheck?.usage ?? 0
+ const memoriesLimit = memoriesCheck?.included_usage ?? 0
+
+ const { data: connectionsCheck } = fetchConnectionsFeature(autumn)
+ const connectionsUsed = connectionsCheck?.usage ?? 0
const handleUpgrade = async () => {
- setIsLoading(true);
+ setIsLoading(true)
try {
await autumn.attach({
productId: "consumer_pro",
successUrl: "https://app.supermemory.ai/",
- });
- window.location.reload();
+ })
+ window.location.reload()
} catch (error) {
- console.error(error);
- setIsLoading(false);
+ console.error(error)
+ setIsLoading(false)
}
- };
+ }
- // Handle manage billing
const handleManageBilling = async () => {
await autumn.openBillingPortal({
returnUrl: "https://app.supermemory.ai",
- });
- };
+ })
+ }
if (session?.isAnonymous) {
return (
@@ -85,13 +69,13 @@ export function ProfileView() {
initial={{ opacity: 0, scale: 0.9 }}
transition={{ type: "spring", damping: 20 }}
>
-
+
Sign in to access your profile and billing
Sign in
@@ -99,95 +83,160 @@ export function ProfileView() {
- );
+ )
}
return (
{/* Profile Section */}
-
-
-
-
+
+
+
+ {session?.image ? (
+
+ ) : (
+
+ )}
-
-
{session?.email}
-
Logged in
+
+
+ {session?.name && (
+
+ {session.name}
+
+ )}
+
+ {session?.email}
+
+
+
+
+
+
+ {/* Additional Profile Details */}
+
+
+
+ Organization
+
+ {organizations?.name || "Personal"}
+
+
+
+ Member since
+
+ {session?.createdAt
+ ? new Date(session.createdAt).toLocaleDateString("en-US", {
+ month: "short",
+ year: "numeric",
+ })
+ : "Recent"}
+
+
{/* Billing Section */}
-
-
-
-
+ {autumn.isLoading || isCheckingStatus ? (
+
+
-
-
- {isPro ? "Pro Plan" : "Free Plan"}
- {isPro && (
-
- Active
-
- )}
-
-
- {isPro ? "Expanded memory capacity" : "Basic plan"}
-
+
+
+
+
+
+
+
-
- {/* Usage Stats */}
-
-
-
Memories
-
= memoriesLimit ? "text-red-400" : "text-white/90"}`}
- >
- {memoriesUsed} / {memoriesLimit}
-
+ ) : (
+
+
+
+
+
+
+
+ {isPro ? "Pro Plan" : "Free Plan"}
+ {isPro && (
+
+ Active
+
+ )}
+
+
+ {isPro ? "Expanded memory capacity" : "Basic plan"}
+
+
-
-
= memoriesLimit
- ? "bg-red-500"
- : isPro
- ? "bg-green-500"
- : "bg-blue-500"
- }`}
- style={{
- width: `${Math.min((memoriesUsed / memoriesLimit) * 100, 100)}%`,
- }}
- />
-
-
- {isPro && (
-
-
Connections
-
- {connectionsUsed} / 10
-
+ {/* Usage Stats */}
+
+
+ Memories
+ = memoriesLimit ? "text-red-500" : "text-foreground"}`}
+ >
+ {memoriesUsed} / {memoriesLimit}
+
+
+
+
= memoriesLimit
+ ? "bg-red-500"
+ : isPro
+ ? "bg-green-500"
+ : "bg-blue-500"
+ }`}
+ style={{
+ width: `${Math.min((memoriesUsed / memoriesLimit) * 100, 100)}%`,
+ }}
+ />
+
- )}
- {/* Billing Actions */}
-
- {isPro ? (
-
+ {isPro && (
+
+ Connections
+
+ {connectionsUsed} / 10
+
+
+ )}
+
+ {/* Billing Actions */}
+
+ {isPro ? (
Manage Billing
-
- ) : (
-
+ ) : (
- Upgrading...
+ Upgrading...
+ Loading...
>
) : (
- "Upgrade to Pro - $15/month"
+ <>
+
+ Upgrade to Pro - $15/month
+
+ Upgrade to Pro
+ >
)}
-
- )}
-
-
-
- {/* Plan Comparison - Only show for free users */}
- {!isPro && (
-
-
- Upgrade to Pro
-
-
-
- {/* Free Plan */}
-
-
- Free Plan
-
-
-
-
- 200 memories
-
-
-
- No connections
-
-
-
- Basic search
-
-
-
-
- {/* Pro Plan */}
-
-
- Pro Plan
-
- Recommended
-
-
-
-
-
- 5000 memories
-
-
-
- 10 connections
-
-
-
- Advanced search
-
-
-
- Priority support
-
-
-
+ )}
-
- $15/month (only for first 100 users) • Cancel anytime. No questions
- asked.
-
+ {!isPro && (
+
+
+ {/* Free Plan */}
+
+
+ Free Plan
+
+
+
+
+ 200 memories
+
+
+
+ No connections
+
+
+
+ Basic search
+
+
+
+
+ {/* Pro Plan */}
+
+
+
+ Pro Plan
+
+ Recommended
+
+
+
+
+
+
+ 5000 memories
+
+
+
+ 10 connections
+
+
+
+ Advanced search
+
+
+
+ Priority support
+
+
+
+
+
+
+ $15/month (only for first 100 users) • Cancel anytime. No
+ questions asked.
+
+
+ )}
)}
-
-
-
- Sign Out
-
- );
+ )
}
diff --git a/packages/lib/queries.ts b/packages/lib/queries.ts
index 36338445..601cdfe2 100644
--- a/packages/lib/queries.ts
+++ b/packages/lib/queries.ts
@@ -3,13 +3,11 @@ import type { useCustomer } from "autumn-js/react"
export const fetchSubscriptionStatus = (
autumn: ReturnType
,
+ isEnabled: boolean,
) =>
useQuery({
queryFn: async () => {
const allPlans = [
- "pro",
- "memory_starter",
- "memory_growth",
"consumer_pro",
]
const statusMap: Record = {}
@@ -17,7 +15,7 @@ export const fetchSubscriptionStatus = (
await Promise.all(
allPlans.map(async (plan) => {
try {
- const res = await autumn.check({
+ const res = autumn.check({
productId: plan,
})
statusMap[plan] = res.data?.allowed ?? false
@@ -33,18 +31,20 @@ export const fetchSubscriptionStatus = (
queryKey: ["subscription-status"],
refetchInterval: 5000, // Refetch every 5 seconds
staleTime: 4000, // Consider data stale after 4 seconds
+ enabled: isEnabled,
})
// Feature checks
-export const fetchMemoriesFeature = (autumn: ReturnType) =>
+export const fetchMemoriesFeature = (autumn: ReturnType, isEnabled: boolean) =>
useQuery({
queryFn: async () => {
- const res = await autumn.check({ featureId: "memories" })
+ const res = autumn.check({ featureId: "memories" })
return res.data
},
queryKey: ["autumn-feature", "memories"],
staleTime: 30 * 1000, // 30 seconds
gcTime: 5 * 60 * 1000, // 5 minutes
+ enabled: isEnabled,
})
export const fetchConnectionsFeature = (
@@ -52,7 +52,7 @@ export const fetchConnectionsFeature = (
) =>
useQuery({
queryFn: async () => {
- const res = await autumn.check({ featureId: "connections" })
+ const res = autumn.check({ featureId: "connections" })
return res.data
},
queryKey: ["autumn-feature", "connections"],
@@ -66,7 +66,7 @@ export const fetchConsumerProProduct = (
) =>
useQuery({
queryFn: async () => {
- const res = await autumn.check({ productId: "consumer_pro" })
+ const res = autumn.check({ productId: "consumer_pro" })
return res.data
},
queryKey: ["autumn-product", "consumer_pro"],
@@ -77,7 +77,7 @@ export const fetchConsumerProProduct = (
export const fetchProProduct = (autumn: ReturnType) =>
useQuery({
queryFn: async () => {
- const res = await autumn.check({ productId: "pro" })
+ const res = autumn.check({ productId: "pro" })
return res.data
},
queryKey: ["autumn-product", "pro"],
diff --git a/packages/ui/components/dropdown-menu.tsx b/packages/ui/components/dropdown-menu.tsx
index 5af01088..0ca71c0f 100644
--- a/packages/ui/components/dropdown-menu.tsx
+++ b/packages/ui/components/dropdown-menu.tsx
@@ -39,7 +39,7 @@ function DropdownMenuContent({