Gedeelde React 19 componenten in packages/ui β importeerbaar via @teezu/ui
# Bouwen vanuit monorepo root
pnpm --filter @teezu/ui build
# Importeren in elke app
import { Button, GlassCard, Badge } from '@teezu/ui'
Package locatie: packages/ui/
Kleuren zijn gedefinieerd als Tailwind CSS 4 custom properties in packages/ui/src/theme.css.
CVA-gebaseerde button met 4 TeezU-specifieke variants en 3 maten. Gebouwd op een Radix UI Slot primitive voor asChild support.
import { Button } from '@teezu/ui'
// Primary
<Button variant="primary" size="md" onClick={handleClick}>
Verstuur
</Button>
// Tip button
<Button variant="tip" size="sm" onClick={() => openTipModal()}>
π° Stuur Tip
</Button>
// Unlock button
<Button variant="unlock" size="lg" disabled={isPending}>
π Ontgrendel Premium
</Button>
// asChild (Radix Slot)
<Button variant="ghost" asChild>
<a href="/profile">Profiel</a>
</Button>
Vier context-specifieke card-varianten, allemaal als wrapper rond GlassCard.
ProfileCard
ContentCard β met unlock overlay indien premium
StreamCard β met viewer count & live badge
ProviderCard β rating & service info
import { ProfileCard, ContentCard, StreamCard, ProviderCard } from '@teezu/ui'
<ProfileCard user={user} showVerified showFollowButton />
<ContentCard post={post} onUnlock={handleUnlock} />
<StreamCard stream={stream} onJoin={handleJoin} />
<ProviderCard provider={provider} onBook={handleBook} />
Basiscomponent voor glass-morphism styling β overal in de UI gebruikt als container. Combineert backdrop-blur, semi-transparante achtergrond en subtiele border.
Glassmorphism effect met blur en transparantie. Werkt op alle achtergronden.
import { GlassCard } from '@teezu/ui'
// Basis
<GlassCard className="p-6">
<h3>Titel</h3>
<p>Content</p>
</GlassCard>
// Met extra blur intensity
<GlassCard blur="heavy" className="p-8">
<ModalContent />
</GlassCard>
Gebouwd op @radix-ui/react-dialog voor volledige accessibility (focus trap, ARIA, escape-sluiten).
AI prompt-invoer, response streaming, kopieer/bewaar acties
18+ leeftijdsverificatie, consent-logging naar audit ledger
Bedrag invoer, wallet-saldo check, bevestiging & animatie
import { AIGenieModal, ConsentModal, TipModal } from '@teezu/ui'
<AIGenieModal
open={showGenie}
onClose={() => setShowGenie(false)}
targetUserId={creator.id}
/>
<ConsentModal
open={needsConsent}
onAccept={handleConsentAccepted}
onDecline={() => router.push('/')}
/>
<TipModal
open={showTip}
recipientId={creator.id}
walletBalance={wallet.balance}
onSuccess={handleTipSent}
/>
Kleine status-indicators voor rollen, moods en verificatiestatus.
import { RoleBadge, MoodBadge, VerifiedBadge } from '@teezu/ui'
<RoleBadge role="creator" />
<MoodBadge mood="naughty" />
<VerifiedBadge type="creator" />
Alle inputs zijn geΓ―ntegreerd met react-hook-form via Controller, gevalideerd met Zod schemas uit @teezu/types.
import { ChatInput, SearchInput, PromptInput } from '@teezu/ui'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { chatMessageSchema } from '@teezu/types'
const { control, handleSubmit } = useForm({
resolver: zodResolver(chatMessageSchema)
})
<ChatInput
control={control}
name="message"
onSend={handleSubmit(onSend)}
maxLength={500}
/>
<SearchInput
value={query}
onChange={setQuery}
placeholder="Zoek creators, content..."
/>
<PromptInput
control={control}
name="prompt"
onRun={handleSubmit(onPrompt)}
/>
Drie navigatiecomponenten voor desktop, mobiel en drawer-flows. Reageren op useAppStore Zustand slice voor actieve route & sidebar-state.
import { Sidebar, BottomNav, Drawer } from '@teezu/ui'
import { useAppStore } from '@/store'
const { isSidebarOpen, toggleSidebar } = useAppStore()
// Desktop layout
<Sidebar isOpen={isSidebarOpen} onToggle={toggleSidebar} />
// Mobile layout
<BottomNav activeRoute={router.pathname} />
// Drawer (bijv. filters)
<Drawer open={showFilters} onClose={() => setShowFilters(false)} side="right">
<FilterPanel />
</Drawer>
Twee speciale overlay-componenten voor creator livestream-controls en AI strip.
Blur overlay met token-gated reveal. Blauwe glow bij actieve freeze.
"Probeer een roleplay scenario met neon-noir esthetiek..."
Horizontale strip onder de stream met AI-gegenereerde suggesties.
import { FreezeRevealOverlay, AIStrip } from '@teezu/ui'
<FreezeRevealOverlay
isFrozen={streamState.frozen}
tokenCost={50}
onReveal={handleReveal}
glowColor="blue"
/>
<AIStrip
suggestions={aiSuggestions}
onSelect={handleSuggestionSelect}
isLoading={aiLoading}
/>