diff --git a/components/Header/index.scss b/components/Header/index.scss
index b80b650e..6599906d 100644
--- a/components/Header/index.scss
+++ b/components/Header/index.scss
@@ -1,23 +1,24 @@
-.Header {
+#Header {
display: flex;
+ flex-direction: row;
margin-bottom: $unit;
+ justify-content: space-between;
width: 100%;
- &.bottom {
- position: sticky;
- bottom: $unit * 2;
- }
-
- #right > div {
+ #Right > div {
display: flex;
- gap: 8px;
+ gap: $unit;
}
- .dropdown {
+ #DropdownWrapper {
display: inline-block;
- position: relative;
padding-bottom: $unit;
+ &:hover .Menu,
+ .Menu.open {
+ display: block;
+ }
+
&:hover {
padding-right: $unit-4x;
@@ -25,17 +26,9 @@
background: var(--button-bg-hover);
color: var(--button-text-hover);
}
-
- .Menu {
- display: block;
- }
}
}
- .push {
- margin-left: auto;
- }
-
@include breakpoint(phone) {
.Button .Text {
display: none;
diff --git a/components/Header/index.tsx b/components/Header/index.tsx
index 16ec9bea..ad34982e 100644
--- a/components/Header/index.tsx
+++ b/components/Header/index.tsx
@@ -1,19 +1,183 @@
-import React from 'react'
+import React, { useState } from 'react'
+import { useSnapshot } from 'valtio'
+import { deleteCookie } from 'cookies-next'
+import { useRouter } from 'next/router'
+import { useTranslation } from 'next-i18next'
+
+import clonedeep from 'lodash.clonedeep'
+
+import api from '~utils/api'
+import { accountState, initialAccountState } from '~utils/accountState'
+import { appState, initialAppState } from '~utils/appState'
+
+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 SaveIcon from '~public/icons/Save.svg'
+import classNames from 'classnames'
import './index.scss'
-interface Props {
- position: 'top' | 'bottom'
- left: JSX.Element
- right: JSX.Element
-}
+const Header = () => {
+ // Localization
+ const { t } = useTranslation('common')
+
+ // Router
+ const router = useRouter()
+
+ // State management
+
+ // Snapshots
+ const { account } = useSnapshot(accountState)
+ const { party } = useSnapshot(appState)
+
+ function onClickOutsideMenu() {
+ setOpen(!open)
+ }
+
+ 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() {
+ deleteCookie('account')
+ deleteCookie('user')
+
+ // Clean state
+ const resetState = clonedeep(initialAccountState)
+ Object.keys(resetState).forEach((key) => {
+ if (key !== 'language') accountState[key] = resetState[key]
+ })
+
+ if (router.route != '/new') appState.party.editable = false
+
+ router.push('/')
+ return false
+ }
+
+ function toggleFavorite() {
+ if (party.favorited) unsaveFavorite()
+ else saveFavorite()
+ }
+
+ function saveFavorite() {
+ if (party.id)
+ api.saveTeam({ id: party.id, params: headers }).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, params: headers }).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 leftNav = () => {
+ return (
+
+ }
+ className={classNames({ Active: open })}
+ blended={true}
+ text={t('buttons.menu')}
+ onClick={menuButtonClicked}
+ />
+
+
+ )
+ }
+
+ const saveButton = () => {
+ if (party.favorited)
+ return (
+ }
+ blended={true}
+ text="Saved"
+ onClick={toggleFavorite}
+ />
+ )
+ else
+ return (
+ }
+ blended={true}
+ text="Save"
+ onClick={toggleFavorite}
+ />
+ )
+ }
+
+ const rightNav = () => {
+ 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}
+ />
+
+ )
+ }
-const Header = (props: Props) => {
return (
-