import { Head, Link, usePage } from '@inertiajs/react'; import { 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 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 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 && ( )} )}

Live streams from independent channels

Watch public live broadcasts, follow channels, and chat while creators stream from OBS.

Creator access
One channel per account with private stream keys.

Live directory

setQuery(event.target.value) } placeholder="Search channels" className="pl-9 sm:w-72" />
{filteredChannels.length > 0 ? (
{filteredChannels.map((channel) => (
Live preview
{channel.broadcast ?.title ?? channel.display_name}
{channel.display_name}{' '} by {channel.owner.name}
LIVE
{channel.category?.name ?? 'Uncategorized'} {channel.viewer_count}{' '} viewers
))}
) : (
No live channels match this view.
)}
); }