writekit/frontends/studio/src/stores/interactions.ts

75 lines
2.2 KiB
TypeScript
Raw Normal View History

2026-01-09 00:16:46 +02:00
import { atom, map, computed, onMount } from 'nanostores'
import { createFetcherStore, createBlogMutatorStore } from './fetcher'
import type { InteractionConfig } from '../types'
const defaultConfig: InteractionConfig = {
comments_enabled: false,
reactions_enabled: false,
reaction_mode: 'emoji',
reaction_emojis: '👍,❤️,🎉,🚀',
upvote_icon: 'arrow',
reactions_require_auth: false,
}
export const $interactionsData = createFetcherStore<InteractionConfig>(['/api/studio/interaction-config'])
export const $interactions = map<InteractionConfig>({ ...defaultConfig })
export const $initialInteractions = atom<InteractionConfig | null>(null)
export const $hasInteractionChanges = computed(
[$interactions, $initialInteractions],
(current, initial) => initial !== null && JSON.stringify(current) !== JSON.stringify(initial)
)
export const $changedInteractionFields = computed(
[$interactions, $initialInteractions],
(current, initial) => {
if (!initial) return []
const changes: string[] = []
const labels: Record<string, string> = {
comments_enabled: 'Comments',
reactions_enabled: 'Reactions',
reaction_mode: 'Reaction mode',
reaction_emojis: 'Emojis',
upvote_icon: 'Upvote icon',
reactions_require_auth: 'Auth required',
}
for (const key of Object.keys(current) as (keyof InteractionConfig)[]) {
if (current[key] !== initial[key]) {
changes.push(labels[key] || key)
}
}
return changes
}
)
onMount($interactionsData, () => {
$interactionsData.listen(({ data }) => {
if (data) {
const merged = { ...defaultConfig, ...data }
$interactions.set(merged)
$initialInteractions.set(merged)
}
})
})
export const $saveInteractions = createBlogMutatorStore<InteractionConfig>(
async ({ data: config }) => {
const previous = $initialInteractions.get()
$initialInteractions.set({ ...config })
const res = await fetch('/api/studio/interaction-config', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(config),
})
if (!res.ok) {
$initialInteractions.set(previous)
throw new Error('Failed to save interactions')
}
return config
}
)