Files
hanzo.ai/components/referrals/RewardTiers.tsx

217 lines
6.8 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client'
import React from 'react'
import { Check, ArrowDown } from 'lucide-react'
import { Box, Button, Text, View, XStack, YStack } from '@hanzo/ui'
import { useI18n } from '@hanzo/i18n/react'
export interface TierCardData {
id: 'bronze' | 'silver' | 'gold'
name: string
amount: string
unit: string
threshold: string
revShare?: string
popular?: boolean
perks: string[]
}
export const REWARD_CARDS: readonly TierCardData[] = [
{
id: 'bronze',
name: 'Bronze',
amount: '$25',
unit: 'Credits',
threshold: '1–5 active referrals*',
perks: [
'10% Lifetime token kickback on referee usage',
'1 Free week of Pro for each paid upgrade',
'$25 in Hanzo API and compute credits',
'Priority beta queue jump and creator role',
],
},
{
id: 'silver',
name: 'Silver',
amount: '$100',
unit: 'Credits',
threshold: '6–25 active referrals*',
revShare: '25% rev share',
popular: true,
perks: [
'10% Lifetime token kickback on referee usage',
'1 Free week of Pro for each paid upgrade',
'$100 in Hanzo API and compute credits',
'25% recurring affiliate rev share on compute',
'Early access to pre-release Zen model weights',
],
},
{
id: 'gold',
name: 'Gold',
amount: '$500',
unit: 'Reward',
threshold: '26+ active referrals*',
revShare: '40% rev share',
perks: [
'10% Lifetime token kickback on referee usage',
'1 Free week of Pro for each paid upgrade',
'$500 Reward (choose cash payout or compute credits)',
'40% top-tier recurring affiliate commission',
'1 Full year of Hanzo Enterprise access',
'Direct 1:1 Slack/Discord channel with Hanzo Founders',
],
},
]
export function RewardTiers() {
const { t } = useI18n()
const scrollToComparison = () => {
const el = document.getElementById('rewards-comparison')
if (el) {
el.scrollIntoView({ behavior: 'smooth' })
}
}
return (
<YStack gap={32} width="100%" py={16}>
{/* Section Header */}
<YStack gap={8} items="center" style={{ textAlign: 'center' }}>
<Text
render="h2"
fontWeight="600"
color="var(--foreground)"
style={{ textAlign: 'center', letterSpacing: '-0.02em' }}
$platform-web={{ fontSize: 'clamp(28px, 3.2vw, 42px)' }}
>
{t('Create. Share. Earn.')}
</Text>
<Text fontSize="$4" color="var(--muted-foreground)" style={{ textAlign: 'center' }}>
{t('Choose your path to rewards.')}
</Text>
</YStack>
{/* 3 Aligned Reward Cards */}
<View
display="grid"
gap={20}
gridTemplateColumns="1fr"
$md={{ gridTemplateColumns: 'repeat(3, minmax(0, 1fr))' }}
>
{REWARD_CARDS.map((card) => {
const isPopular = card.popular
return (
<YStack
key={card.id}
p={28}
rounded={16}
borderWidth={1}
borderColor={isPopular ? 'var(--foreground)' : 'var(--border)'}
bg="var(--background)"
position="relative"
justify="space-between"
gap={24}
$platform-web={{
boxShadow: isPopular ? '0 8px 30px rgba(0,0,0,0.12)' : 'none',
}}
>
{/* Card Header & Threshold */}
<YStack gap={16}>
<XStack items="center" justify="space-between">
<Text fontSize="$3" fontWeight="600" color="var(--muted-foreground)">
{card.name}
</Text>
{card.revShare && (
<XStack
items="center"
px={10}
py={3}
rounded={999}
bg="var(--secondary)"
borderWidth={1}
borderColor="var(--border)"
>
<Text fontFamily="$mono" fontSize="$1" fontWeight="700" color="var(--foreground)">
{card.revShare}
</Text>
</XStack>
)}
</XStack>
{/* Amount and Unit */}
<YStack gap={4}>
<Text
render="div"
fontWeight="700"
color="var(--foreground)"
style={{ letterSpacing: '-0.03em', lineHeight: '1.05em' }}
$platform-web={{ fontSize: 'clamp(40px, 4.4vw, 54px)' }}
>
{card.amount}
</Text>
<Text fontSize="$2" fontWeight="500" color="var(--muted-foreground)">
{card.unit}
</Text>
</YStack>
{/* Qualification Threshold */}
<Box
py={8}
px={12}
rounded={8}
bg="var(--secondary)"
borderWidth={1}
borderColor="var(--border)"
>
<Text fontFamily="$mono" fontSize="$2" fontWeight="600" color="var(--foreground)">
{card.threshold}
</Text>
</Box>
{/* Key Benefits List */}
<YStack gap={10} pt={8}>
{card.perks.map((perk) => (
<XStack key={perk} gap={10} items="flex-start">
<Box mt={4} width={14} height={14} rounded={999} bg="var(--secondary)" items="center" justify="center">
<Check size={10} color="var(--foreground)" />
</Box>
<Text fontSize="$2" color="var(--muted-foreground)" style={{ flex: 1, lineHeight: '1.45em' }}>
{perk}
</Text>
</XStack>
))}
</YStack>
</YStack>
</YStack>
)
})}
</View>
{/* Footnote & Compare All Rewards Action */}
<YStack gap={16} items="center" style={{ textAlign: 'center' }}>
<Text
fontSize="$1"
color="var(--muted-foreground)"
maxW={720}
style={{ textAlign: 'center', lineHeight: '1.5em' }}
>
{t('*Active referrals qualify upon account creation and verified API or platform activity. Social engagement rewards are verified within 24–48 hours of submission.')}
</Text>
<Button
type="button"
variant="outline"
onClick={scrollToComparison}
gap={8}
>
{t('Compare All Rewards & Rules')}
<ArrowDown size={14} aria-hidden />
</Button>
</YStack>
</YStack>
)
}
export default RewardTiers