import React, { useEffect, useState } from 'react' import { useSnapshot } from 'valtio' import { deleteCookie } from 'cookies-next' import { useRouter } from 'next/router' import { useTranslation } from 'next-i18next' import classNames from 'classnames' import clonedeep from 'lodash.clonedeep' import api from '~utils/api' import { accountState, initialAccountState } from '~utils/accountState' import { appState, initialAppState } from '~utils/appState' import capitalizeFirstLetter from '~utils/capitalizeFirstLetter' import Button from '~components/Button' import HeaderMenu from '~components/HeaderMenu' import AddIcon from '~public/icons/Add.svg' import LinkIcon from '~public/icons/Link.svg' import MenuIcon from '~public/icons/Menu.svg' import ArrowIcon from '~public/icons/Arrow.svg' import SaveIcon from '~public/icons/Save.svg' import './index.scss' import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, } from '~components/DropdownMenuContent' import Link from 'next/link' import LoginModal from '~components/LoginModal' import SignupModal from '~components/SignupModal' import AccountModal from '~components/AccountModal' const Header = () => { // Localization const { t } = useTranslation('common') // Router const router = useRouter() // State management const [open, setOpen] = useState(false) const [leftMenuOpen, setLeftMenuOpen] = useState(false) const [rightMenuOpen, setRightMenuOpen] = useState(false) // Snapshots const { account } = useSnapshot(accountState) const { party } = useSnapshot(appState) function handleLeftMenuButtonClicked() { setLeftMenuOpen(!leftMenuOpen) } function handleRightMenuButtonClicked() { setRightMenuOpen(!rightMenuOpen) } function onClickOutsideMenu() { setOpen(false) } function handleLeftMenuOpenChange(open: boolean) { setLeftMenuOpen(open) } function handleRightMenuOpenChange(open: boolean) { setRightMenuOpen(open) } function closeLeftMenu() { setLeftMenuOpen(false) } function closeRightMenu() { setRightMenuOpen(false) } function copyToClipboard() { const el = document.createElement('input') el.value = window.location.href el.id = 'url-input' document.body.appendChild(el) el.select() document.execCommand('copy') el.remove() } function newParty() { // Push the root URL router.push('/') // Clean state const resetState = clonedeep(initialAppState) Object.keys(resetState).forEach((key) => { appState[key] = resetState[key] }) // Set party to be editable appState.party.editable = true } function logout() { // Close menu closeRightMenu() // Delete cookies deleteCookie('account') deleteCookie('user') // Clean state const resetState = clonedeep(initialAccountState) Object.keys(resetState).forEach((key) => { if (key !== 'language') accountState[key] = resetState[key] }) router.reload() return false } function toggleFavorite() { if (party.favorited) unsaveFavorite() else saveFavorite() } function saveFavorite() { if (party.id) api.saveTeam({ id: party.id }).then((response) => { if (response.status == 201) appState.party.favorited = true }) else console.error('Failed to save team: No party ID') } function unsaveFavorite() { if (party.id) api.unsaveTeam({ id: party.id }).then((response) => { if (response.status == 200) appState.party.favorited = false }) else console.error('Failed to unsave team: No party ID') } const copyButton = () => { if (router.route === '/p/[party]') return ( } blended={true} text={t('buttons.copy')} onClick={copyToClipboard} /> ) } const title = () => { let title = '' let hasAccessory = false const path = router.asPath.split('/')[1] console.log(router.asPath.split('/')) if (path === 'p') { hasAccessory = true if (appState.party && appState.party.name) { title = appState.party.name } else { title = t('no_title') } } else if (['weapons', 'summons', 'characters', 'new', ''].includes(path)) { title = t('new_party') } else if ( ['about', 'updates', 'roadmap', 'saved', 'teams'].includes(path) ) { title = capitalizeFirstLetter(path) } else { title = path } return ( ) : undefined } text={title} /> ) } const saveButton = () => { if (party.favorited) return ( } blended={true} text="Saved" onClick={toggleFavorite} /> ) else return ( } blended={true} text="Save" onClick={toggleFavorite} /> ) } const image = () => { let image const user = accountState.account.user if (accountState.account.authorized && user) { image = ( ) } else { image = } return image } const left = () => { return ( } className={classNames({ Active: leftMenuOpen })} blended={true} onClick={handleLeftMenuButtonClicked} /> {leftMenuItems()} {title()} ) } const right = () => { return ( {router.route === '/p/[party]' && account.user && (!party.user || party.user.id !== account.user.id) ? saveButton() : ''} {copyButton()} {/* } blended={true} text={t('buttons.new')} onClick={newParty} /> */} } rightAccessoryClassName="Arrow" onClick={handleRightMenuButtonClicked} blended={true} /> {rightMenuItems()} ) } const leftMenuItems = () => { return ( <> {accountState.account.authorized && accountState.account.user ? ( <> Your profile {t('menu.saved')} > ) : ( '' )} {t('menu.teams')} {t('menu.guides')} {t('coming_soon')} {t('about.segmented_control.about')} {t('about.segmented_control.updates')} {t('about.segmented_control.roadmap')} > ) } const rightMenuItems = () => { let items const account = accountState.account if (account.authorized && account.user) { items = ( <> New party Your profile {t('menu.logout')} > ) } else { items = ( <> New party > ) } return items } return ( {left()} {right()} ) } export default Header