webapp/src/components/Topic/TopicBadge/TopicBadge.tsx

108 lines
3.3 KiB
TypeScript
Raw Normal View History

import { clsx } from 'clsx'
2024-01-31 12:34:15 +00:00
import { createEffect, createSignal, Show } from 'solid-js'
2024-01-31 12:34:15 +00:00
import { useFollowing } from '../../../context/following'
import { useLocalize } from '../../../context/localize'
2024-01-11 17:40:06 +00:00
import { useMediaQuery } from '../../../context/mediaQuery'
import { useSession } from '../../../context/session'
import { FollowingEntity, Topic } from '../../../graphql/schema/core.gen'
2024-01-13 14:26:21 +00:00
import { capitalize } from '../../../utils/capitalize'
import { getImageUrl } from '../../../utils/getImageUrl'
import { Button } from '../../_shared/Button'
import { CheckButton } from '../../_shared/CheckButton'
import styles from './TopicBadge.module.scss'
2024-01-31 12:34:15 +00:00
type Props = {
topic: Topic
minimizeSubscribeButton?: boolean
}
export const TopicBadge = (props: Props) => {
2024-01-11 17:40:06 +00:00
const { t, lang } = useLocalize()
const { mediaMatches } = useMediaQuery()
const [isMobileView, setIsMobileView] = createSignal(false)
const {
2024-01-31 12:34:15 +00:00
actions: { requireAuthentication },
} = useSession()
2024-01-31 12:34:15 +00:00
const { setFollowing, loading: subLoading } = useFollowing()
const [followed, setFollowed] = createSignal()
2024-01-31 12:34:15 +00:00
const handleFollowClick = () => {
const value = !followed()
requireAuthentication(() => {
setFollowed(value)
setFollowing(FollowingEntity.Topic, props.topic.slug, value)
}, 'subscribe')
}
2024-01-31 12:34:15 +00:00
createEffect(() => {
setIsMobileView(!mediaMatches.sm)
})
const title = () =>
lang() === 'en' ? capitalize(props.topic.slug.replaceAll('-', ' ')) : props.topic.title
return (
<div class={styles.TopicBadge}>
2024-01-11 17:40:06 +00:00
<div class={styles.basicInfo}>
<a
href={`/topic/${props.topic.slug}`}
class={clsx(styles.picture, {
[styles.withImage]: props.topic.pic,
[styles.smallSize]: isMobileView(),
})}
style={
props.topic.pic && {
'background-image': `url('${getImageUrl(props.topic.pic, { width: 40, height: 40 })}')`,
}
}
/>
<a href={`/topic/${props.topic.slug}`} class={styles.info}>
<span class={styles.title}>{title()}</span>
<Show
when={props.topic.body}
fallback={
<div class={styles.description}>
{t('PublicationsWithCount', { count: props.topic.stat.shouts ?? 0 })}
</div>
}
>
<div class={clsx('text-truncate', styles.description)}>{props.topic.body}</div>
</Show>
</a>
</div>
<div class={styles.actions}>
<Show
2024-01-11 17:40:06 +00:00
when={!props.minimizeSubscribeButton}
fallback={
2024-01-31 12:34:15 +00:00
<CheckButton text={t('Follow')} checked={Boolean(followed())} onClick={handleFollowClick} />
}
>
<Show
2024-01-31 12:34:15 +00:00
when={followed()}
fallback={
<Button
2024-01-11 17:40:06 +00:00
variant="primary"
size="S"
2024-01-31 12:34:15 +00:00
value={subLoading() ? t('subscribing...') : t('Subscribe')}
onClick={handleFollowClick}
2023-10-09 21:22:06 +00:00
class={styles.subscribeButton}
/>
2024-01-11 17:40:06 +00:00
}
>
<Button
2024-01-31 12:34:15 +00:00
onClick={handleFollowClick}
2024-01-11 17:40:06 +00:00
variant="bordered"
size="S"
value={t('Following')}
class={styles.subscribeButton}
/>
</Show>
2024-01-11 17:40:06 +00:00
</Show>
</div>
</div>
)
}