refactor: move studio to frontends workspace
- Move studio from root to frontends/studio/ - Add owner-tools frontend for live blog admin UI - Add shared ui component library - Set up npm workspaces for frontends - Add enhanced code block extension for editor Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
c662e41b97
commit
bef5dd4437
108 changed files with 8650 additions and 441 deletions
74
frontends/studio/src/stores/interactions.ts
Normal file
74
frontends/studio/src/stores/interactions.ts
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
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
|
||||
}
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue