41 lines
1.3 KiB
TypeScript
41 lines
1.3 KiB
TypeScript
import { atom, computed } from 'nanostores'
|
|
import { createFetcherStore, createMutatorStore } from './fetcher'
|
|
import type { Post } from '../types'
|
|
|
|
export const $posts = createFetcherStore<Post[]>(['/api/studio/posts'])
|
|
|
|
export const $search = atom('')
|
|
export const $filterStatus = atom<'all' | 'published' | 'draft'>('all')
|
|
|
|
export const $filteredPosts = computed(
|
|
[$posts, $search, $filterStatus],
|
|
(postsStore, search, status) => {
|
|
const posts = postsStore.data ?? []
|
|
return posts.filter(p => {
|
|
const searchLower = search.toLowerCase()
|
|
if (search && !p.title.toLowerCase().includes(searchLower) && !p.slug.toLowerCase().includes(searchLower)) {
|
|
return false
|
|
}
|
|
if (status === 'published' && p.draft) return false
|
|
if (status === 'draft' && !p.draft) return false
|
|
return true
|
|
})
|
|
}
|
|
)
|
|
|
|
export const $postCounts = computed([$posts], (postsStore) => {
|
|
const posts = postsStore.data ?? []
|
|
return {
|
|
all: posts.length,
|
|
published: posts.filter(p => !p.draft).length,
|
|
draft: posts.filter(p => p.draft).length,
|
|
}
|
|
})
|
|
|
|
export const $deletePost = createMutatorStore<string>(
|
|
async ({ data: slug, invalidate }) => {
|
|
const res = await fetch(`/api/studio/posts/${slug}`, { method: 'DELETE' })
|
|
if (!res.ok) throw new Error('Failed to delete post')
|
|
invalidate('/api/studio/posts')
|
|
}
|
|
)
|