1+ 'use client' ;
2+
3+ import { useToast } from "@/components/hooks/use-toast" ;
4+ import { ToastAction } from "@/components/ui/toast" ;
5+ import { useEffect } from "react" ;
6+ import { GitHubLogoIcon } from "@radix-ui/react-icons" ;
7+ import { captureEvent } from "@/hooks/useCaptureEvent" ;
8+
9+ const POPUP_SHOWN_COOKIE = "github_popup_shown" ;
10+ const POPUP_START_TIME_COOKIE = "github_popup_start_time" ;
11+ const POPUP_DELAY_S = 60 ;
12+ const SOURCEBOT_GITHUB_URL = "https://github.com/sourcebot-dev/sourcebot" ;
13+
14+ function getCookie ( name : string ) : string | null {
15+ if ( typeof document === "undefined" ) return null ;
16+
17+ const cookies = document . cookie . split ( ';' ) . map ( cookie => cookie . trim ( ) ) ;
18+ const targetCookie = cookies . find ( cookie => cookie . startsWith ( `${ name } =` ) ) ;
19+
20+ if ( ! targetCookie ) return null ;
21+
22+ return targetCookie . substring ( `${ name } =` . length ) ;
23+ }
24+
25+ function setCookie ( name : string , value : string , days : number = 365 ) {
26+ if ( typeof document === "undefined" ) return ;
27+
28+ try {
29+ const expires = new Date ( ) ;
30+ expires . setTime ( expires . getTime ( ) + ( days * 24 * 60 * 60 * 1000 ) ) ;
31+ document . cookie = `${ name } =${ value } ; expires=${ expires . toUTCString ( ) } ; path=/; SameSite=Lax` ;
32+ } catch ( error ) {
33+ console . warn ( 'Failed to set GitHub popup cookie:' , error ) ;
34+ }
35+ }
36+
37+ export const GitHubStarToast = ( ) => {
38+ const { toast } = useToast ( ) ;
39+
40+ useEffect ( ( ) => {
41+ const hasShownPopup = getCookie ( POPUP_SHOWN_COOKIE ) ;
42+ const startTime = getCookie ( POPUP_START_TIME_COOKIE ) ;
43+
44+ if ( hasShownPopup ) {
45+ return ;
46+ }
47+
48+ const currentTime = Date . now ( ) ;
49+ if ( ! startTime ) {
50+ setCookie ( POPUP_START_TIME_COOKIE , currentTime . toString ( ) ) ;
51+ return ;
52+ }
53+
54+ const elapsed = currentTime - parseInt ( startTime , 10 ) ;
55+ if ( elapsed >= ( POPUP_DELAY_S * 1000 ) ) {
56+ toast ( {
57+ title : "Star us on GitHub ❤️" ,
58+ description : "If you've found Sourcebot useful, please consider starring us on GitHub. Your support means a lot!" ,
59+ duration : 15 * 1000 ,
60+ action : (
61+ < div className = "flex flex-col gap-1" >
62+ < ToastAction
63+ altText = "GitHub Button"
64+ onClick = { ( ) => {
65+ captureEvent ( 'wa_github_star_toast_clicked' , { } ) ;
66+ window . open ( SOURCEBOT_GITHUB_URL , "_blank" ) ;
67+ } }
68+ >
69+ < div className = "flex items-center gap-2" >
70+ < GitHubLogoIcon className = "w-4 h-4" />
71+ Sourcebot
72+ </ div >
73+ </ ToastAction >
74+ </ div >
75+ )
76+ } ) ;
77+
78+ captureEvent ( 'wa_github_star_toast_displayed' , { } ) ;
79+ setCookie ( POPUP_SHOWN_COOKIE , "true" ) ;
80+ }
81+ } , [ toast ] ) ;
82+
83+ return null ;
84+ }
0 commit comments