profile page
This commit is contained in:
parent
363a7ba7ae
commit
dee258fb6b
|
@ -31,6 +31,10 @@ function getNavigationOptions(user: User, options: { mobile: boolean }) {
|
|||
name: 'Home',
|
||||
href: '/',
|
||||
},
|
||||
{
|
||||
name: 'Profile',
|
||||
href: '/profile',
|
||||
},
|
||||
...(mobile
|
||||
? [
|
||||
{
|
||||
|
@ -68,9 +72,7 @@ function ProfileSummary(props: { user: User }) {
|
|||
return (
|
||||
<Col className="avatar items-center sm:flex-row gap-2 sm:gap-0">
|
||||
<div className="rounded-full w-10 h-10 sm:mr-4">
|
||||
{user.avatarUrl && (
|
||||
<Image src={user.avatarUrl} width={40} height={40} />
|
||||
)}
|
||||
{user.avatarUrl && <img src={user.avatarUrl} width={40} height={40} />}
|
||||
</div>
|
||||
<div className="truncate text-left" style={{ maxWidth: 170 }}>
|
||||
<div className="hidden sm:flex">{user.name}</div>
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
import { useEffect, useState } from 'react'
|
||||
import { listenForLogin, listenForUser, User } from '../lib/firebase/users'
|
||||
import { PrivateUser } from '../../common/user'
|
||||
import {
|
||||
listenForLogin,
|
||||
listenForPrivateUser,
|
||||
listenForUser,
|
||||
User,
|
||||
} from '../lib/firebase/users'
|
||||
|
||||
export const useUser = () => {
|
||||
const [user, setUser] = useState<User | null | undefined>(undefined)
|
||||
|
@ -14,3 +20,15 @@ export const useUser = () => {
|
|||
|
||||
return user
|
||||
}
|
||||
|
||||
export const usePrivateUser = (userId?: string) => {
|
||||
const [privateUser, setPrivateUser] = useState<
|
||||
PrivateUser | null | undefined
|
||||
>(undefined)
|
||||
|
||||
useEffect(() => {
|
||||
if (userId) return listenForPrivateUser(userId, setPrivateUser)
|
||||
}, [userId])
|
||||
|
||||
return privateUser
|
||||
}
|
||||
|
|
|
@ -53,6 +53,16 @@ export function listenForUser(userId: string, setUser: (user: User) => void) {
|
|||
})
|
||||
}
|
||||
|
||||
export function listenForPrivateUser(
|
||||
userId: string,
|
||||
setPrivateUser: (privateUser: PrivateUser) => void
|
||||
) {
|
||||
const userRef = doc(db, 'private-users', userId)
|
||||
return onSnapshot(userRef, (userSnap) => {
|
||||
setPrivateUser(userSnap.data() as PrivateUser)
|
||||
})
|
||||
}
|
||||
|
||||
const CACHED_USER_KEY = 'CACHED_USER_KEY'
|
||||
|
||||
// used to avoid weird race condition
|
||||
|
|
77
web/pages/profile.tsx
Normal file
77
web/pages/profile.tsx
Normal file
|
@ -0,0 +1,77 @@
|
|||
import Image from 'next/image'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { AddFundsButton } from '../components/add-funds-button'
|
||||
|
||||
import { Page } from '../components/page'
|
||||
import { SEO } from '../components/SEO'
|
||||
import { Title } from '../components/title'
|
||||
import { usePrivateUser, useUser } from '../hooks/use-user'
|
||||
import { formatMoney } from '../lib/util/format'
|
||||
|
||||
export default function ProfilePage() {
|
||||
const user = useUser()
|
||||
const privateUser = usePrivateUser(user?.id)
|
||||
|
||||
const [avatarUrl, setAvatarUrl] = useState(user?.avatarUrl || '')
|
||||
const [name, setName] = useState(user?.name || '')
|
||||
const [username, setUsername] = useState(user?.username || '')
|
||||
|
||||
useEffect(() => {
|
||||
if (user) {
|
||||
setAvatarUrl(user.avatarUrl || '')
|
||||
setName(user.name || '')
|
||||
setUsername(user.username || '')
|
||||
}
|
||||
}, [user])
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<SEO title="Profile" description="User profile settings" url="/profile" />
|
||||
<Title text="Profile" />
|
||||
|
||||
<p>
|
||||
<img
|
||||
src={avatarUrl}
|
||||
width={80}
|
||||
height={80}
|
||||
className="rounded-full bg-gray-400 flex items-center justify-center"
|
||||
/>
|
||||
</p>
|
||||
|
||||
<label className="label">
|
||||
<span className="label-text">Display name</span>
|
||||
</label>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Display name"
|
||||
className="input input-bordered"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value || '')}
|
||||
/>
|
||||
|
||||
<label className="label">
|
||||
<span className="label-text">Username</span>
|
||||
</label>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
className="input input-bordered"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value || '')}
|
||||
/>
|
||||
|
||||
<label className="label">
|
||||
<span className="label-text">Email</span>
|
||||
</label>
|
||||
<p>{privateUser?.email}</p>
|
||||
|
||||
<label className="label">
|
||||
<span className="label-text">Balance</span>
|
||||
</label>
|
||||
<p>{formatMoney(user?.balance || 0)}</p>
|
||||
<AddFundsButton />
|
||||
</Page>
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue
Block a user