Skip to content

Commit e79f36b

Browse files
committed
Don't show referral banner if codebuff account > 1 week old
1 parent a784106 commit e79f36b

File tree

4 files changed

+109
-1
lines changed

4 files changed

+109
-1
lines changed

web/src/app/api/user/profile/route.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export async function GET() {
2626
auto_topup_enabled: true,
2727
auto_topup_threshold: true,
2828
auto_topup_amount: true,
29+
created_at: true,
2930
},
3031
})
3132

@@ -43,6 +44,7 @@ export async function GET() {
4344
auto_topup_threshold: user.auto_topup_threshold ?? 500,
4445
auto_topup_amount: user.auto_topup_amount ?? 2000,
4546
auto_topup_blocked_reason,
47+
created_at: user.created_at,
4648
}
4749

4850
return NextResponse.json(response)

web/src/components/ui/banner.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,26 @@ import posthog from 'posthog-js'
1010
import { Suspense, useState } from 'react'
1111

1212
import { Button } from './button'
13+
import { useUserProfile } from '@/hooks/use-user-profile'
1314

1415
function BannerContent() {
1516
const [isVisible, setIsVisible] = useState(true)
1617
const searchParams = useSearchParams()
1718
const referrer = searchParams.get('referrer')
1819
const { data: session } = useSession()
1920

20-
if (!isVisible || !session?.user) return null
21+
const { data: userProfile } = useUserProfile()
22+
23+
if (!isVisible || !session?.user || !userProfile) return null
24+
25+
// Check if account is less than a week old
26+
const isNewAccount = userProfile.created_at
27+
? new Date().getTime() - new Date(userProfile.created_at).getTime() <
28+
7 * 24 * 60 * 60 * 1000
29+
: false
30+
31+
// Only show banner for new accounts (less than a week old)
32+
if (!isNewAccount) return null
2133

2234
const isPersonalReferral = !!referrer
2335

web/src/hooks/use-user-profile.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { useQuery } from '@tanstack/react-query'
2+
import { useSession } from 'next-auth/react'
3+
import { useEffect } from 'react'
4+
5+
import type { UserProfile } from '@/types/user'
6+
7+
const USER_PROFILE_STORAGE_KEY = 'codebuff-user-profile'
8+
9+
// Helper functions for local storage
10+
const getUserProfileFromStorage = (): UserProfile | null => {
11+
if (typeof window === 'undefined') return null
12+
13+
try {
14+
const stored = localStorage.getItem(USER_PROFILE_STORAGE_KEY)
15+
if (!stored) return null
16+
17+
const parsed = JSON.parse(stored)
18+
// Convert created_at string back to Date if it exists
19+
if (parsed.created_at) {
20+
parsed.created_at = new Date(parsed.created_at)
21+
}
22+
return parsed
23+
} catch {
24+
return null
25+
}
26+
}
27+
28+
const setUserProfileToStorage = (profile: UserProfile) => {
29+
if (typeof window === 'undefined') return
30+
31+
try {
32+
localStorage.setItem(USER_PROFILE_STORAGE_KEY, JSON.stringify(profile))
33+
} catch {
34+
// Silently fail if localStorage is not available
35+
}
36+
}
37+
38+
const clearUserProfileFromStorage = () => {
39+
if (typeof window === 'undefined') return
40+
41+
try {
42+
localStorage.removeItem(USER_PROFILE_STORAGE_KEY)
43+
} catch {
44+
// Silently fail if localStorage is not available
45+
}
46+
}
47+
48+
export const useUserProfile = () => {
49+
const { data: session } = useSession()
50+
51+
const query = useQuery<UserProfile>({
52+
queryKey: ['user-profile'],
53+
queryFn: async () => {
54+
const response = await fetch('/api/user/profile')
55+
if (!response.ok) {
56+
throw new Error('Failed to fetch user profile')
57+
}
58+
const data = await response.json()
59+
60+
// Convert created_at string to Date if it exists
61+
if (data.created_at) {
62+
data.created_at = new Date(data.created_at)
63+
}
64+
65+
return data
66+
},
67+
enabled: !!session?.user,
68+
staleTime: 5 * 60 * 1000, // 5 minutes
69+
initialData: () => {
70+
// Return undefined if no data, which is compatible with useQuery
71+
return getUserProfileFromStorage() ?? undefined
72+
},
73+
})
74+
75+
// Persist to localStorage whenever data changes
76+
useEffect(() => {
77+
if (query.data) {
78+
setUserProfileToStorage(query.data)
79+
}
80+
}, [query.data])
81+
82+
// Clear localStorage when user logs out
83+
useEffect(() => {
84+
if (!session?.user) {
85+
clearUserProfileFromStorage()
86+
}
87+
}, [session?.user])
88+
89+
return {
90+
...query,
91+
clearCache: clearUserProfileFromStorage,
92+
}
93+
}

web/src/types/user.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ export interface UserProfile {
1111
auto_topup_threshold: number | null
1212
auto_topup_amount: number | null
1313
auto_topup_blocked_reason: string | null
14+
created_at: Date | null
1415
}

0 commit comments

Comments
 (0)