webapp/src/components/Views/PublishSettings/TopicSelect/TopicSelect.tsx

94 lines
2.7 KiB
TypeScript
Raw Normal View History

import { clsx } from 'clsx'
2024-06-24 17:50:27 +00:00
import { For, Show, createSignal } from 'solid-js'
import { useLocalize } from '~/context/localize'
2024-06-24 17:50:27 +00:00
import type { Topic } from '~/graphql/schema/core.gen'
2023-05-10 20:20:53 +00:00
import styles from './TopicSelect.module.scss'
2023-03-23 17:15:50 +00:00
type TopicSelectProps = {
topics: Topic[]
selectedTopics: Topic[]
2023-03-23 17:15:50 +00:00
onChange: (selectedTopics: Topic[]) => void
2023-05-10 20:20:53 +00:00
mainTopic?: Topic
onMainTopicChange: (mainTopic: Topic) => void
2023-03-23 17:15:50 +00:00
}
export const TopicSelect = (props: TopicSelectProps) => {
const { t } = useLocalize()
2024-06-24 17:50:27 +00:00
const [isOpen, setIsOpen] = createSignal(false)
const [searchTerm, setSearchTerm] = createSignal('')
2023-03-23 17:15:50 +00:00
2024-06-24 17:50:27 +00:00
const handleChange = (topic: Topic) => {
const isSelected = props.selectedTopics.some((selectedTopic) => selectedTopic.slug === topic.slug)
let newSelectedTopics: Topic[]
2023-05-10 20:20:53 +00:00
2024-06-24 17:50:27 +00:00
if (isSelected) {
newSelectedTopics = props.selectedTopics.filter((selectedTopic) => selectedTopic.slug !== topic.slug)
} else {
newSelectedTopics = [...props.selectedTopics, topic]
}
2023-03-23 17:15:50 +00:00
2024-06-24 17:50:27 +00:00
props.onChange(newSelectedTopics)
2023-03-23 17:15:50 +00:00
}
2024-06-24 17:50:27 +00:00
const handleMainTopicChange = (topic: Topic) => {
2023-05-10 20:20:53 +00:00
props.onMainTopicChange(topic)
2024-06-24 17:50:27 +00:00
setIsOpen(false)
2023-05-10 20:20:53 +00:00
}
2024-06-24 17:50:27 +00:00
const handleSearch = (event: InputEvent) => {
setSearchTerm((event.currentTarget as HTMLInputElement).value)
}
2023-05-10 20:20:53 +00:00
2024-06-24 17:50:27 +00:00
const filteredTopics = () => {
return props.topics.filter((topic: Topic) =>
2024-06-26 08:22:05 +00:00
topic?.title?.toLowerCase().includes(searchTerm().toLowerCase())
2023-05-10 20:20:53 +00:00
)
}
return (
2024-06-24 17:50:27 +00:00
<div class="TopicSelect">
<div class={styles.selectedTopics}>
<For each={props.selectedTopics}>
{(topic) => (
<div
class={clsx(styles.selectedTopic, {
2024-06-26 08:22:05 +00:00
[styles.mainTopic]: props.mainTopic?.slug === topic.slug
2024-06-24 17:50:27 +00:00
})}
onClick={() => handleMainTopicChange(topic)}
>
{topic.title}
</div>
)}
</For>
</div>
<div class={styles.selectWrapper} onClick={() => setIsOpen(true)}>
<input
type="text"
placeholder={t('Topics')}
class={styles.searchInput}
value={searchTerm()}
onInput={handleSearch}
/>
<Show when={isOpen()}>
<div class={styles.options}>
<For each={filteredTopics()}>
{(topic) => (
<div
class={clsx(styles.option, {
[styles.disabled]: props.selectedTopics.some(
2024-06-26 08:22:05 +00:00
(selectedTopic) => selectedTopic.slug === topic.slug
)
2024-06-24 17:50:27 +00:00
})}
onClick={() => handleChange(topic)}
>
{topic.title}
</div>
)}
</For>
</div>
</Show>
</div>
</div>
)
2023-03-23 17:15:50 +00:00
}