@@ -21,13 +21,113 @@ import {
2121 IconHeadphones ,
2222 IconBrandDiscord ,
2323 IconPlayerPlay ,
24- IconSlideshow
24+ IconSlideshow ,
25+ IconSparkles ,
26+ IconCheck
2527} from "@tabler/icons-react"
2628import { cn } from "@utils/cn"
2729import { usePlan } from "@hooks/usePlan"
2830import { motion , AnimatePresence } from "framer-motion"
2931import useClickOutside from "@hooks/useClickOutside"
3032
33+ const proPlanFeatures = [
34+ { name : "Text Chat" , limit : "100 messages per day" } ,
35+ { name : "Voice Chat" , limit : "10 minutes per day" } ,
36+ { name : "One-Time Tasks" , limit : "20 async tasks per day" } ,
37+ { name : "Recurring Tasks" , limit : "10 active recurring workflows" } ,
38+ { name : "Triggered Tasks" , limit : "10 triggered workflows" } ,
39+ {
40+ name : "Parallel Agents" ,
41+ limit : "5 complex tasks per day with 50 sub agents"
42+ } ,
43+ { name : "File Uploads" , limit : "20 files per day" } ,
44+ { name : "Memories" , limit : "Unlimited memories" } ,
45+ {
46+ name : "Other Integrations" ,
47+ limit : "Notion, GitHub, Slack, Discord, Trello"
48+ }
49+ ]
50+
51+ const UpgradeToProModal = ( { isOpen, onClose } ) => {
52+ if ( ! isOpen ) return null
53+
54+ const handleUpgrade = ( ) => {
55+ const dashboardUrl = process . env . NEXT_PUBLIC_LANDING_PAGE_URL
56+ if ( dashboardUrl ) {
57+ window . open ( `${ dashboardUrl } /dashboard` , "_blank" )
58+ }
59+ onClose ( )
60+ }
61+
62+ return (
63+ < AnimatePresence >
64+ { isOpen && (
65+ < motion . div
66+ initial = { { opacity : 0 } }
67+ animate = { { opacity : 1 } }
68+ exit = { { opacity : 0 } }
69+ className = "fixed inset-0 bg-black/70 backdrop-blur-md z-[100] flex items-center justify-center p-4"
70+ onClick = { onClose }
71+ >
72+ < motion . div
73+ initial = { { scale : 0.95 , y : 20 } }
74+ animate = { { scale : 1 , y : 0 } }
75+ exit = { { scale : 0.95 , y : - 20 } }
76+ transition = { { duration : 0.2 , ease : "easeInOut" } }
77+ onClick = { ( e ) => e . stopPropagation ( ) }
78+ className = "relative bg-neutral-900/90 backdrop-blur-xl p-6 rounded-2xl shadow-2xl w-full max-w-md border border-neutral-700 flex flex-col"
79+ >
80+ < header className = "text-center mb-6" >
81+ < h2 className = "text-2xl font-bold text-white flex items-center justify-center gap-2" >
82+ < IconSparkles className = "text-brand-orange" />
83+ Upgrade to Pro
84+ </ h2 >
85+ < p className = "text-neutral-400 mt-2" >
86+ For professionals who want to conquer their day.
87+ </ p >
88+ </ header >
89+ < main className = "space-y-3" >
90+ { proPlanFeatures . map ( ( feature ) => (
91+ < div
92+ key = { feature . name }
93+ className = "flex items-start gap-3"
94+ >
95+ < IconCheck
96+ size = { 20 }
97+ className = "text-green-400 flex-shrink-0 mt-0.5"
98+ />
99+ < div >
100+ < p className = "text-white font-medium" >
101+ { feature . name }
102+ </ p >
103+ < p className = "text-neutral-400 text-sm" >
104+ { feature . limit }
105+ </ p >
106+ </ div >
107+ </ div >
108+ ) ) }
109+ </ main >
110+ < footer className = "mt-8 flex flex-col gap-2" >
111+ < button
112+ onClick = { handleUpgrade }
113+ className = "w-full py-3 px-5 rounded-lg bg-brand-orange hover:bg-brand-orange/90 text-brand-black font-semibold transition-colors"
114+ >
115+ Upgrade to Pro - $9/month
116+ </ button >
117+ < button
118+ onClick = { onClose }
119+ className = "w-full py-2 px-5 rounded-lg hover:bg-neutral-800 text-sm font-medium text-neutral-400"
120+ >
121+ Not now
122+ </ button >
123+ </ footer >
124+ </ motion . div >
125+ </ motion . div >
126+ ) }
127+ </ AnimatePresence >
128+ )
129+ }
130+
31131const UserProfileSection = ( { isCollapsed, user } ) => {
32132 const [ isUserMenuOpen , setUserMenuOpen ] = useState ( false )
33133 const userMenuRef = useRef ( null )
@@ -233,6 +333,7 @@ const SidebarContent = ({
233333 const pathname = usePathname ( )
234334 const [ isHelpMenuOpen , setHelpMenuOpen ] = useState ( false )
235335 const [ isVideoModalOpen , setVideoModalOpen ] = useState ( false )
336+ const [ isUpgradeModalOpen , setUpgradeModalOpen ] = useState ( false )
236337 const router = useRouter ( )
237338
238339 // CHANGED: Use the environment variable for the namespace
@@ -269,6 +370,10 @@ const SidebarContent = ({
269370
270371 return (
271372 < div className = "flex flex-col h-full w-full overflow-y-auto custom-scrollbar" >
373+ < UpgradeToProModal
374+ isOpen = { isUpgradeModalOpen }
375+ onClose = { ( ) => setUpgradeModalOpen ( false ) }
376+ />
272377 < AnimatePresence >
273378 { isVideoModalOpen && (
274379 < HelpVideoModal onClose = { ( ) => setVideoModalOpen ( false ) } />
@@ -341,9 +446,8 @@ const SidebarContent = ({
341446 </ button >
342447
343448 { ! isPro && (
344- < a
345- href = { dashboardUrl }
346- rel = "noopener noreferrer"
449+ < button
450+ onClick = { ( ) => setUpgradeModalOpen ( true ) }
347451 className = { cn (
348452 "w-full bg-neutral-800/40 border border-neutral-700/80 rounded-lg p-2.5 text-left mb-2 hover:bg-neutral-800/80 transition-colors" ,
349453 isCollapsed && "flex justify-center"
@@ -371,7 +475,7 @@ const SidebarContent = ({
371475 ) }
372476 </ AnimatePresence >
373477 </ div >
374- </ a >
478+ </ button >
375479 ) }
376480
377481 < nav className = "flex flex-col gap-1 flex-grow overflow-hidden" >
0 commit comments