feat: add src/store/cmsStore.ts
This commit is contained in:
parent
f96dfd8002
commit
9703fe4ad9
|
|
@ -0,0 +1,251 @@
|
|||
import { create } from 'zustand'
|
||||
import { persist } from 'zustand/middleware'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { Post, Page, GalleryImage, NavItem, SiteSettings, Category } from '@/types'
|
||||
|
||||
interface CMSState {
|
||||
posts: Post[]
|
||||
pages: Page[]
|
||||
gallery: GalleryImage[]
|
||||
navItems: NavItem[]
|
||||
categories: Category[]
|
||||
settings: SiteSettings
|
||||
|
||||
// Posts
|
||||
addPost: (post: Omit<Post, 'id' | 'createdAt' | 'updatedAt' | 'views'>) => Post
|
||||
updatePost: (id: string, data: Partial<Post>) => void
|
||||
deletePost: (id: string) => void
|
||||
getPost: (id: string) => Post | undefined
|
||||
|
||||
// Pages
|
||||
addPage: (page: Omit<Page, 'id' | 'createdAt' | 'updatedAt'>) => Page
|
||||
updatePage: (id: string, data: Partial<Page>) => void
|
||||
deletePage: (id: string) => void
|
||||
getPage: (id: string) => Page | undefined
|
||||
|
||||
// Gallery
|
||||
addImage: (image: Omit<GalleryImage, 'id' | 'uploadedAt'>) => void
|
||||
deleteImage: (id: string) => void
|
||||
updateImage: (id: string, data: Partial<GalleryImage>) => void
|
||||
|
||||
// Navigation
|
||||
addNavItem: (item: Omit<NavItem, 'id'>) => void
|
||||
updateNavItem: (id: string, data: Partial<NavItem>) => void
|
||||
deleteNavItem: (id: string) => void
|
||||
reorderNavItems: (items: NavItem[]) => void
|
||||
|
||||
// Categories
|
||||
addCategory: (cat: Omit<Category, 'id'>) => void
|
||||
updateCategory: (id: string, data: Partial<Category>) => void
|
||||
deleteCategory: (id: string) => void
|
||||
|
||||
// Settings
|
||||
updateSettings: (data: Partial<SiteSettings>) => void
|
||||
}
|
||||
|
||||
const now = () => new Date().toISOString()
|
||||
|
||||
const DEMO_POSTS: Post[] = [
|
||||
{
|
||||
id: '1',
|
||||
title: 'Bienvenue sur mon blog',
|
||||
slug: 'bienvenue-sur-mon-blog',
|
||||
content: '<h2>Bonjour tout le monde !</h2><p>Ceci est mon premier article de blog. Je suis ravi de partager mes pensées et expériences avec vous.</p><p>Ce CMS vous permet de gérer facilement vos articles, pages, galerie et navigation.</p>',
|
||||
excerpt: 'Mon premier article de blog pour inaugurer ce CMS personnel.',
|
||||
status: 'published',
|
||||
category: 'Général',
|
||||
tags: ['bienvenue', 'premier article'],
|
||||
author: 'admin',
|
||||
createdAt: new Date(Date.now() - 7 * 24 * 3600 * 1000).toISOString(),
|
||||
updatedAt: new Date(Date.now() - 7 * 24 * 3600 * 1000).toISOString(),
|
||||
publishedAt: new Date(Date.now() - 7 * 24 * 3600 * 1000).toISOString(),
|
||||
views: 142,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Guide de démarrage rapide',
|
||||
slug: 'guide-demarrage-rapide',
|
||||
content: '<h2>Premiers pas avec le CMS</h2><p>Ce guide vous explique comment utiliser toutes les fonctionnalités du CMS.</p><ul><li>Créer des articles</li><li>Gérer les pages</li><li>Organiser la galerie</li><li>Configurer la navigation</li></ul>',
|
||||
excerpt: 'Apprenez à utiliser toutes les fonctionnalités du CMS en quelques minutes.',
|
||||
status: 'published',
|
||||
category: 'Tutoriel',
|
||||
tags: ['guide', 'démarrage', 'tutoriel'],
|
||||
author: 'admin',
|
||||
createdAt: new Date(Date.now() - 3 * 24 * 3600 * 1000).toISOString(),
|
||||
updatedAt: new Date(Date.now() - 3 * 24 * 3600 * 1000).toISOString(),
|
||||
publishedAt: new Date(Date.now() - 3 * 24 * 3600 * 1000).toISOString(),
|
||||
views: 89,
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
title: 'Article en brouillon',
|
||||
slug: 'article-en-brouillon',
|
||||
content: '<p>Cet article est en cours de rédaction...</p>',
|
||||
excerpt: 'Un article non publié.',
|
||||
status: 'draft',
|
||||
category: 'Général',
|
||||
tags: ['brouillon'],
|
||||
author: 'editor',
|
||||
createdAt: new Date(Date.now() - 1 * 24 * 3600 * 1000).toISOString(),
|
||||
updatedAt: new Date(Date.now() - 1 * 24 * 3600 * 1000).toISOString(),
|
||||
views: 0,
|
||||
},
|
||||
]
|
||||
|
||||
const DEMO_PAGES: Page[] = [
|
||||
{
|
||||
id: '1',
|
||||
title: 'À propos',
|
||||
slug: 'a-propos',
|
||||
content: '<h2>Qui suis-je ?</h2><p>Bienvenue sur ma page à propos. Je suis un développeur passionné par les nouvelles technologies.</p>',
|
||||
status: 'published',
|
||||
template: 'default',
|
||||
createdAt: new Date(Date.now() - 14 * 24 * 3600 * 1000).toISOString(),
|
||||
updatedAt: new Date(Date.now() - 14 * 24 * 3600 * 1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Contact',
|
||||
slug: 'contact',
|
||||
content: '<h2>Me contacter</h2><p>N\'hésitez pas à me contacter pour toute question.</p>',
|
||||
status: 'published',
|
||||
template: 'default',
|
||||
createdAt: new Date(Date.now() - 10 * 24 * 3600 * 1000).toISOString(),
|
||||
updatedAt: new Date(Date.now() - 10 * 24 * 3600 * 1000).toISOString(),
|
||||
},
|
||||
]
|
||||
|
||||
const DEMO_NAV: NavItem[] = [
|
||||
{ id: '1', label: 'Accueil', href: '/', order: 0, isExternal: false },
|
||||
{ id: '2', label: 'Blog', href: '/blog', order: 1, isExternal: false },
|
||||
{ id: '3', label: 'À propos', href: '/a-propos', order: 2, isExternal: false },
|
||||
{ id: '4', label: 'Contact', href: '/contact', order: 3, isExternal: false },
|
||||
]
|
||||
|
||||
const DEMO_CATEGORIES: Category[] = [
|
||||
{ id: '1', name: 'Général', slug: 'general', color: '#6366f1' },
|
||||
{ id: '2', name: 'Tutoriel', slug: 'tutoriel', color: '#10b981' },
|
||||
{ id: '3', name: 'Actualité', slug: 'actualite', color: '#f59e0b' },
|
||||
{ id: '4', name: 'Projet', slug: 'projet', color: '#ef4444' },
|
||||
]
|
||||
|
||||
const DEFAULT_SETTINGS: SiteSettings = {
|
||||
siteName: 'Mon Blog',
|
||||
siteDescription: 'Un blog personnel propulsé par le CMS',
|
||||
siteUrl: 'https://monblog.com',
|
||||
primaryColor: '#6366f1',
|
||||
postsPerPage: 10,
|
||||
allowComments: true,
|
||||
maintenanceMode: false,
|
||||
socialLinks: {
|
||||
twitter: '',
|
||||
github: '',
|
||||
linkedin: '',
|
||||
},
|
||||
}
|
||||
|
||||
export const useCMSStore = create<CMSState>()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
posts: DEMO_POSTS,
|
||||
pages: DEMO_PAGES,
|
||||
gallery: [],
|
||||
navItems: DEMO_NAV,
|
||||
categories: DEMO_CATEGORIES,
|
||||
settings: DEFAULT_SETTINGS,
|
||||
|
||||
// Posts
|
||||
addPost: (postData) => {
|
||||
const post: Post = {
|
||||
...postData,
|
||||
id: uuidv4(),
|
||||
createdAt: now(),
|
||||
updatedAt: now(),
|
||||
views: 0,
|
||||
}
|
||||
set((s) => ({ posts: [post, ...s.posts] }))
|
||||
return post
|
||||
},
|
||||
updatePost: (id, data) =>
|
||||
set((s) => ({
|
||||
posts: s.posts.map((p) =>
|
||||
p.id === id ? { ...p, ...data, updatedAt: now() } : p
|
||||
),
|
||||
})),
|
||||
deletePost: (id) =>
|
||||
set((s) => ({ posts: s.posts.filter((p) => p.id !== id) })),
|
||||
getPost: (id) => get().posts.find((p) => p.id === id),
|
||||
|
||||
// Pages
|
||||
addPage: (pageData) => {
|
||||
const page: Page = {
|
||||
...pageData,
|
||||
id: uuidv4(),
|
||||
createdAt: now(),
|
||||
updatedAt: now(),
|
||||
}
|
||||
set((s) => ({ pages: [page, ...s.pages] }))
|
||||
return page
|
||||
},
|
||||
updatePage: (id, data) =>
|
||||
set((s) => ({
|
||||
pages: s.pages.map((p) =>
|
||||
p.id === id ? { ...p, ...data, updatedAt: now() } : p
|
||||
),
|
||||
})),
|
||||
deletePage: (id) =>
|
||||
set((s) => ({ pages: s.pages.filter((p) => p.id !== id) })),
|
||||
getPage: (id) => get().pages.find((p) => p.id === id),
|
||||
|
||||
// Gallery
|
||||
addImage: (imgData) => {
|
||||
const image: GalleryImage = {
|
||||
...imgData,
|
||||
id: uuidv4(),
|
||||
uploadedAt: now(),
|
||||
}
|
||||
set((s) => ({ gallery: [image, ...s.gallery] }))
|
||||
},
|
||||
deleteImage: (id) =>
|
||||
set((s) => ({ gallery: s.gallery.filter((i) => i.id !== id) })),
|
||||
updateImage: (id, data) =>
|
||||
set((s) => ({
|
||||
gallery: s.gallery.map((i) => (i.id === id ? { ...i, ...data } : i)),
|
||||
})),
|
||||
|
||||
// Navigation
|
||||
addNavItem: (itemData) => {
|
||||
const item: NavItem = { ...itemData, id: uuidv4() }
|
||||
set((s) => ({ navItems: [...s.navItems, item] }))
|
||||
},
|
||||
updateNavItem: (id, data) =>
|
||||
set((s) => ({
|
||||
navItems: s.navItems.map((i) => (i.id === id ? { ...i, ...data } : i)),
|
||||
})),
|
||||
deleteNavItem: (id) =>
|
||||
set((s) => ({ navItems: s.navItems.filter((i) => i.id !== id) })),
|
||||
reorderNavItems: (items) => set({ navItems: items }),
|
||||
|
||||
// Categories
|
||||
addCategory: (catData) => {
|
||||
const cat: Category = { ...catData, id: uuidv4() }
|
||||
set((s) => ({ categories: [...s.categories, cat] }))
|
||||
},
|
||||
updateCategory: (id, data) =>
|
||||
set((s) => ({
|
||||
categories: s.categories.map((c) =>
|
||||
c.id === id ? { ...c, ...data } : c
|
||||
),
|
||||
})),
|
||||
deleteCategory: (id) =>
|
||||
set((s) => ({ categories: s.categories.filter((c) => c.id !== id) })),
|
||||
|
||||
// Settings
|
||||
updateSettings: (data) =>
|
||||
set((s) => ({ settings: { ...s.settings, ...data } })),
|
||||
}),
|
||||
{
|
||||
name: 'cms-data',
|
||||
}
|
||||
)
|
||||
)
|
||||
Loading…
Reference in New Issue