mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-05-08 23:25:01 -04:00
Refactor profile and compatibility display components: streamline layout, replace utility functions, and improve styling consistency
This commit is contained in:
@@ -216,8 +216,8 @@ export function CompatibilityQuestionsDisplay(props: {
|
||||
<Row className={'gap-8'}>
|
||||
<Subtitle>
|
||||
{isCurrentUser
|
||||
? t('answers.display.your_prompts', 'Your Compatibility Prompts')
|
||||
: t('answers.display.user_prompts', "{name}'s Compatibility Prompts", {
|
||||
? t('answers.display.your_prompts', 'Compatibility Prompts')
|
||||
: t('answers.display.user_prompts', 'Compatibility Prompts', {
|
||||
name: shortenName(user.name),
|
||||
})}
|
||||
</Subtitle>
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import {ArrowLeftIcon} from '@heroicons/react/24/solid'
|
||||
import {ChevronLeftIcon} from '@heroicons/react/24/outline'
|
||||
import clsx from 'clsx'
|
||||
import {useRouter} from 'next/navigation'
|
||||
import {useEffect, useState} from 'react'
|
||||
import {Button} from 'web/components/buttons/button'
|
||||
import React, {useEffect, useState} from 'react'
|
||||
|
||||
export function BackButton(props: {className?: string}) {
|
||||
const {className} = props
|
||||
const router = useRouter()
|
||||
const [canGoBack, setCanGoBack] = useState(false)
|
||||
|
||||
// Can't put this in a useMemo to avoid the page jump else we'll get hydration errors.
|
||||
@@ -17,9 +14,15 @@ export function BackButton(props: {className?: string}) {
|
||||
if (!canGoBack) return null
|
||||
|
||||
return (
|
||||
<Button className={clsx('rounded-none', className)} onClick={router.back} color={'gray-white'}>
|
||||
<ArrowLeftIcon className="h-5 w-5" aria-hidden />
|
||||
<div className="sr-only">Back</div>
|
||||
</Button>
|
||||
<button
|
||||
type="button"
|
||||
className={clsx(
|
||||
'text-ink-500 hover:text-ink-900 inline-flex items-center gap-2 text-sm',
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<ChevronLeftIcon className="h-4 w-4" />
|
||||
Back
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import {Gender} from 'common/gender'
|
||||
import {CompatibilityScore} from 'common/profiles/compatibility-score'
|
||||
import {Profile} from 'common/profiles/profile'
|
||||
import {DisplayOptions} from 'common/profiles-rendering'
|
||||
import {capitalize} from 'lodash'
|
||||
import {
|
||||
Brain,
|
||||
Briefcase,
|
||||
@@ -36,6 +35,7 @@ import {isDark, useTheme} from 'web/hooks/use-theme'
|
||||
import {useUser} from 'web/hooks/use-user'
|
||||
import {useT} from 'web/lib/locale'
|
||||
import {getSeekingConnectionText} from 'web/lib/profile/seeking'
|
||||
import {capitalizePure} from 'web/lib/util/time'
|
||||
|
||||
import {Col} from './layout/col'
|
||||
|
||||
@@ -403,7 +403,7 @@ function ProfilePreview(props: {
|
||||
<Row className={'gap-2 flex-wrap py-2'} data-testid="profile-keywords">
|
||||
{profile.keywords
|
||||
?.slice(0, 10)
|
||||
?.map(capitalize)
|
||||
?.map(capitalizePure)
|
||||
?.map((tag, i) => (
|
||||
<span key={i} className={'bg-canvas-200 text-sm px-3 py-2 rounded-full'}>
|
||||
{tag.trim()}
|
||||
|
||||
@@ -8,10 +8,9 @@ import clsx from 'clsx'
|
||||
import {debug} from 'common/logger'
|
||||
import {Profile} from 'common/profiles/profile'
|
||||
import {User, UserActivity} from 'common/user'
|
||||
import {capitalize} from 'lodash'
|
||||
import Link from 'next/link'
|
||||
import Router from 'next/router'
|
||||
import React, {useState} from 'react'
|
||||
import React from 'react'
|
||||
import toast from 'react-hot-toast'
|
||||
import {Button} from 'web/components/buttons/button'
|
||||
import {MoreOptionsUserButton} from 'web/components/buttons/more-options-user-button'
|
||||
@@ -19,45 +18,29 @@ import DropdownMenu from 'web/components/comments/dropdown-menu'
|
||||
import {Col} from 'web/components/layout/col'
|
||||
import {Row} from 'web/components/layout/row'
|
||||
import {SendMessageButton} from 'web/components/messaging/send-message-button'
|
||||
import HideProfileButton from 'web/components/widgets/hide-profile-button'
|
||||
import {ViewProfileCardButton} from 'web/components/photos-modal'
|
||||
import {linkClass} from 'web/components/widgets/site-link'
|
||||
import {StarButton} from 'web/components/widgets/star-button'
|
||||
import {Tooltip} from 'web/components/widgets/tooltip'
|
||||
import {useUser} from 'web/hooks/use-user'
|
||||
import {updateProfile} from 'web/lib/api'
|
||||
import {useT} from 'web/lib/locale'
|
||||
import {track} from 'web/lib/service/analytics'
|
||||
import {disableProfile} from 'web/lib/util/disable'
|
||||
import {capitalizePure} from 'web/lib/util/time'
|
||||
|
||||
import {ShareProfileButton} from '../widgets/share-profile-button'
|
||||
import ProfilePrimaryInfo from './profile-primary-info'
|
||||
import {VisibilityConfirmationModal} from './visibility-confirmation-modal'
|
||||
|
||||
export default function ProfileHeader(props: {
|
||||
user: User
|
||||
userActivity?: UserActivity
|
||||
profile: Profile
|
||||
simpleView?: boolean
|
||||
starredUserIds: string[]
|
||||
refreshStars: () => Promise<void>
|
||||
isHiddenFromMe: boolean | undefined
|
||||
showMessageButton: boolean
|
||||
refreshProfile: () => void
|
||||
}) {
|
||||
const {
|
||||
user,
|
||||
profile,
|
||||
userActivity,
|
||||
simpleView,
|
||||
starredUserIds,
|
||||
refreshStars,
|
||||
showMessageButton,
|
||||
refreshProfile,
|
||||
isHiddenFromMe,
|
||||
} = props
|
||||
const {user, profile, userActivity, simpleView, isHiddenFromMe} = props
|
||||
const currentUser = useUser()
|
||||
const isCurrentUser = currentUser?.id === user.id
|
||||
const [showVisibilityModal, setShowVisibilityModal] = useState(false)
|
||||
const disabled = profile.disabled
|
||||
const t = useT()
|
||||
|
||||
@@ -68,6 +51,93 @@ export default function ProfileHeader(props: {
|
||||
currentUser,
|
||||
})
|
||||
|
||||
return (
|
||||
<Row className="w-full">
|
||||
<Col className="w-full">
|
||||
{currentUser && !isCurrentUser && isHiddenFromMe && (
|
||||
<div className="guidance">
|
||||
{t(
|
||||
'profile_grid.hidden_notice',
|
||||
"You hid this person, so they don't appear in your search results.",
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{currentUser && isCurrentUser && disabled && (
|
||||
<div className="text-red-500">
|
||||
{t(
|
||||
'profile.header.disabled_notice',
|
||||
'You disabled your profile, so no one else can access it.',
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<Row className={clsx('flex-wrap justify-between gap-2 py-1')}>
|
||||
<Row className="items-center gap-1">
|
||||
<Col className="gap-1">
|
||||
<Row className="items-center gap-1 text-xl" data-testid="profile-display-name-age">
|
||||
{/*{!isCurrentUser && <OnlineIcon last_online_time={userActivity?.last_online_time}/>}*/}
|
||||
<span>
|
||||
{simpleView ? (
|
||||
<Link className={linkClass} href={`/${user.username}`}>
|
||||
<span className="font-semibold">{user.name}</span>
|
||||
</Link>
|
||||
) : (
|
||||
<span className="font-semibold">{user.name}</span>
|
||||
)}
|
||||
</span>
|
||||
</Row>
|
||||
<ProfilePrimaryInfo profile={profile} />
|
||||
</Col>
|
||||
</Row>
|
||||
</Row>
|
||||
|
||||
<Row className={'px-4 gap-2 flex-wrap py-2'} data-testid="profile-keywords">
|
||||
{profile.keywords?.map(capitalizePure)?.map((tag, i) => (
|
||||
<span
|
||||
key={i}
|
||||
className={'bg-canvas-200'}
|
||||
style={{
|
||||
padding: '6px 16px',
|
||||
borderRadius: '20px',
|
||||
}}
|
||||
>
|
||||
{tag.trim()}
|
||||
</span>
|
||||
))}
|
||||
</Row>
|
||||
</Col>
|
||||
{profile.headline && (
|
||||
<div className="italic max-w-3xl px-4 py-3" data-testid="profile-headline">
|
||||
"{profile.headline}"
|
||||
</div>
|
||||
)}
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
|
||||
export function ProfileHeaderActions(props: {
|
||||
user: User
|
||||
profile: Profile
|
||||
starredUserIds: string[]
|
||||
refreshStars: () => Promise<void>
|
||||
showMessageButton: boolean
|
||||
refreshProfile: () => void
|
||||
isHiddenFromMe: boolean | undefined
|
||||
setShowVisibilityModal: (show: boolean) => void
|
||||
}) {
|
||||
const {
|
||||
user,
|
||||
profile,
|
||||
starredUserIds,
|
||||
refreshStars,
|
||||
showMessageButton,
|
||||
refreshProfile,
|
||||
setShowVisibilityModal,
|
||||
} = props
|
||||
const currentUser = useUser()
|
||||
const isCurrentUser = currentUser?.id === user.id
|
||||
const disabled = profile.disabled
|
||||
const t = useT()
|
||||
|
||||
let tooltipText = undefined
|
||||
if (!profile.allow_direct_messaging) {
|
||||
tooltipText = t(
|
||||
@@ -86,184 +156,109 @@ export default function ProfileHeader(props: {
|
||||
', but you can still express interest at the end of the profile',
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Col className="w-full">
|
||||
{currentUser && !isCurrentUser && isHiddenFromMe && (
|
||||
<div className="guidance">
|
||||
{t(
|
||||
'profile_grid.hidden_notice',
|
||||
"You hid this person, so they don't appear in your search results.",
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{currentUser && isCurrentUser && disabled && (
|
||||
<div className="text-red-500">
|
||||
{t(
|
||||
'profile.header.disabled_notice',
|
||||
'You disabled your profile, so no one else can access it.',
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<Row className={clsx('flex-wrap justify-between gap-2 py-1')}>
|
||||
<Row className="items-center gap-1">
|
||||
<Col className="gap-1">
|
||||
<Row className="items-center gap-1 text-xl" data-testid="profile-display-name-age">
|
||||
{/*{!isCurrentUser && <OnlineIcon last_online_time={userActivity?.last_online_time}/>}*/}
|
||||
<span>
|
||||
{simpleView ? (
|
||||
<Link className={linkClass} href={`/${user.username}`}>
|
||||
<span className="font-semibold">{user.name}</span>
|
||||
</Link>
|
||||
) : (
|
||||
<span className="font-semibold">{user.name}</span>
|
||||
)}
|
||||
</span>
|
||||
</Row>
|
||||
<ProfilePrimaryInfo profile={profile} />
|
||||
</Col>
|
||||
</Row>
|
||||
{currentUser && isCurrentUser ? (
|
||||
<Row className={'items-center gap-4'}>
|
||||
<ShareProfileButton className="sm:flex" username={user.username} />
|
||||
<Tooltip text={t('more_options_user.edit_profile', 'Edit profile')} noTap>
|
||||
<Button
|
||||
data-testid="profile-edit"
|
||||
color={'gray-outline'}
|
||||
onClick={() => {
|
||||
track('editprofile', {userId: user.id})
|
||||
Router.push('profile')
|
||||
}}
|
||||
size="sm"
|
||||
>
|
||||
<PencilIcon className=" h-4 w-4" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip
|
||||
text={t('more_options_user.profile_options', 'Profile options')}
|
||||
noTap
|
||||
testId="profile-options"
|
||||
>
|
||||
<DropdownMenu
|
||||
menuWidth={'w-52'}
|
||||
icon={<EllipsisHorizontalIcon className="h-5 w-5" aria-hidden="true" />}
|
||||
items={[
|
||||
{
|
||||
name:
|
||||
profile.visibility === 'member'
|
||||
? t('profile.header.menu.list_public', 'List Profile Publicly')
|
||||
: t('profile.header.menu.limit_members', 'Limit to Members Only'),
|
||||
icon:
|
||||
profile.visibility === 'member' ? (
|
||||
<EyeIcon className="h-4 w-4" />
|
||||
) : (
|
||||
<LockClosedIcon className="h-4 w-4" />
|
||||
),
|
||||
onClick: () => setShowVisibilityModal(true),
|
||||
},
|
||||
{
|
||||
name: disabled
|
||||
? t('profile.header.menu.enable_profile', 'Enable profile')
|
||||
: t('profile.header.menu.disable_profile', 'Disable profile'),
|
||||
icon: null,
|
||||
onClick: async () => {
|
||||
const confirmed = true // confirm(
|
||||
// 'Are you sure you want to disable your profile? This will hide your profile from searches and listings..'
|
||||
// )
|
||||
if (confirmed) {
|
||||
toast
|
||||
.promise(disableProfile(!disabled), {
|
||||
loading: disabled
|
||||
? t('profile.header.toast.enabling', 'Enabling profile...')
|
||||
: t('profile.header.toast.disabling', 'Disabling profile...'),
|
||||
success: () => {
|
||||
return disabled
|
||||
? t('profile.header.toast.enabled', 'Profile enabled')
|
||||
: t('profile.header.toast.disabled', 'Profile disabled')
|
||||
},
|
||||
error: () => {
|
||||
return disabled
|
||||
? t(
|
||||
'profile.header.toast.failed_enable',
|
||||
'Failed to enable profile',
|
||||
)
|
||||
: t(
|
||||
'profile.header.toast.failed_disable',
|
||||
'Failed to disable profile',
|
||||
)
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
refreshProfile()
|
||||
})
|
||||
.catch(() => {
|
||||
// return false
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Row>
|
||||
) : (
|
||||
<Row className="items-center gap-1 sm:gap-2">
|
||||
{currentUser && !isCurrentUser && <HideProfileButton hiddenUserId={user.id} />}
|
||||
<ShareProfileButton className="sm:flex" username={user.username} />
|
||||
{currentUser && (
|
||||
<StarButton
|
||||
targetProfile={profile}
|
||||
isStarred={starredUserIds.includes(user.id)}
|
||||
refresh={refreshStars}
|
||||
/>
|
||||
)}
|
||||
{currentUser && showMessageButton && (
|
||||
<SendMessageButton
|
||||
toUser={user}
|
||||
currentUser={currentUser}
|
||||
profile={profile}
|
||||
tooltipText={tooltipText}
|
||||
disabled={!profile.allow_direct_messaging}
|
||||
/>
|
||||
)}
|
||||
<MoreOptionsUserButton user={user} />
|
||||
</Row>
|
||||
)}
|
||||
</Row>
|
||||
|
||||
{/*<Row className="justify-end sm:hidden">*/}
|
||||
{/* <ShareProfileButton username={user.username} />*/}
|
||||
{/*</Row>*/}
|
||||
|
||||
<VisibilityConfirmationModal
|
||||
open={showVisibilityModal}
|
||||
setOpen={setShowVisibilityModal}
|
||||
currentVisibility={profile.visibility}
|
||||
onConfirm={async () => {
|
||||
const newVisibility = profile.visibility === 'member' ? 'public' : 'member'
|
||||
await updateProfile({visibility: newVisibility})
|
||||
refreshProfile()
|
||||
}}
|
||||
/>
|
||||
{profile.headline && (
|
||||
<div className="italic max-w-3xl px-4 py-3" data-testid="profile-headline">
|
||||
"{profile.headline}"
|
||||
</div>
|
||||
)}
|
||||
<Row className={'px-4 gap-2 flex-wrap py-2'} data-testid="profile-keywords">
|
||||
{profile.keywords?.map(capitalize)?.map((tag, i) => (
|
||||
<span
|
||||
key={i}
|
||||
className={'bg-canvas-200'}
|
||||
style={{
|
||||
padding: '6px 16px',
|
||||
borderRadius: '20px',
|
||||
if (currentUser && isCurrentUser) {
|
||||
return (
|
||||
<Row className={'items-center gap-4'}>
|
||||
<ViewProfileCardButton user={user} profile={profile} />
|
||||
<ShareProfileButton className="sm:flex" username={user.username} />
|
||||
<Tooltip text={t('more_options_user.edit_profile', 'Edit profile')} noTap>
|
||||
<Button
|
||||
data-testid="profile-edit"
|
||||
color={'gray-outline'}
|
||||
onClick={() => {
|
||||
track('editprofile', {userId: user.id})
|
||||
Router.push('profile')
|
||||
}}
|
||||
size="sm"
|
||||
>
|
||||
{tag.trim()}
|
||||
</span>
|
||||
))}
|
||||
<PencilIcon className=" h-4 w-4" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip
|
||||
text={t('more_options_user.profile_options', 'Profile options')}
|
||||
noTap
|
||||
testId="profile-options"
|
||||
>
|
||||
<DropdownMenu
|
||||
menuWidth={'w-52'}
|
||||
icon={<EllipsisHorizontalIcon className="h-5 w-5" aria-hidden="true" />}
|
||||
items={[
|
||||
{
|
||||
name:
|
||||
profile.visibility === 'member'
|
||||
? t('profile.header.menu.list_public', 'List Profile Publicly')
|
||||
: t('profile.header.menu.limit_members', 'Limit to Members Only'),
|
||||
icon:
|
||||
profile.visibility === 'member' ? (
|
||||
<EyeIcon className="h-4 w-4" />
|
||||
) : (
|
||||
<LockClosedIcon className="h-4 w-4" />
|
||||
),
|
||||
onClick: () => setShowVisibilityModal(true),
|
||||
},
|
||||
{
|
||||
name: disabled
|
||||
? t('profile.header.menu.enable_profile', 'Enable profile')
|
||||
: t('profile.header.menu.disable_profile', 'Disable profile'),
|
||||
icon: null,
|
||||
onClick: async () => {
|
||||
const confirmed = true
|
||||
if (confirmed) {
|
||||
toast
|
||||
.promise(disableProfile(!disabled), {
|
||||
loading: disabled
|
||||
? t('profile.header.toast.enabling', 'Enabling profile...')
|
||||
: t('profile.header.toast.disabling', 'Disabling profile...'),
|
||||
success: () => {
|
||||
return disabled
|
||||
? t('profile.header.toast.enabled', 'Profile enabled')
|
||||
: t('profile.header.toast.disabled', 'Profile disabled')
|
||||
},
|
||||
error: () => {
|
||||
return disabled
|
||||
? t('profile.header.toast.failed_enable', 'Failed to enable profile')
|
||||
: t('profile.header.toast.failed_disable', 'Failed to disable profile')
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
refreshProfile()
|
||||
})
|
||||
.catch(() => {
|
||||
// noop
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Row>
|
||||
</Col>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Row className="items-center gap-1 sm:gap-2">
|
||||
<ViewProfileCardButton user={user} profile={profile} />
|
||||
<ShareProfileButton className="sm:flex" username={user.username} />
|
||||
{currentUser && (
|
||||
<StarButton
|
||||
targetProfile={profile}
|
||||
isStarred={starredUserIds.includes(user.id)}
|
||||
refresh={refreshStars}
|
||||
/>
|
||||
)}
|
||||
{currentUser && showMessageButton && (
|
||||
<SendMessageButton
|
||||
toUser={user}
|
||||
currentUser={currentUser}
|
||||
profile={profile}
|
||||
tooltipText={tooltipText}
|
||||
disabled={!profile.allow_direct_messaging}
|
||||
/>
|
||||
)}
|
||||
<MoreOptionsUserButton user={user} />
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -10,9 +10,8 @@ import {ProfileBio} from 'web/components/bio/profile-bio'
|
||||
import {Col} from 'web/components/layout/col'
|
||||
import {Row} from 'web/components/layout/row'
|
||||
import {SignUpButton} from 'web/components/nav/sidebar'
|
||||
import {ViewProfileCardButton} from 'web/components/photos-modal'
|
||||
import {ConnectActions} from 'web/components/profile/connect-actions'
|
||||
import ProfileHeader from 'web/components/profile/profile-header'
|
||||
import ProfileHeader, {ProfileHeaderActions} from 'web/components/profile/profile-header'
|
||||
import ProfileAbout from 'web/components/profile-about'
|
||||
import ProfileCarousel from 'web/components/profile-carousel'
|
||||
import {ProfileCommentSection} from 'web/components/profile-comment-section'
|
||||
@@ -25,6 +24,8 @@ import {User} from 'web/lib/firebase/users'
|
||||
import {useT} from 'web/lib/locale'
|
||||
import {getStars} from 'web/lib/supabase/stars'
|
||||
|
||||
import {BackButton} from '../back-button'
|
||||
|
||||
export function ProfileInfo(props: {
|
||||
profile: Profile
|
||||
user: User
|
||||
@@ -75,7 +76,27 @@ export function ProfileInfo(props: {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mx-auto w-full max-w-6xl px-4 pb-6 pt-4">
|
||||
<div className="bg-canvas-50 border-canvas-300 mb-6 flex items-center gap-2 border-b px-8 py-3">
|
||||
<div className="flex w-full items-center gap-2">
|
||||
<BackButton />
|
||||
|
||||
<div className="ml-auto flex items-center gap-2">
|
||||
<ProfileHeaderActions
|
||||
user={user}
|
||||
profile={profile}
|
||||
starredUserIds={starredUserIds ?? []}
|
||||
refreshStars={refreshStars}
|
||||
showMessageButton={showMessageButton}
|
||||
refreshProfile={refreshProfile}
|
||||
isHiddenFromMe={isHiddenFromMe}
|
||||
// no-op: the visibility modal lives inside ProfileHeader below
|
||||
setShowVisibilityModal={() => {}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mx-auto w-full px-8 pb-6 pt-0">
|
||||
<Row className="items-start gap-6">
|
||||
{profile.pinned_url && (
|
||||
<div className="h-[108px] w-[108px] flex-none">
|
||||
@@ -96,10 +117,6 @@ export function ProfileInfo(props: {
|
||||
userActivity={userActivity}
|
||||
profile={profile}
|
||||
simpleView={!!fromProfilePage}
|
||||
starredUserIds={starredUserIds ?? []}
|
||||
refreshStars={refreshStars}
|
||||
showMessageButton={showMessageButton}
|
||||
refreshProfile={refreshProfile}
|
||||
isHiddenFromMe={isHiddenFromMe}
|
||||
/>
|
||||
</div>
|
||||
@@ -209,23 +226,7 @@ function ProfileContent(props: {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Row className="mt-4 items-center justify-end">
|
||||
<div className="w-fit">
|
||||
<ViewProfileCardButton user={user} profile={profile} />
|
||||
</div>
|
||||
</Row>
|
||||
|
||||
<div className="mt-4 grid grid-cols-1 items-start gap-6 lg:grid-cols-[320px_1fr]">
|
||||
<Col className="gap-6">
|
||||
<ProfileCard title="Details" className="p-5">
|
||||
<ProfileAbout
|
||||
profile={profile}
|
||||
userActivity={userActivity}
|
||||
isCurrentUser={isCurrentUser}
|
||||
/>
|
||||
</ProfileCard>
|
||||
</Col>
|
||||
|
||||
<div className="mt-4 grid grid-cols-1 items-start gap-6 lg:grid-cols-[1fr_480px]">
|
||||
<Col className="gap-6">
|
||||
<ProfileCard className="p-5">
|
||||
<ProfileBio
|
||||
@@ -265,6 +266,16 @@ function ProfileContent(props: {
|
||||
/>
|
||||
</ProfileCard>
|
||||
</Col>
|
||||
|
||||
<Col className="gap-6">
|
||||
<ProfileCard title="Details" className="p-5">
|
||||
<ProfileAbout
|
||||
profile={profile}
|
||||
userActivity={userActivity}
|
||||
isCurrentUser={isCurrentUser}
|
||||
/>
|
||||
</ProfileCard>
|
||||
</Col>
|
||||
</div>
|
||||
{/*<LikesDisplay*/}
|
||||
{/* likesGiven={likesGiven}*/}
|
||||
|
||||
@@ -9,7 +9,6 @@ import {GetStaticPropsContext} from 'next'
|
||||
import Head from 'next/head'
|
||||
import {useRouter} from 'next/router'
|
||||
import {useEffect, useMemo, useState} from 'react'
|
||||
import {BackButton} from 'web/components/back-button'
|
||||
import {Col} from 'web/components/layout/col'
|
||||
import {PageBase} from 'web/components/page-base'
|
||||
import {ProfileInfo} from 'web/components/profile/profile-info'
|
||||
@@ -314,7 +313,7 @@ function UserPageInner(props: ActiveUserPageProps) {
|
||||
<PageBase
|
||||
trackPageView={'user page'}
|
||||
trackPageProps={{username: user.username}}
|
||||
className={'relative p-2 sm:pt-0'}
|
||||
className={'relative !px-0 sm:pt-0 !mt-0 col-span-10'}
|
||||
>
|
||||
<SEO
|
||||
title={`${user.name}`}
|
||||
@@ -331,10 +330,9 @@ function UserPageInner(props: ActiveUserPageProps) {
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
</Head>
|
||||
)}
|
||||
<BackButton className="-ml-2 mb-2 self-start" />
|
||||
|
||||
{currentUser !== undefined && (
|
||||
<Col className={'gap-4 mx-2'}>
|
||||
<Col className={'gap-4'}>
|
||||
{profile ? (
|
||||
<ProfileInfo
|
||||
key={profile.user_id}
|
||||
|
||||
Reference in New Issue
Block a user