Files
inq-roi-simulador-web/src/store/library-store.ts

116 lines
3.7 KiB
TypeScript

import { create } from 'zustand'
import { v4 as uuidv4 } from 'uuid'
import { supabaseProcessRepo } from '@/persistence/supabase/process-repo'
import { supabaseGroupRepo } from '@/persistence/supabase/group-repo'
import { supabaseSettingsRepo } from '@/persistence/supabase/settings-repo'
import { simulationRepo } from '@/persistence/repositories'
import type { Process, ProcessGroup, AppSettings, Simulation } from '@/domain/types'
interface LibraryState {
groups: ProcessGroup[]
processes: Process[]
settings: AppSettings
isLoading: boolean
load: () => Promise<void>
createGroup: (name: string, userId: string) => Promise<ProcessGroup>
deleteGroup: (id: string) => Promise<void>
deleteProcess: (id: string) => Promise<void>
assignProcessToGroup: (processId: string, groupId: string | null, userId: string) => Promise<void>
getProcessesByGroup: (groupId: string | null) => Process[]
getLatestSimulation: (processId: string) => Promise<Simulation | undefined>
updateSettings: (updates: Partial<Omit<AppSettings, 'id'>>) => Promise<void>
getAllTags: () => string[]
}
const DEFAULT_SETTINGS: AppSettings = { id: 'singleton', groupLabel: 'Cliente' }
export const useLibraryStore = create<LibraryState>((set, get) => ({
groups: [],
processes: [],
settings: DEFAULT_SETTINGS,
isLoading: false,
load: async () => {
set({ isLoading: true })
try {
const TIMEOUT_MS = 8_000
const [groups, processes, settings] = await Promise.race([
Promise.all([
supabaseGroupRepo.getAll(),
supabaseProcessRepo.getAll(),
supabaseSettingsRepo.get(),
]),
new Promise<never>((_, reject) =>
setTimeout(
() => reject(new Error('Timeout: la biblioteca tardó más de 8s en cargar')),
TIMEOUT_MS,
)
),
])
set({ groups, processes, settings, isLoading: false })
} catch (err) {
console.error('Error al cargar la biblioteca:', err)
set({ isLoading: false })
}
},
createGroup: async (name, userId) => {
const now = Date.now()
const group: ProcessGroup = { id: uuidv4(), name, createdAt: now, updatedAt: now }
await supabaseGroupRepo.save(group, userId)
set((state) => ({ groups: [...state.groups, group].sort((a, b) => a.name.localeCompare(b.name)) }))
return group
},
deleteGroup: async (id) => {
await supabaseGroupRepo.delete(id)
set((state) => ({
groups: state.groups.filter((g) => g.id !== id),
processes: state.processes.map((p) => p.groupId === id ? { ...p, groupId: null } : p),
}))
},
deleteProcess: async (id) => {
await supabaseProcessRepo.delete(id)
set((state) => ({ processes: state.processes.filter((p) => p.id !== id) }))
},
assignProcessToGroup: async (processId, groupId, userId) => {
const process = get().processes.find((p) => p.id === processId)
if (!process) return
const updated = { ...process, groupId, updatedAt: Date.now() }
await supabaseProcessRepo.save(updated, userId)
set((state) => ({
processes: state.processes.map((p) => p.id === processId ? updated : p),
}))
},
getProcessesByGroup: (groupId) => {
const processes = get().processes
return groupId === null
? processes.filter((p) => p.groupId == null)
: processes.filter((p) => p.groupId === groupId)
},
getLatestSimulation: (processId) => {
return simulationRepo.getLatestByProcess(processId)
},
updateSettings: async (updates) => {
await supabaseSettingsRepo.update(updates)
set((state) => ({ settings: { ...state.settings, ...updates } }))
},
getAllTags: () => {
const tagSet = new Set<string>()
get().processes.forEach((p) => p.tags.forEach((t) => tagSet.add(t)))
return [...tagSet].sort()
},
}))