import { useEffect, useState } from 'react'
import { RefreshIcon } from '@heroicons/react/outline'
import Router from 'next/router'
import { AddFundsButton } from 'web/components/add-funds-button'
import { Page } from 'web/components/page'
import { SEO } from 'web/components/SEO'
import { Title } from 'web/components/title'
import { usePrivateUser, useUser } from 'web/hooks/use-user'
import { formatMoney } from 'common/util/format'
import { cleanDisplayName, cleanUsername } from 'common/util/clean-username'
import { changeUserInfo } from 'web/lib/firebase/api-call'
import { uploadImage } from 'web/lib/firebase/storage'
import { Col } from 'web/components/layout/col'
import { Row } from 'web/components/layout/row'
import { User } from 'common/user'
import { updateUser, updatePrivateUser } from 'web/lib/firebase/users'
import { defaultBannerUrl } from 'web/components/user-page'
import { SiteLink } from 'web/components/site-link'
import Textarea from 'react-expanding-textarea'
function EditUserField(props: {
user: User
field: 'bio' | 'bannerUrl' | 'twitterHandle' | 'discordHandle'
label: string
}) {
const { user, field, label } = props
const [value, setValue] = useState(user[field] ?? '')
async function updateField() {
// Note: We trim whitespace before uploading to Firestore
await updateUser(user.id, { [field]: value.trim() })
}
return (
{field === 'bio' ? (
)
}
export default function ProfilePage() {
const user = useUser()
const privateUser = usePrivateUser(user?.id)
const [avatarUrl, setAvatarUrl] = useState(user?.avatarUrl || '')
const [avatarLoading, setAvatarLoading] = useState(false)
const [name, setName] = useState(user?.name || '')
const [username, setUsername] = useState(user?.username || '')
const [apiKey, setApiKey] = useState(privateUser?.apiKey || '')
useEffect(() => {
if (user) {
setAvatarUrl(user.avatarUrl || '')
setName(user.name || '')
setUsername(user.username || '')
}
}, [user])
useEffect(() => {
if (privateUser) {
setApiKey(privateUser.apiKey || '')
}
}, [privateUser])
const updateDisplayName = async () => {
const newName = cleanDisplayName(name)
if (newName) {
setName(newName)
await changeUserInfo({ name: newName })
.catch(() => ({ status: 'error' }))
.then((r) => {
if (r.status === 'error') setName(user?.name || '')
})
} else {
setName(user?.name || '')
}
}
const updateUsername = async () => {
const newUsername = cleanUsername(username)
if (newUsername) {
setUsername(newUsername)
await changeUserInfo({ username: newUsername })
.catch(() => ({ status: 'error' }))
.then((r) => {
if (r.status === 'error') setUsername(user?.username || '')
})
} else {
setUsername(user?.username || '')
}
}
const updateApiKey = async (e: React.MouseEvent) => {
const newApiKey = crypto.randomUUID()
if (user?.id != null) {
setApiKey(newApiKey)
await updatePrivateUser(user.id, { apiKey: newApiKey }).catch(() => {
setApiKey(privateUser?.apiKey || '')
})
}
e.preventDefault()
}
const fileHandler = async (event: any) => {
const file = event.target.files[0]
setAvatarLoading(true)
await uploadImage(user?.username || 'default', file)
.then(async (url) => {
await changeUserInfo({ avatarUrl: url })
setAvatarUrl(url)
setAvatarLoading(false)
})
.catch(() => {
setAvatarLoading(false)
setAvatarUrl(user?.avatarUrl || '')
})
}
if (user === null) {
Router.replace('/')
return <>>
}
return (
Done
{avatarLoading ? (
) : (
<>
>
)}
setName(e.target.value || '')}
onBlur={updateDisplayName}
/>
setUsername(e.target.value || '')}
onBlur={updateUsername}
/>
{user && (
<>
{/* TODO: Allow users with M$ 2000 of assets to set custom banners */}
{/* */}
{[
['bio', 'Bio'],
['website', 'Website URL'],
['twitterHandle', 'Twitter'],
['discordHandle', 'Discord'],
].map(([field, label]) => (
))}
>
)}
{privateUser?.email ?? '\u00a0'}
{formatMoney(user?.balance || 0)}
)
}