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 (
<>
{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.
{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 ? (

) : (
)}
);
}
function LiveBadge({ compact = false }: { compact?: boolean }) {
return (
LIVE
);
}
function Metric({
icon: Icon,
label,
value,
}: {
icon: typeof Radio;
label: string;
value: string;
}) {
return (
);
}