'use client' import { Avatar, AvatarFallback, AvatarImage } from '@thedaviddias/design-system/avatar' import { Button } from '@thedaviddias/design-system/button' import { Calendar, Github, Search } from 'lucide-react' import Link from 'next/link' import { useEffect, useMemo, useState } from 'react' import { useAnalyticsEvents } from '@/components/analytics-tracker' import { Card, CardContent } from '@/components/ui/card' interface Member { id: string firstName?: string | null lastName?: string | null username?: string | null imageUrl?: string | null createdAt: string publicMetadata?: { github_username?: string | null migrated_from?: string | null } } interface MembersListProps { members: Member[] currentPage: number totalPages: number totalUsers: number hasNextPage: boolean hasPrevPage: boolean } /** * Generates a URL slug from a member's username or ID */ function generateSlugFromUser(user: Member): string { if (!user) return '' const username = user.username || user.publicMetadata?.github_username if (!username) return user.id.slice(-8) return username } /** * Renders a paginated and searchable list of community members */ export function MembersList({ members, currentPage, totalPages, totalUsers, hasNextPage, hasPrevPage }: MembersListProps) { const [searchQuery, setSearchQuery] = useState('') const { trackSearch } = useAnalyticsEvents() const filteredMembers = useMemo(() => { if (!searchQuery.trim()) { return members } const query = searchQuery.toLowerCase() return members.filter(user => { const displayName = user.firstName && user.lastName ? `${user.firstName} ${user.lastName}` : user.firstName || user.lastName || user.username || 'Member' const username = user.username || user.publicMetadata?.github_username return displayName.toLowerCase().includes(query) || username?.toLowerCase().includes(query) }) }, [members, searchQuery]) const filteredCount = filteredMembers.length // Track member searches with debouncing useEffect(() => { if (searchQuery.trim()) { const debounceTimer = setTimeout(() => { trackSearch(searchQuery, filteredCount, 'members-list-search') }, 500) return () => clearTimeout(debounceTimer) } }, [searchQuery, filteredCount, trackSearch]) return ( <> {/* Search */}
@{username}
)}{searchQuery ? `No members match "${searchQuery}". Try a different search term.` : 'There are no members on this page.'}
{searchQuery && ( )}