Skip to content

Commit

Permalink
Feat/profile ssr (#3978)
Browse files Browse the repository at this point in the history
  • Loading branch information
mariojsnunes authored Nov 4, 2024
1 parent f792a90 commit 9c8bb45
Show file tree
Hide file tree
Showing 16 changed files with 343 additions and 338 deletions.
74 changes: 42 additions & 32 deletions src/pages/User/content/MemberProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { MemberBadge, Username, UserStatistics } from 'oa-components'
import { ExternalLinkLabel, ProfileTypeList, UserRole } from 'oa-shared'
// eslint-disable-next-line import/no-unresolved
import { ClientOnly } from 'remix-utils/client-only'
import DefaultMemberImage from 'src/assets/images/default_member.svg'
import { AuthWrapper } from 'src/common/AuthWrapper'
import { cdnImageUrl } from 'src/utils/cdnImageUrl'
Expand All @@ -13,7 +15,7 @@ import type { IUserDB } from 'oa-shared'
import type { UserCreatedDocs } from '../types'

interface IProps {
docs: UserCreatedDocs | undefined
docs: UserCreatedDocs
user: IUserDB
}

Expand Down Expand Up @@ -83,34 +85,38 @@ export const MemberProfile = ({ docs, user }: IProps) => {
height: '120px',
}}
/>
<AuthWrapper
roleRequired={UserRole.BETA_TESTER}
fallback={
<UserStatistics
userName={user.userName}
country={user.location?.country}
isVerified={user.verified}
isSupporter={!!user.badges?.supporter}
howtoCount={docs?.howtos.length || 0}
researchCount={docs?.research.length || 0}
usefulCount={user.totalUseful || 0}
totalViews={0}
sx={{ alignSelf: 'stretch' }}
/>
}
>
<UserStatistics
userName={user.userName}
country={user.location?.country}
isVerified={user.verified}
isSupporter={!!user.badges?.supporter}
howtoCount={docs?.howtos.length || 0}
researchCount={docs?.research.length || 0}
usefulCount={user.totalUseful || 0}
sx={{ alignSelf: 'stretch' }}
totalViews={user.total_views || 0}
/>
</AuthWrapper>
<ClientOnly fallback={<></>}>
{() => (
<AuthWrapper
roleRequired={UserRole.BETA_TESTER}
fallback={
<UserStatistics
userName={user.userName}
country={user.location?.country}
isVerified={user.verified}
isSupporter={!!user.badges?.supporter}
howtoCount={docs?.howtos.length || 0}
researchCount={docs?.research.length || 0}
usefulCount={user.totalUseful || 0}
totalViews={0}
sx={{ alignSelf: 'stretch' }}
/>
}
>
<UserStatistics
userName={user.userName}
country={user.location?.country}
isVerified={user.verified}
isSupporter={!!user.badges?.supporter}
howtoCount={docs?.howtos.length || 0}
researchCount={docs?.research.length || 0}
usefulCount={user.totalUseful || 0}
sx={{ alignSelf: 'stretch' }}
totalViews={user.total_views || 0}
/>
</AuthWrapper>
)}
</ClientOnly>
</Flex>
<Flex sx={{ flexGrow: 2, width: '100%', flexDirection: 'column' }}>
<Flex
Expand Down Expand Up @@ -141,9 +147,13 @@ export const MemberProfile = ({ docs, user }: IProps) => {
<UserContactAndLinks links={userLinks} />
</Flex>
</Flex>
<AuthWrapper roleRequired={UserRole.BETA_TESTER}>
<UserCreatedDocuments docs={docs} />
</AuthWrapper>
<ClientOnly fallback={<></>}>
{() => (
<AuthWrapper roleRequired={UserRole.BETA_TESTER}>
<UserCreatedDocuments docs={docs} />
</AuthWrapper>
)}
</ClientOnly>
</Card>
</Flex>
)
Expand Down
8 changes: 6 additions & 2 deletions src/pages/User/content/SpaceProfile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
UserStatistics,
} from 'oa-components'
import { ExternalLinkLabel, UserRole } from 'oa-shared'
// eslint-disable-next-line import/no-unresolved
import { ClientOnly } from 'remix-utils/client-only'
import { AuthWrapper } from 'src/common/AuthWrapper'
import { ProfileTags } from 'src/common/ProfileTags'
import { isPreciousPlastic } from 'src/config/config'
Expand Down Expand Up @@ -36,7 +38,7 @@ import type { UserCreatedDocs } from '../types'

interface IProps {
user: IUser
docs: UserCreatedDocs | undefined
docs: UserCreatedDocs
}

const getCoverImages = (user: IUser) => {
Expand Down Expand Up @@ -232,7 +234,9 @@ export const SpaceProfile = ({ user, docs }: IProps) => {
)}
<TabPanel>
<Box>
<UserContactForm user={user} />
<ClientOnly fallback={<></>}>
{() => <UserContactForm user={user} />}
</ClientOnly>
<UserContactAndLinks links={userLinks} />
</Box>
</TabPanel>
Expand Down
5 changes: 2 additions & 3 deletions src/pages/User/content/UserCreatedDocuments.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import * as React from 'react'
import { Flex, Heading } from 'theme-ui'

import UserCreatedDocumentsItem from './UserCreatedDocumentsItem'

import type { UserCreatedDocs } from '../types'

interface IProps {
docs: UserCreatedDocs | undefined
docs: UserCreatedDocs
}

const UserCreatedDocuments = ({ docs }: IProps) => {
return (
<>
{(docs?.howtos.length > 0 || docs?.research.length > 0) && (
{(docs.howtos.length > 0 || docs.research.length > 0) && (
<Flex pt={2} sx={{ justifyContent: 'space-between', gap: 4 }}>
{docs?.howtos.length > 0 && (
<Flex
Expand Down
179 changes: 63 additions & 116 deletions src/pages/User/content/UserProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,137 +1,84 @@
import { useEffect, useState } from 'react'
import { useParams } from '@remix-run/react'
import { useMemo } from 'react'
import { observer } from 'mobx-react-lite'
import { Button, InternalLink, Loader } from 'oa-components'
import { Button, InternalLink } from 'oa-components'
import { ProfileTypeList } from 'oa-shared'
// eslint-disable-next-line import/no-unresolved
import { ClientOnly } from 'remix-utils/client-only'
import { useCommonStores } from 'src/common/hooks/useCommonStores'
import { incrementViewCount } from 'src/utils/incrementViewCount'
import { seoTagsUpdate } from 'src/utils/seo'
import { Flex, Text } from 'theme-ui'
import { Flex } from 'theme-ui'

import { logger } from '../../../logger'
import { MemberProfile } from './MemberProfile'
import { SpaceProfile } from './SpaceProfile'

import type { IUserDB } from 'oa-shared'
import type { UserCreatedDocs } from '../types'

type UserProfileProps = {
profile: IUserDB
userCreatedDocs: UserCreatedDocs
}

/**
* High level wrapper which loads state, then determines
* whether to render a MemberProfile or SpaceProfile.
*/
export const UserProfile = observer(() => {
const { id } = useParams()
const { userStore } = useCommonStores().stores
const [user, setUser] = useState<IUserDB | undefined>()
const [userCreatedDocs, setUserCreatedDocs] = useState<
UserCreatedDocs | undefined
>()
const [isLoading, setIsLoading] = useState<boolean>(true)

useEffect(() => {
const userId = id

if (userId) {
const fetchUserData = async () => {
try {
const userData = await userStore.getUserProfile(userId)
if (userData as IUserDB) {
setUser(userData)

incrementViewCount({
document: userData,
documentType: 'user',
store: userStore,
})

seoTagsUpdate({
title: `${userData.displayName} - Profile`,
})
}
} catch (error) {
logger.error('Error getting user profile', error)
}
}

const fetchUserDocs = async () => {
try {
const docs = await userStore.getUserCreatedDocs(userId)
setUserCreatedDocs(docs)
setIsLoading(false)
} catch (error) {
logger.error('Error getting user created docs', error)
}
}

fetchUserData()
fetchUserDocs()
}
}, [id])

if (isLoading) {
return <Loader />
}
export const UserProfile = observer(
({ profile, userCreatedDocs }: UserProfileProps) => {
const { userStore } = useCommonStores().stores
const isViewingOwnProfile = useMemo(
() => userStore.activeUser?._id === profile?._id,
[userStore.activeUser?._id],
)
const showMemberProfile =
profile?.profileType === ProfileTypeList.MEMBER ||
profile?.profileType === undefined

if (!user) {
return (
<Text
<Flex
sx={{
alignSelf: 'center',
maxWidth: showMemberProfile ? '42em' : '60em',
flexDirection: 'column',
width: '100%',
textAlign: 'center',
display: 'block',
marginTop: 10,
marginTop: isViewingOwnProfile ? 4 : [6, 8],
gap: 4,
}}
>
User not found
</Text>
)
}
{isViewingOwnProfile && (
<InternalLink
sx={{
alignSelf: ['center', 'flex-end'],
marginBottom: showMemberProfile ? [2, 0] : 0,
zIndex: 2,
}}
to="/settings"
>
<Button type="button" data-cy="EditYourProfile">
Edit Your Profile
</Button>
</InternalLink>
)}

const isViewingOwnProfile =
userStore.activeUser && user && userStore.activeUser._id === user._id
const showMemberProfile =
user.profileType === ProfileTypeList.MEMBER ||
user.profileType === undefined

return (
<Flex
sx={{
alignSelf: 'center',
maxWidth: showMemberProfile ? '42em' : '60em',
flexDirection: 'column',
width: '100%',
marginTop: isViewingOwnProfile ? 4 : [6, 8],
gap: 4,
}}
>
{isViewingOwnProfile && (
<InternalLink
sx={{
alignSelf: ['center', 'flex-end'],
marginBottom: showMemberProfile ? [2, 0] : 0,
zIndex: 2,
}}
to="/settings"
>
<Button type="button" data-cy="EditYourProfile">
Edit Your Profile
</Button>
</InternalLink>
)}

{showMemberProfile ? (
<MemberProfile
data-cy="memberProfile"
user={user}
docs={userCreatedDocs}
/>
) : (
<SpaceProfile
data-cy="spaceProfile"
user={user}
docs={userCreatedDocs}
/>
)}
</Flex>
)
})
<ClientOnly fallback={<></>}>
{() => (
<>
{showMemberProfile ? (
<MemberProfile
data-cy="memberProfile"
user={profile}
docs={userCreatedDocs}
/>
) : (
<SpaceProfile
data-cy="spaceProfile"
user={profile}
docs={userCreatedDocs}
/>
)}
</>
)}
</ClientOnly>
</Flex>
)
},
)
6 changes: 4 additions & 2 deletions src/pages/User/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import type { IHowtoDB, IResearchDB } from 'oa-shared'

export interface UserCreatedDocs {
howtos: any
research: any
howtos: IHowtoDB[]
research: IResearchDB[]
}
Loading

0 comments on commit 9c8bb45

Please sign in to comment.