webapp/src/components/Nav/HeaderAuth.tsx

233 lines
8.0 KiB
TypeScript
Raw Normal View History

import { getPagePath } from '@nanostores/router'
import { clsx } from 'clsx'
import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js'
import { useEditorContext } from '../../context/editor'
2023-02-17 09:21:02 +00:00
import { useLocalize } from '../../context/localize'
import { useNotifications } from '../../context/notifications'
import { useSession } from '../../context/session'
import { router, useRouter } from '../../stores/router'
import { showModal } from '../../stores/ui'
import { Button } from '../_shared/Button'
import { Icon } from '../_shared/Icon'
import { Popover } from '../_shared/Popover'
import { ShowOnlyOnClient } from '../_shared/ShowOnlyOnClient'
import { Userpic } from '../Author/Userpic'
import { ProfilePopup } from './ProfilePopup'
import styles from './Header/Header.module.scss'
type Props = {
setIsProfilePopupVisible: (value: boolean) => void
}
type IconedButtonProps = {
value: string
icon: string
action: () => void
}
const MD_WIDTH_BREAKPOINT = 992
export const HeaderAuth = (props: Props) => {
2023-02-17 09:21:02 +00:00
const { t } = useLocalize()
const { page } = useRouter()
2024-01-18 15:57:10 +00:00
const { session, author, isAuthenticated } = useSession()
const {
unreadNotificationsCount,
actions: { showNotificationsPanel },
} = useNotifications()
2023-05-03 16:13:48 +00:00
const {
form,
actions: { toggleEditorPanel, saveShout, publishShout },
2023-05-03 16:13:48 +00:00
} = useEditorContext()
const handleBellIconClick = (event: Event) => {
event.preventDefault()
if (!isAuthenticated()) {
showModal('auth')
return
}
showNotificationsPanel()
}
2023-05-31 12:23:18 +00:00
const isEditorPage = createMemo(() => page().route === 'edit' || page().route === 'editSettings')
const isNotificationsVisible = createMemo(() => isAuthenticated() && !isEditorPage())
const isSaveButtonVisible = createMemo(() => isAuthenticated() && isEditorPage())
const isCreatePostButtonVisible = createMemo(() => isAuthenticated() && !isEditorPage())
const isAuthenticatedControlsVisible = createMemo(() => isAuthenticated())
2023-04-20 13:58:56 +00:00
2023-05-01 18:32:32 +00:00
const handleBurgerButtonClick = () => {
2023-05-03 16:13:48 +00:00
toggleEditorPanel()
2023-05-01 18:32:32 +00:00
}
2023-05-08 17:21:06 +00:00
const handleSaveButtonClick = () => {
saveShout(form)
2023-05-08 17:21:06 +00:00
}
const handlePublishButtonClick = () => {
publishShout(form)
2023-05-05 20:05:50 +00:00
}
const [width, setWidth] = createSignal(0)
onMount(() => {
const handleResize = () => setWidth(window.innerWidth)
handleResize()
window.addEventListener('resize', handleResize)
onCleanup(() => window.removeEventListener('resize', handleResize))
})
const renderIconedButton = (buttonProps: IconedButtonProps) => {
return (
<Show
when={width() < MD_WIDTH_BREAKPOINT}
fallback={
<Button
value={<span class={styles.textLabel}>{buttonProps.value}</span>}
2023-10-31 21:21:30 +00:00
variant={'light'}
onClick={buttonProps.action}
2023-10-31 21:21:30 +00:00
class={styles.editorControl}
/>
}
>
<Popover content={buttonProps.value}>
{(ref) => (
<Button
ref={ref}
2023-10-31 21:21:30 +00:00
variant={'light'}
onClick={buttonProps.action}
value={<Icon name={buttonProps.icon} class={styles.icon} />}
2023-10-31 21:21:30 +00:00
class={styles.editorControl}
/>
)}
</Popover>
</Show>
)
}
return (
<ShowOnlyOnClient>
2024-01-18 15:57:10 +00:00
<Show when={session()?.user?.email_verified} keyed={true}>
2023-10-16 20:11:08 +00:00
<div class={clsx('col-auto col-lg-7', styles.usernav)}>
2023-09-04 20:45:02 +00:00
<div class={styles.userControl}>
<Show when={isCreatePostButtonVisible()}>
2023-03-23 17:15:50 +00:00
<div class={clsx(styles.userControlItem, styles.userControlItemVerbose)}>
<a href={getPagePath(router, 'create')}>
<span class={styles.textLabel}>{t('Create post')}</span>
<Icon name="pencil" class={styles.icon} />
2023-07-23 15:59:28 +00:00
<Icon name="pencil" class={clsx(styles.icon, styles.iconHover)} />
2023-03-23 17:15:50 +00:00
</a>
</div>
</Show>
2023-10-31 21:21:30 +00:00
<Show when={!isSaveButtonVisible()}>
<div class={styles.userControlItem}>
2023-11-02 19:21:51 +00:00
<button onClick={() => showModal('search')}>
2023-10-31 21:21:30 +00:00
<Icon name="search" class={styles.icon} />
<Icon name="search" class={clsx(styles.icon, styles.iconHover)} />
2023-11-02 19:21:51 +00:00
</button>
2023-10-31 21:21:30 +00:00
</div>
</Show>
2023-05-24 21:51:47 +00:00
2023-12-15 13:45:34 +00:00
<Show when={isNotificationsVisible() || !author()}>
<div class={styles.userControlItem} onClick={handleBellIconClick}>
2023-10-16 22:13:13 +00:00
<div class={styles.button}>
2023-12-15 13:45:34 +00:00
<Icon
name="bell-white"
2023-12-24 08:16:41 +00:00
counter={session() ? unreadNotificationsCount() || 0 : 1}
2023-12-15 13:45:34 +00:00
class={styles.icon}
/>
2023-10-16 22:13:13 +00:00
<Icon
name="bell-white-hover"
2023-12-24 08:16:41 +00:00
counter={session() ? unreadNotificationsCount() || 0 : 1}
2023-10-16 22:13:13 +00:00
class={clsx(styles.icon, styles.iconHover)}
/>
</div>
</div>
</Show>
2023-10-23 22:35:02 +00:00
<Show when={isSaveButtonVisible()}>
<div class={clsx(styles.userControlItem, styles.userControlItemVerbose)}>
{renderIconedButton({
value: t('Save'),
icon: 'save',
action: handleSaveButtonClick,
})}
</div>
<div class={clsx(styles.userControlItem, styles.userControlItemVerbose)}>
{renderIconedButton({
value: t('Publish'),
icon: 'publish',
action: handlePublishButtonClick,
})}
</div>
2023-04-06 21:40:34 +00:00
<div class={clsx(styles.userControlItem, styles.userControlItemVerbose)}>
<Popover content={t('Settings')}>
{(ref) => (
<Button
ref={ref}
value={<Icon name="burger" />}
2023-10-31 21:21:30 +00:00
variant={'light'}
onClick={handleBurgerButtonClick}
2023-10-31 21:21:30 +00:00
class={styles.settingsControl}
/>
)}
</Popover>
2023-04-06 21:40:34 +00:00
</div>
</Show>
<Show
when={isAuthenticatedControlsVisible()}
fallback={
<div class={clsx(styles.userControlItem, styles.userControlItemVerbose, 'loginbtn')}>
<a href="?modal=auth&mode=login">
<span class={styles.textLabel}>{t('Enter')}</span>
2023-10-16 20:11:08 +00:00
<Icon name="key" class={styles.icon} />
2023-07-18 21:50:27 +00:00
{/*<Icon name="user-default" class={clsx(styles.icon, styles.iconHover)} />*/}
</a>
</div>
}
>
2023-10-31 21:21:30 +00:00
<Show when={!isSaveButtonVisible()}>
<div class={clsx(styles.userControlItem, styles.userControlItemInbox)}>
2023-12-25 05:31:26 +00:00
<a href={getPagePath(router, 'inbox')}>
2023-10-31 21:21:30 +00:00
<div classList={{ entered: page().path === '/inbox' }}>
<Icon name="inbox-white" class={styles.icon} />
<Icon name="inbox-white-hover" class={clsx(styles.icon, styles.iconHover)} />
</div>
</a>
</div>
</Show>
<ProfilePopup
onVisibilityChange={(isVisible) => {
props.setIsProfilePopupVisible(isVisible)
}}
containerCssClass={styles.control}
trigger={
<div class={styles.userControlItem}>
<button class={styles.button}>
2023-11-29 20:24:33 +00:00
<div classList={{ entered: page().path === `/${author()?.slug}` }}>
2023-08-11 16:42:41 +00:00
<Userpic
size={'M'}
2023-12-08 11:49:50 +00:00
name={author()?.name}
userpic={author()?.pic}
2023-08-11 16:42:41 +00:00
class={styles.userpic}
/>
</div>
</button>
</div>
}
/>
</Show>
</div>
</div>
</Show>
</ShowOnlyOnClient>
)
}