mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
197 lines
7.2 KiB
TypeScript
197 lines
7.2 KiB
TypeScript
'use client'
|
|
|
|
import React, { useEffect, useRef, useState } from 'react'
|
|
import { useAccount } from '@hanzo/app/lib/account'
|
|
import { ReferralHero } from '@/components/referrals/ReferralHero'
|
|
import ReferralLink from '@/components/referrals/ReferralLink'
|
|
import ReferralStatsComponent from '@/components/referrals/ReferralStats'
|
|
import ReferralHistory from '@/components/referrals/ReferralHistory'
|
|
import { RewardTiers } from '@/components/referrals/RewardTiers'
|
|
import { HowItWorks } from '@/components/referrals/HowItWorks'
|
|
import { CreatorStudio } from '@/components/referrals/CreatorStudio'
|
|
import { SubmitPost } from '@/components/referrals/SubmitPost'
|
|
import { ReferralFaq } from '@/components/referrals/ReferralFaq'
|
|
import { ReferralRecord, ReferralStats as ReferralStatsType } from '@/components/referrals/types'
|
|
import { mine } from '@/lib/hanzo/referrals'
|
|
import { Box, Button, Pulse, Text, View, XStack, YStack } from '@hanzo/ui'
|
|
import { Action } from '@hanzo/ui/marketing'
|
|
import { ArrowRight } from 'lucide-react'
|
|
import { useI18n } from '@hanzo/i18n/react'
|
|
|
|
export default function ReferralProgram() {
|
|
const { t } = useI18n()
|
|
const { user } = useAccount()
|
|
|
|
const [referralCode, setReferralCode] = useState<string>('')
|
|
const [referralLink, setReferralLink] = useState<string>('')
|
|
const [stats, setStats] = useState<ReferralStatsType>({
|
|
signedUp: 0,
|
|
qualified: 0,
|
|
pending: 0,
|
|
})
|
|
const [history, setHistory] = useState<ReferralRecord[]>([])
|
|
const [loading, setLoading] = useState(true)
|
|
const [error, setError] = useState<string | null>(null)
|
|
|
|
const dashboardRef = useRef<HTMLDivElement>(null)
|
|
|
|
useEffect(() => {
|
|
if (!user?.id) {
|
|
setLoading(false)
|
|
return
|
|
}
|
|
|
|
// ONE read: the org's code, the link the service mints for it, and the orgs
|
|
// that signed up with it (lib/hanzo/referrals.ts).
|
|
async function loadReferralData() {
|
|
try {
|
|
setLoading(true)
|
|
setError(null)
|
|
const got = await mine()
|
|
setReferralCode(got.code)
|
|
setReferralLink(got.link)
|
|
setStats({
|
|
signedUp: got.counts.total,
|
|
qualified: got.counts.qualified,
|
|
pending: got.counts.signup,
|
|
})
|
|
setHistory(
|
|
got.referrals.map((r) => ({
|
|
id: r.id,
|
|
name: r.referee,
|
|
status: r.status === 'qualified' ? 'Using Hanzo' : 'Not yet active',
|
|
date: r.createdAt ? new Date(r.createdAt * 1000).toLocaleDateString() : '',
|
|
})),
|
|
)
|
|
} catch (err) {
|
|
setError(err instanceof Error ? err.message : 'Your referral link could not be loaded right now.')
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}
|
|
|
|
void loadReferralData()
|
|
}, [user?.id])
|
|
|
|
const scrollToDashboard = () => {
|
|
if (dashboardRef.current) {
|
|
dashboardRef.current.scrollIntoView({ behavior: 'smooth' })
|
|
}
|
|
}
|
|
|
|
const isLoggedIn = Boolean(user?.id && referralCode)
|
|
const effectiveCode = isLoggedIn ? referralCode : ''
|
|
const effectiveLink = isLoggedIn ? referralLink || `https://hanzo.ai/?ref=${referralCode}` : ''
|
|
|
|
return (
|
|
<YStack px="$4" py="$8" $sm={{ px: '$8', py: '$12' }}>
|
|
<YStack width="100%" maxW={1040} mx="auto" gap={48}>
|
|
{/* Section 01: Hero (One clear message, 3 benefits, single CTA) */}
|
|
<ReferralHero
|
|
isAuthenticated={isLoggedIn}
|
|
referralLink={effectiveLink}
|
|
onGetLinkClick={scrollToDashboard}
|
|
/>
|
|
|
|
{error && (
|
|
<Box
|
|
p={16}
|
|
borderWidth={1}
|
|
borderColor="var(--destructive)"
|
|
rounded="var(--radius-lg)"
|
|
bg="var(--panel, rgba(255, 255, 255, 0.03))"
|
|
>
|
|
<Text display="block" fontSize="$2" lineHeight="1.1607rem" color="var(--state-error-text)">
|
|
{error}
|
|
</Text>
|
|
</Box>
|
|
)}
|
|
|
|
{loading && user?.id ? (
|
|
<YStack gap={24}>
|
|
{[1, 2].map((i) => (
|
|
<Pulse
|
|
key={i}
|
|
p={24}
|
|
borderWidth={1}
|
|
borderColor="var(--neutral-800)"
|
|
rounded="var(--radius-lg)"
|
|
bg="var(--panel, rgba(255, 255, 255, 0.03))"
|
|
>
|
|
<Box height={16} width="33.333333%" mb={16} rounded="var(--radius-sm)" bg="var(--neutral-800)" />
|
|
<Box height={32} width="100%" rounded="var(--radius-sm)" bg="var(--neutral-800)" />
|
|
</Pulse>
|
|
))}
|
|
</YStack>
|
|
) : null}
|
|
|
|
{/* Live Creator Link & Stats strictly when authenticated, or Sign-In Gate when unauthenticated */}
|
|
{isLoggedIn ? (
|
|
<div ref={dashboardRef}>
|
|
<YStack gap={24}>
|
|
<ReferralLink referralLink={effectiveLink} referralCode={effectiveCode} />
|
|
<ReferralStatsComponent referralStats={stats} />
|
|
{history.length > 0 && <ReferralHistory referralHistory={history} />}
|
|
</YStack>
|
|
</div>
|
|
) : !loading ? (
|
|
<div ref={dashboardRef}>
|
|
<YStack
|
|
p={28}
|
|
$sm={{ p: 36 }}
|
|
rounded="var(--radius-lg)"
|
|
borderWidth={1}
|
|
borderColor="var(--border)"
|
|
bg="var(--panel, rgba(255, 255, 255, 0.03))"
|
|
gap={20}
|
|
>
|
|
<XStack items="center" justify="space-between" flexWrap="wrap" gap={16}>
|
|
<YStack gap={4} maxW={600}>
|
|
<Text fontSize="$5" fontWeight="600" color="var(--foreground)">
|
|
{t('Sign in to access your Referral Link & Dashboard')}
|
|
</Text>
|
|
<Text fontSize="$2" color="var(--muted-foreground)">
|
|
{t('Referral links and custom vanity codes require a signed-in Hanzo account so referrals and 10% token rewards are credited to your organization.')}
|
|
</Text>
|
|
</YStack>
|
|
|
|
<XStack gap={10} items="center">
|
|
<Action render="a" href="/login?next=/referral" fill>
|
|
{t('Sign In')}
|
|
<ArrowRight size={14} aria-hidden />
|
|
</Action>
|
|
<Action render="a" href="/signup?next=/referral">
|
|
{t('Create Account')}
|
|
</Action>
|
|
</XStack>
|
|
</XStack>
|
|
</YStack>
|
|
</div>
|
|
) : null}
|
|
|
|
{/* Section 02: Three Reward Cards (Bronze $25, Silver $100, Gold $500) */}
|
|
<RewardTiers />
|
|
|
|
{/* Section 03: How It Works (01, 02, 03) */}
|
|
<HowItWorks />
|
|
|
|
{/* Section 04 & 05: Creator Studio & Submit a Post (strictly for logged-in accounts with a real referral link) */}
|
|
{isLoggedIn ? (
|
|
<>
|
|
<CreatorStudio referralLink={effectiveLink} />
|
|
<SubmitPost referralLink={effectiveLink} />
|
|
</>
|
|
) : null}
|
|
<ReferralFaq />
|
|
|
|
{/* Compact Footer Note */}
|
|
<Box pt={16} borderTopWidth={1} borderColor="var(--border)" items="center">
|
|
<Text fontSize="$1" color="var(--muted-foreground)" style={{ textAlign: 'center' }}>
|
|
{t('Official Hanzo AI Creator & Referral Program ยท All submissions reviewed by engineering operations.')}
|
|
</Text>
|
|
</Box>
|
|
</YStack>
|
|
</YStack>
|
|
)
|
|
}
|