webapp/src/components/Author/AuthorBadge/AuthorBadge.tsx

111 lines
3.5 KiB
TypeScript
Raw Normal View History

import { clsx } from 'clsx'
import styles from './AuthorBadge.module.scss'
import { Userpic } from '../Userpic'
import { Author, FollowingEntity } from '../../../graphql/types.gen'
import { createMemo, createSignal, Match, Show, Switch } from 'solid-js'
import { formatDate } from '../../../utils'
import { useLocalize } from '../../../context/localize'
import { Button } from '../../_shared/Button'
import { useSession } from '../../../context/session'
import { follow, unfollow } from '../../../stores/zine/common'
import { CheckButton } from '../../_shared/CheckButton'
type Props = {
author: Author
minimizeSubscribeButton?: boolean
}
export const AuthorBadge = (props: Props) => {
const [isSubscribing, setIsSubscribing] = createSignal(false)
const {
session,
2023-10-05 04:24:01 +00:00
actions: { loadSession, requireAuthentication }
} = useSession()
const { t } = useLocalize()
const subscribed = createMemo<boolean>(() => {
return session()?.news?.authors?.some((u) => u === props.author.slug) || false
})
const subscribe = async (really = true) => {
setIsSubscribing(true)
await (really
? follow({ what: FollowingEntity.Author, slug: props.author.slug })
: unfollow({ what: FollowingEntity.Author, slug: props.author.slug }))
await loadSession()
setIsSubscribing(false)
}
2023-10-05 04:24:01 +00:00
const handleSubscribe = (really: boolean) => {
requireAuthentication(() => {
subscribe(really)
}, 'subscribe')
}
return (
<div class={clsx(styles.AuthorBadge)}>
2023-10-09 21:22:06 +00:00
<Userpic
hasLink={true}
isMedium={true}
name={props.author.name}
userpic={props.author.userpic}
slug={props.author.slug}
/>
<a href={`/author/${props.author.slug}`} class={styles.info}>
<div class={styles.name}>{props.author.name}</div>
<Switch
fallback={
<div class={styles.bio}>
{t('Registered since {date}', { date: formatDate(new Date(props.author.createdAt)) })}
</div>
}
>
<Match when={props.author.bio}>
<div class={clsx('text-truncate', styles.bio)} innerHTML={props.author.bio} />
</Match>
<Match when={props.author?.stat && props.author?.stat.shouts > 0}>
<div class={styles.bio}>
{t('PublicationsWithCount', { count: props.author.stat?.shouts ?? 0 })}
</div>
</Match>
</Switch>
</a>
2023-10-05 04:24:01 +00:00
<Show when={props.author.slug !== session()?.user.slug}>
<div class={styles.actions}>
<Show
when={!props.minimizeSubscribeButton}
fallback={
<CheckButton
text={t('Follow')}
checked={subscribed()}
2023-10-05 04:24:01 +00:00
onClick={() => handleSubscribe(!subscribed())}
/>
}
>
<Show
when={subscribed()}
fallback={
<Button
variant="primary"
size="S"
value={isSubscribing() ? t('...subscribing') : t('Subscribe')}
2023-10-05 04:24:01 +00:00
onClick={() => handleSubscribe(true)}
2023-10-09 21:22:06 +00:00
class={styles.subscribeButton}
/>
}
>
<Button
2023-10-09 21:22:06 +00:00
variant="bordered"
size="S"
2023-10-16 09:54:14 +00:00
value={t('Following')}
2023-10-05 04:24:01 +00:00
onClick={() => handleSubscribe(false)}
2023-10-09 21:22:06 +00:00
class={styles.subscribeButton}
/>
</Show>
</Show>
</div>
</Show>
</div>
)
}