import {JSONContent} from '@tiptap/core' import clsx from 'clsx' import {CompatibilityScore} from 'common/profiles/compatibility-score' import {Profile} from 'common/profiles/profile' import {capitalize} from 'lodash' import Image from 'next/image' import Link from 'next/link' import {Row} from 'web/components/layout/row' import {CompatibleBadge} from 'web/components/widgets/compatible-badge' import {Content} from 'web/components/widgets/editor' import HideProfileButton from 'web/components/widgets/hide-profile-button' import {CompassLoadingIndicator} from 'web/components/widgets/loading-indicator' import {LoadMoreUntilNotVisible} from 'web/components/widgets/visibility-observer' import {useAllChoices} from 'web/hooks/use-choices' import {useUser} from 'web/hooks/use-user' import {useT} from 'web/lib/locale' import {getSeekingGenderText} from 'web/lib/profile/seeking' import {Col} from './layout/col' export const ProfileGrid = (props: { profiles: Profile[] loadMore: () => Promise isLoadingMore: boolean isReloading: boolean compatibilityScores: Record | undefined starredUserIds: string[] | undefined refreshStars: () => Promise onHide?: (userId: string) => void hiddenUserIds?: string[] onUndoHidden?: (userId: string) => void showPhotos?: boolean | null }) => { const { profiles, loadMore, isLoadingMore, isReloading, compatibilityScores, starredUserIds, refreshStars, onHide, hiddenUserIds, onUndoHidden, showPhotos, } = props const user = useUser() const t = useT() const other_profiles = profiles.filter((profile) => profile.user_id !== user?.id) return (
{other_profiles.map((profile) => ( ))}
{isLoadingMore && (
)} {!isLoadingMore && !isReloading && other_profiles.length === 0 && (

{t('profile_grid.no_profiles', 'No profiles found.')}

{t( 'profile_grid.notification_cta', "Feel free to click on Get Notified and we'll notify you when new users match your search!", )}

)}
) } function ProfilePreview(props: { profile: Profile compatibilityScore: CompatibilityScore | undefined hasStar: boolean refreshStars: () => Promise onHide?: (userId: string) => void isHidden?: boolean onUndoHidden?: (userId: string) => void showPhotos?: boolean | null }) { const {profile, compatibilityScore, onHide, isHidden, onUndoHidden, showPhotos} = props const {user} = profile const choicesIdsToLabels = useAllChoices() const t = useT() // const currentUser = useUser() const bio = profile.bio as JSONContent // If this profile was just hidden, render a compact placeholder with Undo action. if (isHidden) { return (
{t( 'profile_grid.profile_hidden_short', "You won't see {name} in your search results anymore.", {name: user?.name}, )}
) } if (bio && bio.content) { const newBio = [] let i = 0 for (const c of bio.content) { if ((c?.content?.length || 0) == 0) continue if (c.type === 'paragraph') { newBio.push(c) } else if (['heading'].includes(c.type ?? '')) { newBio.push({ type: 'paragraph', content: c.content, }) } else if (c.type === 'image') { continue } else { newBio.push(c) } i += 1 if (i >= 5) break } bio.content = newBio } const seekingGenderText = getSeekingGenderText(profile, t) // if (!profile.work?.length && !profile.occupation_title && !profile.interests?.length && (profile.bio_length || 0) < 100) { // return null // } const isPhotoRendered = showPhotos !== false && profile.pinned_url return ( track('click profile preview')} href={`/${user.username}`} className="cursor-pointer group block rounded-lg overflow-hidden bg-transparent hover:bg-gray-50 dark:hover:bg-gray-800/50 h-full border border-canvas-300" > {/* {currentUser ? (*/} {/* */} {/* ) : (*/} {/*
*/} {/* )}*/} {compatibilityScore && ( )} {/* Hide profile button */} {onHide && ( )} {/**/} {/* {city} • {capitalize(convertGender(gender as Gender))}*/} {/**/} {/* Profile image moved to bottom right */} {isPhotoRendered && (
)} ) }