webapp/src/stores/zine/topics.ts

74 lines
1.9 KiB
TypeScript
Raw Normal View History

2022-09-09 11:53:35 +00:00
import { apiClient } from '../../utils/apiClient'
import type { ReadableAtom, WritableAtom } from 'nanostores'
import { atom, computed } from 'nanostores'
import type { Topic } from '../../graphql/types.gen'
import { useStore } from '@nanostores/solid'
import { byCreated } from '../../utils/sortby'
export type TopicsSortBy = 'created' | 'name'
const sortByStore = atom<TopicsSortBy>('created')
let topicEntitiesStore: WritableAtom<Record<string, Topic>>
let sortedTopicsStore: ReadableAtom<Topic[]>
const initStore = (initial?: Record<string, Topic>) => {
if (topicEntitiesStore) {
return
}
topicEntitiesStore = atom<Record<string, Topic>>(initial)
sortedTopicsStore = computed([topicEntitiesStore, sortByStore], (topicEntities, sortBy) => {
const topics = Object.values(topicEntities)
switch (sortBy) {
case 'created': {
topics.sort(byCreated)
break
}
// eslint-disable-next-line unicorn/no-useless-switch-case
case 'name':
default: {
// use default sorting abc stores
console.debug('[topics.store] default sort')
}
}
return topics
})
}
const addTopics = (topics: Topic[] = []) => {
const newTopicEntities = topics.reduce((acc, topic) => {
acc[topic.slug] = topic
return acc
}, {} as Record<string, Topic>)
if (!topicEntitiesStore) {
initStore(newTopicEntities)
} else {
topicEntitiesStore.set({
...topicEntitiesStore.get(),
...newTopicEntities
})
}
}
export const loadAllTopics = async (): Promise<void> => {
const topics = await apiClient.getAllTopics()
addTopics(topics)
}
type InitialState = {
topics?: Topic[]
randomTopics?: Topic[]
}
2022-09-13 08:05:11 +00:00
export const useTopicsStore = ({ topics }: InitialState) => {
2022-09-09 11:53:35 +00:00
addTopics(topics)
const getTopicEntities = useStore(topicEntitiesStore)
const getSortedTopics = useStore(sortedTopicsStore)
2022-09-13 08:05:11 +00:00
return { getTopicEntities, getSortedTopics }
2022-09-09 11:53:35 +00:00
}