Teach AuthContext
to manage the private user doc (#738)
* Return both user and privateUser from `createuser` * Make `useStateCheckEquality` more flexible * Make `AuthContext` track the private user doc * Change `usePrivateUser` hook to use the auth context data * Pass both user and private user through SSR to auth context * Fix bug in create user flow
This commit is contained in:
parent
3cbf5a6f7d
commit
3cb28cdecb
|
@ -98,7 +98,7 @@ export const createuser = newEndpoint(opts, async (req, auth) => {
|
||||||
await sendWelcomeEmail(user, privateUser)
|
await sendWelcomeEmail(user, privateUser)
|
||||||
await track(auth.uid, 'create user', { username }, { ip: req.ip })
|
await track(auth.uid, 'create user', { username }, { ip: req.ip })
|
||||||
|
|
||||||
return user
|
return { user, privateUser }
|
||||||
})
|
})
|
||||||
|
|
||||||
const firestore = admin.firestore()
|
const firestore = admin.firestore()
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { ReactNode, createContext, useEffect } from 'react'
|
import { ReactNode, createContext, useEffect } from 'react'
|
||||||
import { User } from 'common/user'
|
|
||||||
import { onIdTokenChanged } from 'firebase/auth'
|
import { onIdTokenChanged } from 'firebase/auth'
|
||||||
import {
|
import {
|
||||||
|
UserAndPrivateUser,
|
||||||
auth,
|
auth,
|
||||||
listenForUser,
|
listenForUser,
|
||||||
getUser,
|
listenForPrivateUser,
|
||||||
|
getUserAndPrivateUser,
|
||||||
setCachedReferralInfoForUser,
|
setCachedReferralInfoForUser,
|
||||||
} from 'web/lib/firebase/users'
|
} from 'web/lib/firebase/users'
|
||||||
import { deleteTokenCookies, setTokenCookies } from 'web/lib/firebase/auth'
|
import { deleteTokenCookies, setTokenCookies } from 'web/lib/firebase/auth'
|
||||||
|
@ -14,10 +15,10 @@ import { identifyUser, setUserProperty } from 'web/lib/service/analytics'
|
||||||
import { useStateCheckEquality } from 'web/hooks/use-state-check-equality'
|
import { useStateCheckEquality } from 'web/hooks/use-state-check-equality'
|
||||||
|
|
||||||
// Either we haven't looked up the logged in user yet (undefined), or we know
|
// Either we haven't looked up the logged in user yet (undefined), or we know
|
||||||
// the user is not logged in (null), or we know the user is logged in (User).
|
// the user is not logged in (null), or we know the user is logged in.
|
||||||
type AuthUser = undefined | null | User
|
type AuthUser = undefined | null | UserAndPrivateUser
|
||||||
|
|
||||||
const CACHED_USER_KEY = 'CACHED_USER_KEY'
|
const CACHED_USER_KEY = 'CACHED_USER_KEY_V2'
|
||||||
|
|
||||||
const ensureDeviceToken = () => {
|
const ensureDeviceToken = () => {
|
||||||
let deviceToken = localStorage.getItem('device-token')
|
let deviceToken = localStorage.getItem('device-token')
|
||||||
|
@ -36,6 +37,7 @@ export function AuthProvider(props: {
|
||||||
}) {
|
}) {
|
||||||
const { children, serverUser } = props
|
const { children, serverUser } = props
|
||||||
const [authUser, setAuthUser] = useStateCheckEquality<AuthUser>(serverUser)
|
const [authUser, setAuthUser] = useStateCheckEquality<AuthUser>(serverUser)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (serverUser === undefined) {
|
if (serverUser === undefined) {
|
||||||
const cachedUser = localStorage.getItem(CACHED_USER_KEY)
|
const cachedUser = localStorage.getItem(CACHED_USER_KEY)
|
||||||
|
@ -50,16 +52,16 @@ export function AuthProvider(props: {
|
||||||
id: await fbUser.getIdToken(),
|
id: await fbUser.getIdToken(),
|
||||||
refresh: fbUser.refreshToken,
|
refresh: fbUser.refreshToken,
|
||||||
})
|
})
|
||||||
let user = await getUser(fbUser.uid)
|
let current = await getUserAndPrivateUser(fbUser.uid)
|
||||||
if (!user) {
|
if (!current.user || !current.privateUser) {
|
||||||
const deviceToken = ensureDeviceToken()
|
const deviceToken = ensureDeviceToken()
|
||||||
user = (await createUser({ deviceToken })) as User
|
current = (await createUser({ deviceToken })) as UserAndPrivateUser
|
||||||
}
|
}
|
||||||
setAuthUser(user)
|
setAuthUser(current)
|
||||||
// Persist to local storage, to reduce login blink next time.
|
// Persist to local storage, to reduce login blink next time.
|
||||||
// Note: Cap on localStorage size is ~5mb
|
// Note: Cap on localStorage size is ~5mb
|
||||||
localStorage.setItem(CACHED_USER_KEY, JSON.stringify(user))
|
localStorage.setItem(CACHED_USER_KEY, JSON.stringify(current))
|
||||||
setCachedReferralInfoForUser(user)
|
setCachedReferralInfoForUser(current.user)
|
||||||
} else {
|
} else {
|
||||||
// User logged out; reset to null
|
// User logged out; reset to null
|
||||||
deleteTokenCookies()
|
deleteTokenCookies()
|
||||||
|
@ -69,15 +71,30 @@ export function AuthProvider(props: {
|
||||||
})
|
})
|
||||||
}, [setAuthUser])
|
}, [setAuthUser])
|
||||||
|
|
||||||
const authUserId = authUser?.id
|
const uid = authUser?.user.id
|
||||||
const authUsername = authUser?.username
|
const username = authUser?.user.username
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (authUserId && authUsername) {
|
if (uid && username) {
|
||||||
identifyUser(authUserId)
|
identifyUser(uid)
|
||||||
setUserProperty('username', authUsername)
|
setUserProperty('username', username)
|
||||||
return listenForUser(authUserId, setAuthUser)
|
const userListener = listenForUser(uid, (user) =>
|
||||||
|
setAuthUser((authUser) => {
|
||||||
|
/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
|
||||||
|
return { ...authUser!, user: user! }
|
||||||
|
})
|
||||||
|
)
|
||||||
|
const privateUserListener = listenForPrivateUser(uid, (privateUser) => {
|
||||||
|
setAuthUser((authUser) => {
|
||||||
|
/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
|
||||||
|
return { ...authUser!, privateUser: privateUser! }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return () => {
|
||||||
|
userListener()
|
||||||
|
privateUserListener()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [authUserId, authUsername, setAuthUser])
|
}, [uid, username, setAuthUser])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AuthContext.Provider value={authUser}>{children}</AuthContext.Provider>
|
<AuthContext.Provider value={authUser}>{children}</AuthContext.Provider>
|
||||||
|
|
|
@ -31,7 +31,7 @@ export function GroupChat(props: {
|
||||||
}) {
|
}) {
|
||||||
const { messages, user, group, tips } = props
|
const { messages, user, group, tips } = props
|
||||||
|
|
||||||
const privateUser = usePrivateUser(user?.id)
|
const privateUser = usePrivateUser()
|
||||||
|
|
||||||
const { editor, upload } = useTextEditor({
|
const { editor, upload } = useTextEditor({
|
||||||
simple: true,
|
simple: true,
|
||||||
|
|
|
@ -44,7 +44,7 @@ export function BottomNavBar() {
|
||||||
const currentPage = router.pathname
|
const currentPage = router.pathname
|
||||||
|
|
||||||
const user = useUser()
|
const user = useUser()
|
||||||
const privateUser = usePrivateUser(user?.id)
|
const privateUser = usePrivateUser()
|
||||||
|
|
||||||
const isIframe = useIsIframe()
|
const isIframe = useIsIframe()
|
||||||
if (isIframe) {
|
if (isIframe) {
|
||||||
|
|
|
@ -221,7 +221,7 @@ export default function Sidebar(props: { className?: string }) {
|
||||||
const currentPage = router.pathname
|
const currentPage = router.pathname
|
||||||
|
|
||||||
const user = useUser()
|
const user = useUser()
|
||||||
const privateUser = usePrivateUser(user?.id)
|
const privateUser = usePrivateUser()
|
||||||
// usePing(user?.id)
|
// usePing(user?.id)
|
||||||
|
|
||||||
const navigationOptions = !user ? signedOutNavigation : getNavigation()
|
const navigationOptions = !user ? signedOutNavigation : getNavigation()
|
||||||
|
|
|
@ -2,15 +2,14 @@ import { BellIcon } from '@heroicons/react/outline'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { Row } from 'web/components/layout/row'
|
import { Row } from 'web/components/layout/row'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { usePrivateUser, useUser } from 'web/hooks/use-user'
|
import { usePrivateUser } from 'web/hooks/use-user'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import { useUnseenPreferredNotificationGroups } from 'web/hooks/use-notifications'
|
import { useUnseenPreferredNotificationGroups } from 'web/hooks/use-notifications'
|
||||||
import { NOTIFICATIONS_PER_PAGE } from 'web/pages/notifications'
|
import { NOTIFICATIONS_PER_PAGE } from 'web/pages/notifications'
|
||||||
import { PrivateUser } from 'common/user'
|
import { PrivateUser } from 'common/user'
|
||||||
|
|
||||||
export default function NotificationsIcon(props: { className?: string }) {
|
export default function NotificationsIcon(props: { className?: string }) {
|
||||||
const user = useUser()
|
const privateUser = usePrivateUser()
|
||||||
const privateUser = usePrivateUser(user?.id)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row className={clsx('justify-center')}>
|
<Row className={clsx('justify-center')}>
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { isAdmin } from 'common/envs/constants'
|
import { isAdmin } from 'common/envs/constants'
|
||||||
import { usePrivateUser, useUser } from './use-user'
|
import { usePrivateUser } from './use-user'
|
||||||
|
|
||||||
export const useAdmin = () => {
|
export const useAdmin = () => {
|
||||||
const user = useUser()
|
const privateUser = usePrivateUser()
|
||||||
const privateUser = usePrivateUser(user?.id)
|
|
||||||
return isAdmin(privateUser?.email || '')
|
return isAdmin(privateUser?.email || '')
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { isEqual } from 'lodash'
|
import { isEqual } from 'lodash'
|
||||||
import { useMemo, useRef, useState } from 'react'
|
import { SetStateAction, useMemo, useRef, useState } from 'react'
|
||||||
|
|
||||||
export const useStateCheckEquality = <T>(initialState: T) => {
|
export const useStateCheckEquality = <T>(initialState: T) => {
|
||||||
const [state, setState] = useState(initialState)
|
const [state, setState] = useState(initialState)
|
||||||
|
@ -8,8 +8,9 @@ export const useStateCheckEquality = <T>(initialState: T) => {
|
||||||
stateRef.current = state
|
stateRef.current = state
|
||||||
|
|
||||||
const checkSetState = useMemo(
|
const checkSetState = useMemo(
|
||||||
() => (newState: T) => {
|
() => (next: SetStateAction<T>) => {
|
||||||
const state = stateRef.current
|
const state = stateRef.current
|
||||||
|
const newState = next instanceof Function ? next(state) : next
|
||||||
if (!isEqual(state, newState)) {
|
if (!isEqual(state, newState)) {
|
||||||
setState(newState)
|
setState(newState)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,19 @@
|
||||||
import { useContext, useEffect, useState } from 'react'
|
import { useContext } from 'react'
|
||||||
import { useFirestoreDocumentData } from '@react-query-firebase/firestore'
|
import { useFirestoreDocumentData } from '@react-query-firebase/firestore'
|
||||||
import { QueryClient } from 'react-query'
|
import { QueryClient } from 'react-query'
|
||||||
|
|
||||||
import { doc, DocumentData, where } from 'firebase/firestore'
|
import { doc, DocumentData } from 'firebase/firestore'
|
||||||
import { PrivateUser } from 'common/user'
|
import { getUser, User, users } from 'web/lib/firebase/users'
|
||||||
import {
|
|
||||||
getUser,
|
|
||||||
listenForPrivateUser,
|
|
||||||
User,
|
|
||||||
users,
|
|
||||||
} from 'web/lib/firebase/users'
|
|
||||||
import { AuthContext } from 'web/components/auth-context'
|
import { AuthContext } from 'web/components/auth-context'
|
||||||
|
|
||||||
export const useUser = () => {
|
export const useUser = () => {
|
||||||
return useContext(AuthContext)
|
const authUser = useContext(AuthContext)
|
||||||
|
return authUser ? authUser.user : authUser
|
||||||
}
|
}
|
||||||
|
|
||||||
export const usePrivateUser = (userId?: string) => {
|
export const usePrivateUser = () => {
|
||||||
const [privateUser, setPrivateUser] = useState<
|
const authUser = useContext(AuthContext)
|
||||||
PrivateUser | null | undefined
|
return authUser ? authUser.privateUser : authUser
|
||||||
>(undefined)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (userId) return listenForPrivateUser(userId, setPrivateUser)
|
|
||||||
}, [userId])
|
|
||||||
|
|
||||||
return privateUser
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useUserById = (userId = '_') => {
|
export const useUserById = (userId = '_') => {
|
||||||
|
|
|
@ -43,6 +43,8 @@ export const privateUsers = coll<PrivateUser>('private-users')
|
||||||
|
|
||||||
export type { User }
|
export type { User }
|
||||||
|
|
||||||
|
export type UserAndPrivateUser = { user: User; privateUser: PrivateUser }
|
||||||
|
|
||||||
export type Period = 'daily' | 'weekly' | 'monthly' | 'allTime'
|
export type Period = 'daily' | 'weekly' | 'monthly' | 'allTime'
|
||||||
|
|
||||||
export const auth = getAuth(app)
|
export const auth = getAuth(app)
|
||||||
|
@ -57,6 +59,16 @@ export async function getPrivateUser(userId: string) {
|
||||||
return (await getDoc(doc(privateUsers, userId))).data()!
|
return (await getDoc(doc(privateUsers, userId))).data()!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getUserAndPrivateUser(userId: string) {
|
||||||
|
const [user, privateUser] = (
|
||||||
|
await Promise.all([
|
||||||
|
getDoc(doc(users, userId))!, // eslint-disable-line @typescript-eslint/no-non-null-assertion
|
||||||
|
getDoc(doc(privateUsers, userId))!, // eslint-disable-line @typescript-eslint/no-non-null-assertion
|
||||||
|
])
|
||||||
|
).map((d) => d.data()) as [User, PrivateUser]
|
||||||
|
return { user, privateUser } as UserAndPrivateUser
|
||||||
|
}
|
||||||
|
|
||||||
export async function getUserByUsername(username: string) {
|
export async function getUserByUsername(username: string) {
|
||||||
// Find a user whose username matches the given username, or null if no such user exists.
|
// Find a user whose username matches the given username, or null if no such user exists.
|
||||||
const q = query(users, where('username', '==', username), limit(1))
|
const q = query(users, where('username', '==', username), limit(1))
|
||||||
|
|
|
@ -79,7 +79,7 @@ function MyApp({ Component, pageProps }: AppProps) {
|
||||||
content="width=device-width, initial-scale=1, maximum-scale=1"
|
content="width=device-width, initial-scale=1, maximum-scale=1"
|
||||||
/>
|
/>
|
||||||
</Head>
|
</Head>
|
||||||
<AuthProvider serverUser={pageProps.user}>
|
<AuthProvider serverUser={pageProps.authUser}>
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<Welcome {...pageProps} />
|
<Welcome {...pageProps} />
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
|
|
|
@ -4,7 +4,7 @@ import clsx from 'clsx'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import Textarea from 'react-expanding-textarea'
|
import Textarea from 'react-expanding-textarea'
|
||||||
import { Spacer } from 'web/components/layout/spacer'
|
import { Spacer } from 'web/components/layout/spacer'
|
||||||
import { getUser } from 'web/lib/firebase/users'
|
import { getUserAndPrivateUser } from 'web/lib/firebase/users'
|
||||||
import { Contract, contractPath } from 'web/lib/firebase/contracts'
|
import { Contract, contractPath } from 'web/lib/firebase/contracts'
|
||||||
import { createMarket } from 'web/lib/firebase/api'
|
import { createMarket } from 'web/lib/firebase/api'
|
||||||
import { FIXED_ANTE } from 'common/antes'
|
import { FIXED_ANTE } from 'common/antes'
|
||||||
|
@ -34,8 +34,7 @@ import { SEO } from 'web/components/SEO'
|
||||||
import { MultipleChoiceAnswers } from 'web/components/answers/multiple-choice-answers'
|
import { MultipleChoiceAnswers } from 'web/components/answers/multiple-choice-answers'
|
||||||
|
|
||||||
export const getServerSideProps = redirectIfLoggedOut('/', async (_, creds) => {
|
export const getServerSideProps = redirectIfLoggedOut('/', async (_, creds) => {
|
||||||
const user = await getUser(creds.user.uid)
|
return { props: { auth: await getUserAndPrivateUser(creds.user.uid) } }
|
||||||
return { props: { user } }
|
|
||||||
})
|
})
|
||||||
|
|
||||||
type NewQuestionParams = {
|
type NewQuestionParams = {
|
||||||
|
@ -52,9 +51,9 @@ type NewQuestionParams = {
|
||||||
initValue?: string
|
initValue?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Create(props: { user: User }) {
|
export default function Create(props: { auth: { user: User } }) {
|
||||||
useTracking('view create page')
|
useTracking('view create page')
|
||||||
const { user } = props
|
const { user } = props.auth
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const params = router.query as NewQuestionParams
|
const params = router.query as NewQuestionParams
|
||||||
// TODO: Not sure why Question is pulled out as its own component;
|
// TODO: Not sure why Question is pulled out as its own component;
|
||||||
|
|
|
@ -10,19 +10,18 @@ import { Contract } from 'common/contract'
|
||||||
import { User } from 'common/user'
|
import { User } from 'common/user'
|
||||||
import { ContractPageContent } from './[username]/[contractSlug]'
|
import { ContractPageContent } from './[username]/[contractSlug]'
|
||||||
import { getContractFromSlug } from 'web/lib/firebase/contracts'
|
import { getContractFromSlug } from 'web/lib/firebase/contracts'
|
||||||
import { getUser } from 'web/lib/firebase/users'
|
import { getUserAndPrivateUser } from 'web/lib/firebase/users'
|
||||||
import { useTracking } from 'web/hooks/use-tracking'
|
import { useTracking } from 'web/hooks/use-tracking'
|
||||||
import { track } from 'web/lib/service/analytics'
|
import { track } from 'web/lib/service/analytics'
|
||||||
import { redirectIfLoggedOut } from 'web/lib/firebase/server-auth'
|
import { redirectIfLoggedOut } from 'web/lib/firebase/server-auth'
|
||||||
import { useSaveReferral } from 'web/hooks/use-save-referral'
|
import { useSaveReferral } from 'web/hooks/use-save-referral'
|
||||||
|
|
||||||
export const getServerSideProps = redirectIfLoggedOut('/', async (_, creds) => {
|
export const getServerSideProps = redirectIfLoggedOut('/', async (_, creds) => {
|
||||||
const user = await getUser(creds.user.uid)
|
return { props: { auth: await getUserAndPrivateUser(creds.user.uid) } }
|
||||||
return { props: { user } }
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const Home = (props: { user: User }) => {
|
const Home = (props: { auth: { user: User } }) => {
|
||||||
const { user } = props
|
const { user } = props.auth
|
||||||
const [contract, setContract] = useContractPage()
|
const [contract, setContract] = useContractPage()
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { Page } from 'web/components/page'
|
||||||
import { SEO } from 'web/components/SEO'
|
import { SEO } from 'web/components/SEO'
|
||||||
import { Title } from 'web/components/title'
|
import { Title } from 'web/components/title'
|
||||||
import { Subtitle } from 'web/components/subtitle'
|
import { Subtitle } from 'web/components/subtitle'
|
||||||
import { getUser } from 'web/lib/firebase/users'
|
import { getUserAndPrivateUser } from 'web/lib/firebase/users'
|
||||||
import { useUserManalinks } from 'web/lib/firebase/manalinks'
|
import { useUserManalinks } from 'web/lib/firebase/manalinks'
|
||||||
import { useUserById } from 'web/hooks/use-user'
|
import { useUserById } from 'web/hooks/use-user'
|
||||||
import { ManalinkTxn } from 'common/txn'
|
import { ManalinkTxn } from 'common/txn'
|
||||||
|
@ -31,16 +31,15 @@ import { SiteLink } from 'web/components/site-link'
|
||||||
const LINKS_PER_PAGE = 24
|
const LINKS_PER_PAGE = 24
|
||||||
|
|
||||||
export const getServerSideProps = redirectIfLoggedOut('/', async (_, creds) => {
|
export const getServerSideProps = redirectIfLoggedOut('/', async (_, creds) => {
|
||||||
const user = await getUser(creds.user.uid)
|
return { props: { auth: await getUserAndPrivateUser(creds.user.uid) } }
|
||||||
return { props: { user } }
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export function getManalinkUrl(slug: string) {
|
export function getManalinkUrl(slug: string) {
|
||||||
return `${location.protocol}//${location.host}/link/${slug}`
|
return `${location.protocol}//${location.host}/link/${slug}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function LinkPage(props: { user: User }) {
|
export default function LinkPage(props: { auth: { user: User } }) {
|
||||||
const { user } = props
|
const { user } = props.auth
|
||||||
const links = useUserManalinks(user.id ?? '')
|
const links = useUserManalinks(user.id ?? '')
|
||||||
// const manalinkTxns = useManalinkTxns(user?.id ?? '')
|
// const manalinkTxns = useManalinkTxns(user?.id ?? '')
|
||||||
const [highlightedSlug, setHighlightedSlug] = useState('')
|
const [highlightedSlug, setHighlightedSlug] = useState('')
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
MANIFOLD_USERNAME,
|
MANIFOLD_USERNAME,
|
||||||
PrivateUser,
|
PrivateUser,
|
||||||
} from 'common/user'
|
} from 'common/user'
|
||||||
import { getPrivateUser } from 'web/lib/firebase/users'
|
import { getUserAndPrivateUser } from 'web/lib/firebase/users'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { RelativeTimestamp } from 'web/components/relative-timestamp'
|
import { RelativeTimestamp } from 'web/components/relative-timestamp'
|
||||||
import { Linkify } from 'web/components/linkify'
|
import { Linkify } from 'web/components/linkify'
|
||||||
|
@ -46,12 +46,13 @@ const MULTIPLE_USERS_KEY = 'multipleUsers'
|
||||||
const HIGHLIGHT_CLASS = 'bg-indigo-50'
|
const HIGHLIGHT_CLASS = 'bg-indigo-50'
|
||||||
|
|
||||||
export const getServerSideProps = redirectIfLoggedOut('/', async (_, creds) => {
|
export const getServerSideProps = redirectIfLoggedOut('/', async (_, creds) => {
|
||||||
const privateUser = await getPrivateUser(creds.user.uid)
|
return { props: { auth: await getUserAndPrivateUser(creds.user.uid) } }
|
||||||
return { props: { privateUser } }
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export default function Notifications(props: { privateUser: PrivateUser }) {
|
export default function Notifications(props: {
|
||||||
const { privateUser } = props
|
auth: { privateUser: PrivateUser }
|
||||||
|
}) {
|
||||||
|
const { privateUser } = props.auth
|
||||||
const local = safeLocalStorage()
|
const local = safeLocalStorage()
|
||||||
let localNotifications = [] as Notification[]
|
let localNotifications = [] as Notification[]
|
||||||
const localSavedNotificationGroups = local?.getItem('notification-groups')
|
const localSavedNotificationGroups = local?.getItem('notification-groups')
|
||||||
|
|
|
@ -13,8 +13,7 @@ import { Col } from 'web/components/layout/col'
|
||||||
import { Row } from 'web/components/layout/row'
|
import { Row } from 'web/components/layout/row'
|
||||||
import { User, PrivateUser } from 'common/user'
|
import { User, PrivateUser } from 'common/user'
|
||||||
import {
|
import {
|
||||||
getUser,
|
getUserAndPrivateUser,
|
||||||
getPrivateUser,
|
|
||||||
updateUser,
|
updateUser,
|
||||||
updatePrivateUser,
|
updatePrivateUser,
|
||||||
} from 'web/lib/firebase/users'
|
} from 'web/lib/firebase/users'
|
||||||
|
@ -24,11 +23,7 @@ import Textarea from 'react-expanding-textarea'
|
||||||
import { redirectIfLoggedOut } from 'web/lib/firebase/server-auth'
|
import { redirectIfLoggedOut } from 'web/lib/firebase/server-auth'
|
||||||
|
|
||||||
export const getServerSideProps = redirectIfLoggedOut('/', async (_, creds) => {
|
export const getServerSideProps = redirectIfLoggedOut('/', async (_, creds) => {
|
||||||
const [user, privateUser] = await Promise.all([
|
return { props: { auth: await getUserAndPrivateUser(creds.user.uid) } }
|
||||||
getUser(creds.user.uid),
|
|
||||||
getPrivateUser(creds.user.uid),
|
|
||||||
])
|
|
||||||
return { props: { user, privateUser } }
|
|
||||||
})
|
})
|
||||||
|
|
||||||
function EditUserField(props: {
|
function EditUserField(props: {
|
||||||
|
@ -69,10 +64,9 @@ function EditUserField(props: {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ProfilePage(props: {
|
export default function ProfilePage(props: {
|
||||||
user: User
|
auth: { user: User; privateUser: PrivateUser }
|
||||||
privateUser: PrivateUser
|
|
||||||
}) {
|
}) {
|
||||||
const { user, privateUser } = props
|
const { user, privateUser } = props.auth
|
||||||
const [avatarUrl, setAvatarUrl] = useState(user.avatarUrl || '')
|
const [avatarUrl, setAvatarUrl] = useState(user.avatarUrl || '')
|
||||||
const [avatarLoading, setAvatarLoading] = useState(false)
|
const [avatarLoading, setAvatarLoading] = useState(false)
|
||||||
const [name, setName] = useState(user.name)
|
const [name, setName] = useState(user.name)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user