@@ -20,6 +20,8 @@ import { useOrgBillingMode } from "./data/billing-mode/org-billing-mode-query";
2020import { Organization } from "@gitpod/public-api/lib/gitpod/v1/organization_pb" ;
2121import { MaintenanceModeBanner } from "./org-admin/MaintenanceModeBanner" ;
2222import { MaintenanceNotificationBanner } from "./org-admin/MaintenanceNotificationBanner" ;
23+ import { useToast } from "./components/toasts/Toasts" ;
24+ import { getPrimaryEmail } from "@gitpod/public-api-common/lib/user-utils" ;
2325import onaWordmark from "./images/ona-wordmark.svg" ;
2426
2527const KEY_APP_DISMISSED_NOTIFICATIONS = "gitpod-app-notifications-dismissed" ;
@@ -129,36 +131,84 @@ const INVALID_BILLING_ADDRESS = (stripePortalUrl: string | undefined) => {
129131 } as Notification ;
130132} ;
131133
132- const GITPOD_CLASSIC_SUNSET = {
133- id : "gitpod-classic-sunset" ,
134- type : "info" as AlertType ,
135- message : (
136- < span className = "text-md text-white font-semibold items-center justify-center" >
137- Meet < img src = { onaWordmark } alt = "Ona" className = "inline align-middle w-12 mb-0.5" draggable = "false" /> | the
138- privacy-first software engineering agent |{ " " }
139- < a href = "https://ona.com/" target = "_blank" rel = "noreferrer" className = "underline hover:no-underline" >
140- Get early access
141- </ a >
142- </ span >
143- ) ,
144- } as Notification ;
134+ const GITPOD_CLASSIC_SUNSET = (
135+ user : User | undefined ,
136+ toast : any ,
137+ onaClicked : boolean ,
138+ handleOnaBannerClick : ( ) => void ,
139+ ) => {
140+ return {
141+ id : "gitpod-classic-sunset" ,
142+ type : "info" as AlertType ,
143+ message : (
144+ < span className = "text-md text-white font-semibold items-center justify-center" >
145+ Meet < img src = { onaWordmark } alt = "Ona" className = "inline align-middle w-12 mb-0.5" draggable = "false" /> |
146+ the privacy-first software engineering agent |{ " " }
147+ { ! onaClicked ? (
148+ < button
149+ onClick = { handleOnaBannerClick }
150+ className = "underline hover:no-underline cursor-pointer bg-transparent border-none text-white font-semibold"
151+ >
152+ Get early access
153+ </ button >
154+ ) : (
155+ < a
156+ href = "https://www.gitpod.io/solutions/ai"
157+ target = "_blank"
158+ rel = "noreferrer"
159+ className = "underline hover:no-underline"
160+ >
161+ Learn more
162+ </ a >
163+ ) }
164+ </ span >
165+ ) ,
166+ } as Notification ;
167+ } ;
145168
146169export function AppNotifications ( ) {
147170 const [ topNotification , setTopNotification ] = useState < Notification | undefined > ( undefined ) ;
171+ const [ onaClicked , setOnaClicked ] = useState ( false ) ;
148172 const { user, loading } = useUserLoader ( ) ;
149173 const { mutateAsync } = useUpdateCurrentUserMutation ( ) ;
174+ const { toast } = useToast ( ) ;
150175
151176 const currentOrg = useCurrentOrg ( ) . data ;
152177 const { data : billingMode } = useOrgBillingMode ( ) ;
153178
179+ useEffect ( ( ) => {
180+ const storedOnaData = localStorage . getItem ( "ona-banner-data" ) ;
181+ if ( storedOnaData ) {
182+ const { clicked } = JSON . parse ( storedOnaData ) ;
183+ setOnaClicked ( clicked || false ) ;
184+ }
185+ } , [ ] ) ;
186+
187+ const handleOnaBannerClick = useCallback ( ( ) => {
188+ const userEmail = user ? getPrimaryEmail ( user ) || "" : "" ;
189+ trackEvent ( "waitlist_joined" , { email : userEmail , feature : "Ona" } ) ;
190+
191+ setOnaClicked ( true ) ;
192+ const existingData = localStorage . getItem ( "ona-banner-data" ) ;
193+ const parsedData = existingData ? JSON . parse ( existingData ) : { } ;
194+ localStorage . setItem ( "ona-banner-data" , JSON . stringify ( { ...parsedData , clicked : true } ) ) ;
195+
196+ toast (
197+ < div >
198+ < div className = "font-medium" > You're on the waitlist</ div >
199+ < div className = "text-sm opacity-80" > We'll reach out to you soon.</ div >
200+ </ div > ,
201+ ) ;
202+ } , [ user , toast ] ) ;
203+
154204 useEffect ( ( ) => {
155205 let ignore = false ;
156206
157207 const updateNotifications = async ( ) => {
158208 const notifications = [ ] ;
159209 if ( ! loading ) {
160210 if ( isGitpodIo ( ) ) {
161- notifications . push ( GITPOD_CLASSIC_SUNSET ) ;
211+ notifications . push ( GITPOD_CLASSIC_SUNSET ( user , toast , onaClicked , handleOnaBannerClick ) ) ;
162212 }
163213
164214 if (
@@ -192,7 +242,7 @@ export function AppNotifications() {
192242 return ( ) => {
193243 ignore = true ;
194244 } ;
195- } , [ loading , mutateAsync , user , currentOrg , billingMode ] ) ;
245+ } , [ loading , mutateAsync , user , currentOrg , billingMode , onaClicked , handleOnaBannerClick , toast ] ) ;
196246
197247 const dismissNotification = useCallback ( ( ) => {
198248 if ( ! topNotification ) {
0 commit comments