mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-03-25 10:02:27 -04:00
125 lines
4.0 KiB
TypeScript
125 lines
4.0 KiB
TypeScript
import {debug} from 'common/logger'
|
|
import {Profile, ProfileWithoutUser} from 'common/profiles/profile'
|
|
import {BaseUser, User} from 'common/user'
|
|
import {filterDefined} from 'common/util/array'
|
|
import {removeUndefinedProps} from 'common/util/object'
|
|
import Router from 'next/router'
|
|
import {useEffect, useState} from 'react'
|
|
import toast from 'react-hot-toast'
|
|
import {BackButton} from 'web/components/back-button'
|
|
import {Col} from 'web/components/layout/col'
|
|
import {OptionalProfileUserForm} from 'web/components/optional-profile-form'
|
|
import {PageBase} from 'web/components/page-base'
|
|
import {RequiredProfileUserForm} from 'web/components/required-profile-form'
|
|
import {SEO} from 'web/components/SEO'
|
|
import {CompassLoadingIndicator} from 'web/components/widgets/loading-indicator'
|
|
import {useProfileByUser} from 'web/hooks/use-profile'
|
|
import {useUser} from 'web/hooks/use-user'
|
|
import {api, updateProfile, updateUser} from 'web/lib/api'
|
|
import {useT} from 'web/lib/locale'
|
|
|
|
export default function ProfilePage() {
|
|
const user = useUser()
|
|
const {profile} = useProfileByUser(user ?? undefined)
|
|
const [showLoading, setShowLoading] = useState(false)
|
|
|
|
useEffect(() => {
|
|
if (user === null || profile === null) {
|
|
Router.replace('/')
|
|
}
|
|
}, [user])
|
|
|
|
useEffect(() => {
|
|
if (!user || !profile) {
|
|
const timer = setTimeout(() => {
|
|
setShowLoading(true)
|
|
}, 1000)
|
|
return () => clearTimeout(timer)
|
|
} else {
|
|
setShowLoading(false)
|
|
}
|
|
}, [user, profile])
|
|
|
|
return user && profile ? (
|
|
<ProfilePageInner user={user} profile={profile} />
|
|
) : (
|
|
<PageBase trackPageView={'profile'}>
|
|
<Col className="items-center">{showLoading ? <CompassLoadingIndicator /> : null}</Col>
|
|
</PageBase>
|
|
)
|
|
}
|
|
|
|
function ProfilePageInner(props: {user: User; profile: Profile}) {
|
|
const {user} = props
|
|
const t = useT()
|
|
|
|
const [profile, setProfile] = useState<Profile>({
|
|
...props.profile,
|
|
user,
|
|
})
|
|
|
|
const setProfileState = <K extends keyof ProfileWithoutUser>(
|
|
key: K,
|
|
value: ProfileWithoutUser[K] | undefined,
|
|
) => {
|
|
setProfile((prevState) => ({...prevState, [key]: value}))
|
|
}
|
|
|
|
const [baseUser, setBaseUser] = useState<BaseUser>(user)
|
|
|
|
const setBaseUserState = <K extends keyof BaseUser>(key: K, value: BaseUser[K] | undefined) => {
|
|
setBaseUser((prevState) => ({...prevState, [key]: value}))
|
|
}
|
|
|
|
async function submitForm() {
|
|
const {interests, causes, work, ...otherProfileProps} = profile
|
|
const parsedProfile = removeUndefinedProps(otherProfileProps) as any
|
|
debug('parsedProfile', parsedProfile)
|
|
const promises: Promise<any>[] = filterDefined([
|
|
updateProfile(parsedProfile),
|
|
baseUser && updateUser(baseUser),
|
|
interests && api('update-options', {table: 'interests', values: interests}),
|
|
causes && api('update-options', {table: 'causes', values: causes}),
|
|
work && api('update-options', {table: 'work', values: work}),
|
|
])
|
|
try {
|
|
await Promise.all(promises)
|
|
} catch (error) {
|
|
console.error(error)
|
|
toast.error(
|
|
`We ran into an issue saving your profile. Please try again or contact us if the issue persists.`,
|
|
)
|
|
return
|
|
}
|
|
Router.push(`/${user.username}`)
|
|
}
|
|
|
|
return (
|
|
<PageBase trackPageView={'profile'}>
|
|
<SEO
|
|
title={t('profile.seo.title', 'Profile')}
|
|
description={t('profile.seo.description', 'Your Profile')}
|
|
url={`/profile`}
|
|
/>
|
|
<Col className="items-center">
|
|
<BackButton className="-ml-2 mb-2 self-start" />
|
|
<Col className={'w-full px-6 py-4'}>
|
|
<RequiredProfileUserForm
|
|
data={baseUser}
|
|
setData={setBaseUserState}
|
|
profileCreatedAlready
|
|
/>
|
|
<div className={'h-4'} />
|
|
<OptionalProfileUserForm
|
|
profile={profile}
|
|
setProfile={setProfileState}
|
|
user={baseUser}
|
|
buttonLabel={t('profile.save', 'Save')}
|
|
onSubmit={async () => await submitForm()}
|
|
/>
|
|
</Col>
|
|
</Col>
|
|
</PageBase>
|
|
)
|
|
}
|