Extract ProfileCardViewer component and replace direct Image usage across relevant files for better reuse and readability

This commit is contained in:
MartinBraquet
2026-04-06 01:26:31 +02:00
parent 7c591ca73e
commit 7dfaeb7692
5 changed files with 53 additions and 21 deletions

View File

@@ -1042,6 +1042,8 @@
"profile.wants_kids_3": "Neigt dazu, Kinder zu wollen",
"profile.wants_kids_4": "Möchte Kinder",
"profile.wont_be_notified_unless_mutual": "Sie werden nicht benachrichtigt, es sei denn, das Interesse ist gegenseitig.",
"profile_card.alt": "Profilkarte von {username}",
"profile_card.crafting": "Profilkarte wird erstellt...",
"profile_card.loading": "Ihre Karte wird geladen, es kann ein paar Sekunden dauern...",
"profile_grid.hidden_notice": "Du hast diese Person ausgeblendet, sie wird nicht mehr in deinen Suchergebnissen angezeigt.",
"profile_grid.hide_profile": "Nicht mehr in den Suchergebnissen anzeigen",

View File

@@ -1041,6 +1041,8 @@
"profile.wants_kids_3": "Tend à vouloir des enfants",
"profile.wants_kids_4": "Veut des enfants",
"profile.wont_be_notified_unless_mutual": "Il/elle ne sera pas notifié(e) à moins que l'intérêt soit mutuel.",
"profile_card.alt": "Carte de profil de {username}",
"profile_card.crafting": "Création de la carte de profil...",
"profile_card.loading": "Chargement de votre carte, cela peut prendre quelques secondes...",
"profile_grid.hidden_notice": "Vous avez masqué cette personne, elle n'apparaîtra plus dans vos résultats de recherche.",
"profile_grid.hide_profile": "Ne plus afficher dans les résultats de recherche",

View File

@@ -1,7 +1,5 @@
import {getProfileOgImageUrl} from 'common/profiles/og-image'
import {Profile} from 'common/profiles/profile'
import {User} from 'common/user'
import Image from 'next/image'
import {useState} from 'react'
import {Button} from 'web/components/buttons/button'
import {Col} from 'web/components/layout/col'
@@ -9,6 +7,8 @@ import {Modal} from 'web/components/layout/modal'
import {ShareProfileButtons} from 'web/components/widgets/share-profile-button'
import {useT} from 'web/lib/locale'
import {ProfileCardViewer} from './profile-card-viewer'
// export const PhotosModal = (props: {
// open: boolean
// setOpen: (open: boolean) => void
@@ -68,11 +68,10 @@ export const ViewProfileCardButton = (props: {
width?: number
height?: number
}) => {
const {user, profile, width = 1000, height = 300} = props
const {user, profile, width, height} = props
const [open, setOpen] = useState<boolean>(false)
const t = useT()
if (!user || !profile) return
const src = getProfileOgImageUrl(user, profile)
const username = user.username
return (
<>
@@ -80,14 +79,8 @@ export const ViewProfileCardButton = (props: {
{t('share_profile.view_profile_card', 'View Profile Card')}
</Button>
<Modal open={open} setOpen={setOpen} size={'lg'} className={''}>
<Col className="gap-4 bg-canvas-100/75 rounded-2xl">
<Image
src={src}
width={width}
height={height}
alt={t('profile_card.loading', `${user.username}'s profile card`)}
className={'rounded-2xl'}
/>
<Col className="gap-4 bg-canvas-100/75 rounded-2xl justify-center">
<ProfileCardViewer user={user} profile={profile} width={width} height={height} />
<ShareProfileButtons
username={username}
className={'justify-center gap-4 text-3xl pb-4'}

View File

@@ -0,0 +1,42 @@
import {getProfileOgImageUrl} from 'common/profiles/og-image'
import {Profile} from 'common/profiles/profile'
import {User} from 'common/user'
import Image from 'next/image'
import {useState} from 'react'
import {CompassLoadingIndicator} from 'web/components/widgets/loading-indicator'
import {useT} from 'web/lib/locale'
export const ProfileCardViewer = (props: {
user: User
profile: Profile
width?: number
height?: number
}) => {
const {user, profile, width = 800, height = 200} = props
const t = useT()
const [loaded, setLoaded] = useState(false)
const src = getProfileOgImageUrl(user, profile)
return (
<>
{!loaded && <CompassLoadingIndicator />}
{!loaded && (
<p className={'text-ink-1000/50 text-xl justify-center mx-auto'}>
{t('profile_card.crafting', 'Crafting the profile card...')}
</p>
)}
<Image
src={src}
width={width}
height={height}
alt={t('profile_card.alt', "{username}'s profile card", {username: user.username})}
className={`rounded-2xl transition-opacity duration-300 ${loaded ? 'opacity-100' : 'opacity-0'}`}
onLoad={() => setLoaded(true)}
priority
loading="eager"
fetchPriority={'high'}
/>
</>
)
}

View File

@@ -1,9 +1,8 @@
import {getProfileOgImageUrl} from 'common/profiles/og-image'
import Image from 'next/image'
import Router from 'next/router'
import {Button} from 'web/components/buttons/button'
import {Col} from 'web/components/layout/col'
import {PageBase} from 'web/components/page-base'
import {ProfileCardViewer} from 'web/components/profile-card-viewer'
import {SEO} from 'web/components/SEO'
import {ShareProfileButtons} from 'web/components/widgets/share-profile-button'
import {useProfile} from 'web/hooks/use-profile'
@@ -40,13 +39,7 @@ export default function SoftGatePage() {
{profile && user && (
<Col className="gap-4 text-ink-700 items-center">
<Image
src={getProfileOgImageUrl(user, profile)}
alt="OG"
width={550}
height={325}
className="rounded-xl border border-md"
/>
<ProfileCardViewer user={user} profile={profile} />
<p>
{t(
'onboarding.soft-gate.profile_card',