NeonClary's picture
Revert to pre-tutorial version (b0ebe11)
2f63261 verified
Raw
History Blame Contribute Delete
4.36 kB
import { useState, useRef, useEffect } from 'react'
import { Link } from 'react-router-dom'
import { useAuth } from '../context/AuthContext'
import { SampleDataMenuItem } from './SampleDataMenuItem'
import { SpeechSettingsMenuItem } from './SpeechSettingsPanel'
type Props = {
onProfile: () => void
onAccount: () => void
onClearData: () => void
}
export function UserMenu({ onProfile, onAccount, onClearData }: Props) {
const { user, signOut } = useAuth()
const [open, setOpen] = useState(false)
const [speechOpen, setSpeechOpen] = useState(false)
const [sampleDataOpen, setSampleDataOpen] = useState(false)
const ref = useRef<HTMLDivElement>(null)
useEffect(() => {
function close(e: MouseEvent) {
if (ref.current && !ref.current.contains(e.target as Node)) {
setOpen(false)
setSpeechOpen(false)
setSampleDataOpen(false)
}
}
document.addEventListener('mousedown', close)
return () => document.removeEventListener('mousedown', close)
}, [])
const label = user ? user.firstName || user.email : 'Guest'
return (
<div className="user-menu-wrap" ref={ref}>
<button
type="button"
className="user-menu-trigger"
onClick={() => setOpen((o) => !o)}
aria-expanded={open}
aria-haspopup="menu"
aria-label="Account menu"
>
<span className="user-menu-name">{label}</span>
<span className="user-menu-kebab" aria-hidden title="Menu">
</span>
</button>
{open && (
<div className="user-dropdown" role="menu">
<button
type="button"
role="menuitem"
onClick={() => {
setOpen(false)
setSpeechOpen(false)
setSampleDataOpen(false)
onProfile()
}}
>
Profile
</button>
<button
type="button"
role="menuitem"
onClick={() => {
setOpen(false)
setSpeechOpen(false)
setSampleDataOpen(false)
if (user) onAccount()
}}
disabled={!user}
title={!user ? 'Sign in to change account settings' : undefined}
style={!user ? { opacity: 0.55, cursor: 'not-allowed' } : undefined}
>
Account
</button>
<button
type="button"
role="menuitem"
onClick={() => {
setOpen(false)
setSpeechOpen(false)
setSampleDataOpen(false)
onClearData()
}}
>
Clear User Data
</button>
<SampleDataMenuItem
open={sampleDataOpen}
onToggle={() => {
setSampleDataOpen((s) => !s)
setSpeechOpen(false)
}}
onActionComplete={() => {
setOpen(false)
setSpeechOpen(false)
setSampleDataOpen(false)
}}
/>
<div className="user-dropdown-divider" role="presentation" />
<SpeechSettingsMenuItem
open={speechOpen}
onToggle={() => {
setSpeechOpen((s) => !s)
setSampleDataOpen(false)
}}
/>
{user ? (
<button
type="button"
role="menuitem"
className="danger"
onClick={() => {
setOpen(false)
setSpeechOpen(false)
setSampleDataOpen(false)
signOut()
}}
>
Sign out
</button>
) : (
<Link
to="/auth"
role="menuitem"
className="user-dropdown-link"
onClick={() => {
setOpen(false)
setSpeechOpen(false)
setSampleDataOpen(false)
}}
style={{ display: 'block', padding: '0.5rem 1rem', textDecoration: 'none', color: 'inherit' }}
>
Sign In / Create Account
</Link>
)}
</div>
)}
</div>
)
}