webapp/src/components/Feed/Sidebar/Sidebar.tsx

148 lines
4.1 KiB
TypeScript
Raw Normal View History

import { createSignal, For, Show } from 'solid-js'
import type { Author } from '../../../graphql/types.gen'
import { useAuthorsStore } from '../../../stores/zine/authors'
import { Icon } from '../../_shared/Icon'
import { useTopicsStore } from '../../../stores/zine/topics'
import { useArticlesStore } from '../../../stores/zine/articles'
import { useSeenStore } from '../../../stores/zine/seen'
import { useSession } from '../../../context/session'
import { useLocalize } from '../../../context/localize'
import styles from './Sidebar.module.scss'
2023-06-06 21:16:40 +00:00
import { clsx } from 'clsx'
type FeedSidebarProps = {
authors: Author[]
}
type ListItem = {
title: string
icon?: string
counter?: number
href?: string
isBold?: boolean
}
export const Sidebar = (props: FeedSidebarProps) => {
const { t } = useLocalize()
const { seen } = useSeenStore()
const { session } = useSession()
const { authorEntities } = useAuthorsStore({ authors: props.authors })
const { articlesByTopic } = useArticlesStore()
const { topicEntities } = useTopicsStore()
2023-06-06 21:16:40 +00:00
const [isSubscriptionsVisible, setSubscriptionsVisible] = createSignal(true)
const checkTopicIsSeen = (topicSlug: string) => {
return articlesByTopic()[topicSlug]?.every((article) => Boolean(seen()[article.slug]))
}
const checkAuthorIsSeen = (authorSlug: string) => {
return Boolean(seen()[authorSlug])
}
const menuItems: ListItem[] = [
{
icon: 'feed-all',
title: t('general feed')
},
{
icon: 'feed-my',
2023-06-06 21:16:40 +00:00
title: t('My feed')
},
{
icon: 'feed-collaborate',
2023-06-06 21:16:40 +00:00
title: t('Accomplices')
},
{
icon: 'feed-discussion',
2023-06-06 21:16:40 +00:00
title: t('Discussions'),
counter: 4
},
{
icon: 'feed-drafts',
2023-06-06 21:16:40 +00:00
title: t('Drafts'),
counter: 14
},
{
icon: 'bookmark',
2023-06-06 21:16:40 +00:00
title: t('Bookmarks'),
counter: 6
},
{
icon: 'feed-notifications',
2023-06-06 21:16:40 +00:00
title: t('Notifications')
}
]
return (
<div class={styles.sidebar}>
<ul>
2023-04-29 13:54:15 +00:00
<For each={menuItems}>
2023-05-01 18:32:32 +00:00
{(item: ListItem) => (
<li>
2023-04-29 13:54:15 +00:00
<a href="#">
<span class={styles.sidebarItemName}>
{item.icon && <Icon name={item.icon} class={styles.icon} />}
<strong>{item.title}</strong>
</span>
2023-06-06 21:16:40 +00:00
{item.counter && <span class={styles.counter}>18</span>}
2023-04-29 13:54:15 +00:00
</a>
</li>
)}
</For>
</ul>
2023-05-11 11:52:56 +00:00
<Show when={session()?.news?.authors || session()?.news?.topics}>
<h4
classList={{ [styles.opened]: isSubscriptionsVisible() }}
onClick={() => {
setSubscriptionsVisible(!isSubscriptionsVisible())
}}
>
{t('My subscriptions')}
</h4>
2023-06-06 21:16:40 +00:00
<ul class={clsx(styles.subscriptions, { [styles.hidden]: !isSubscriptionsVisible() })}>
2023-05-11 11:52:56 +00:00
<For each={session()?.news?.authors}>
{(authorSlug: string) => (
<li>
<a
href={`/author/${authorSlug}`}
classList={{ [styles.unread]: checkAuthorIsSeen(authorSlug) }}
>
2023-06-06 21:16:40 +00:00
<div class={styles.sidebarItemName}>
<Icon name="hash" class={styles.icon} />
{authorSlug}
{authorEntities()[authorSlug]?.name}
</div>
2023-05-11 11:52:56 +00:00
</a>
</li>
)}
</For>
<For each={session()?.news?.topics}>
{(topicSlug: string) => (
<li>
<a
href={`/topic/${topicSlug}`}
classList={{ [styles.unread]: checkTopicIsSeen(topicSlug) }}
>
2023-06-06 21:16:40 +00:00
<div class={styles.sidebarItemName}>
<Icon name="hash" class={styles.icon} />
{topicEntities()[topicSlug]?.title ?? topicSlug}
</div>
2023-05-11 11:52:56 +00:00
</a>
</li>
)}
</For>
</ul>
</Show>
<div class={styles.settings}>
<a href="/feed/settings">
<Icon name="settings" class={styles.icon} />
{t('Feed settings')}
</a>
</div>
</div>
)
}