Files
fabdash/frontend/src/store/useProjectStore.js

118 lines
3.1 KiB
JavaScript
Raw Normal View History

2026-03-05 12:13:22 -06:00
import { create } from 'zustand'
2026-03-12 10:23:22 -05:00
import * as projectApi from '../api/projects'
import * as deliverableApi from '../api/deliverables'
2026-03-05 12:13:22 -06:00
const useProjectStore = create((set, get) => ({
projects: [],
loading: false,
error: null,
2026-03-12 10:23:22 -05:00
getProjectById: (id) => get().projects.find(p => p.id === id),
2026-03-05 12:13:22 -06:00
2026-03-12 10:23:22 -05:00
// Async Actions
loadProjects: async () => {
set({ loading: true, error: null })
try {
const data = await projectApi.fetchProjects()
set({ projects: data, loading: false })
} catch (err) {
set({ error: err.message, loading: false })
}
},
2026-03-05 12:13:22 -06:00
2026-03-12 10:23:22 -05:00
createProject: async (data) => {
set({ loading: true })
try {
const newProj = await projectApi.createProject(data)
set(s => ({ projects: [newProj, ...s.projects], loading: false }))
return newProj
} catch (err) {
set({ error: err.message, loading: false })
throw err
}
},
2026-03-05 12:13:22 -06:00
2026-03-12 10:23:22 -05:00
updateProject: async (id, data) => {
try {
const updated = await projectApi.updateProject(id, data)
set(s => ({
projects: s.projects.map(p => p.id === updated.id ? { ...updated, deliverables: p.deliverables } : p),
}))
return updated
} catch (err) {
set({ error: err.message })
throw err
}
},
2026-03-05 12:13:22 -06:00
2026-03-12 10:23:22 -05:00
deleteProject: async (id) => {
try {
await projectApi.deleteProject(id)
set(s => ({ projects: s.projects.filter(p => p.id !== id) }))
} catch (err) {
set({ error: err.message })
throw err
}
},
2026-03-05 12:13:22 -06:00
2026-03-12 10:23:22 -05:00
toggleArchive: async (id, isArchived) => {
try {
const updated = isArchived
? await projectApi.unarchiveProject(id)
: await projectApi.archiveProject(id)
set(s => ({
projects: s.projects.map(p => p.id === updated.id ? { ...updated, deliverables: p.deliverables } : p),
}))
} catch (err) {
set({ error: err.message })
throw err
}
},
2026-03-05 12:13:22 -06:00
2026-03-12 10:23:22 -05:00
addDeliverable: async (data) => {
try {
const d = await deliverableApi.createDeliverable(data)
set(s => ({
projects: s.projects.map(p => p.id === d.project_id
? { ...p, deliverables: [...(p.deliverables||[]), d].sort((a,b) => new Date(a.due_date)-new Date(b.due_date)) }
: p
),
}))
return d
} catch (err) {
set({ error: err.message })
throw err
}
},
2026-03-05 12:13:22 -06:00
2026-03-12 10:23:22 -05:00
updateDeliverable: async (id, data) => {
try {
const updated = await deliverableApi.updateDeliverable(id, data)
set(s => ({
projects: s.projects.map(p => p.id === updated.project_id
? { ...p, deliverables: (p.deliverables||[]).map(d => d.id === updated.id ? updated : d) }
: p
),
}))
return updated
} catch (err) {
set({ error: err.message })
throw err
}
},
removeDeliverable: async (id) => {
try {
await deliverableApi.deleteDeliverable(id)
set(s => ({
projects: s.projects.map(p => ({ ...p, deliverables: (p.deliverables||[]).filter(d => d.id !== id) })),
}))
} catch (err) {
set({ error: err.message })
throw err
}
},
2026-03-05 12:13:22 -06:00
}))
export default useProjectStore