import { Head, Link, usePage } from '@inertiajs/react'; import { ArrowRight, Compass, LifeBuoy, LayoutDashboard, Radio, Search, UserPlus, Users, Video, } from 'lucide-react'; import { useMemo, useState } from 'react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { cn } from '@/lib/utils'; import { dashboard, home, login, register } from '@/routes'; import { show as showChannel } from '@/routes/channels'; import { index as supportIndex } from '@/routes/support'; import type { Category, ChannelCard } from '@/types'; type Props = { canRegister: boolean; liveChannels: ChannelCard[]; categories: Category[]; }; export default function Welcome({ canRegister, liveChannels, categories, }: Props) { const { auth } = usePage().props; const [query, setQuery] = useState(''); const [category, setCategory] = useState('all'); const featuredChannel = liveChannels[0] ?? null; const filteredChannels = useMemo(() => { const normalizedQuery = query.trim().toLowerCase(); return liveChannels.filter((channel) => { const matchesCategory = category === 'all' || channel.category?.slug === category; const matchesQuery = normalizedQuery === '' || channel.display_name.toLowerCase().includes(normalizedQuery) || channel.broadcast?.title .toLowerCase() .includes(normalizedQuery) || channel.owner.name.toLowerCase().includes(normalizedQuery); return matchesCategory && matchesQuery; }); }, [category, liveChannels, query]); return ( <>
Nyone
{auth.user ? ( <> ) : ( <> {canRegister && ( )} )}
{featuredChannel ? (

{featuredChannel.broadcast ?.title ?? featuredChannel.display_name}

{featuredChannel.description ?? `${featuredChannel.display_name} is live now with ${featuredChannel.viewer_count} viewers.`}

{featuredChannel.display_name} {featuredChannel.category ?.name ?? 'Uncategorized'} { featuredChannel.viewer_count }{' '} viewers Watch
) : (

The live floor is quiet

Creators can prepare a broadcast in the studio and go live from OBS when ready.

)}

Live directory

Browse active channels by category or title.

setQuery(event.target.value) } placeholder="Search live channels" className="pl-9 sm:w-72" />
{filteredChannels.length > 0 ? (
{filteredChannels.map((channel) => ( ))}
) : (
No streams match this view
Clear search or switch categories.
)}
); } function StreamCard({ channel }: { channel: ChannelCard }) { return (
{channel.broadcast?.title ?? channel.display_name}
{channel.display_name} by {channel.owner.name}
{channel.category?.name ?? 'Uncategorized'} {channel.viewer_count} viewers
); } function Thumbnail({ channel, className, label = 'Live preview', }: { channel: ChannelCard; className?: string; label?: string; }) { return (
{channel.thumbnail_url ? ( ) : (
{label}
)}
); } function LiveBadge({ compact = false }: { compact?: boolean }) { return ( LIVE ); } function Metric({ icon: Icon, label, value, }: { icon: typeof Radio; label: string; value: string; }) { return (
{label}
{value}
); }