← back to ClawCoder
src/lib/store.ts
126 lines
'use client'
import { create } from 'zustand'
import type { Profile } from '@/lib/profiles/types'
import type { AnalysisResult, Suggestion } from '@/lib/analyzer/types'
interface MassUpdateFile {
id: string
name: string
content: string
type: 'claude_md' | 'rule' | 'skill' | 'hook'
analysis: AnalysisResult | null
lastAnalyzed: string | null
}
interface ClawCoderStore {
// Profile selection
selectedProfile: Profile | null
setProfile: (p: Profile) => void
// Onboarding answers
onboardingAnswers: Record<string, string>
setAnswer: (key: string, value: string) => void
// Step navigation
currentStep: number
setStep: (n: number) => void
// Analysis
analysisResult: AnalysisResult | null
setAnalysis: (a: AnalysisResult | null) => void
// Suggestions
selectedSuggestions: Set<string>
toggleSuggestion: (id: string) => void
selectAllSuggestions: (suggestions: Suggestion[]) => void
clearSuggestions: () => void
// Generated content
generatedContent: string
setGeneratedContent: (c: string) => void
// Loading state
isLoading: boolean
setLoading: (b: boolean) => void
// Mass update files
massFiles: MassUpdateFile[]
addMassFiles: (files: MassUpdateFile[]) => void
removeMassFile: (id: string) => void
updateMassFile: (id: string, updates: Partial<MassUpdateFile>) => void
clearMassFiles: () => void
selectedMassFileIds: Set<string>
toggleMassFileSelection: (id: string) => void
selectAllMassFiles: () => void
clearMassFileSelection: () => void
}
export const useStore = create<ClawCoderStore>((set) => ({
selectedProfile: null,
setProfile: (p) => set({ selectedProfile: p }),
onboardingAnswers: {},
setAnswer: (key, value) =>
set((s) => ({
onboardingAnswers: { ...s.onboardingAnswers, [key]: value },
})),
currentStep: 0,
setStep: (n) => set({ currentStep: n }),
analysisResult: null,
setAnalysis: (a) => set({ analysisResult: a }),
selectedSuggestions: new Set(),
toggleSuggestion: (id) =>
set((s) => {
const next = new Set(s.selectedSuggestions)
if (next.has(id)) {
next.delete(id)
} else {
next.add(id)
}
return { selectedSuggestions: next }
}),
selectAllSuggestions: (sugs) =>
set({ selectedSuggestions: new Set(sugs.map((s) => s.id)) }),
clearSuggestions: () => set({ selectedSuggestions: new Set() }),
generatedContent: '',
setGeneratedContent: (c) => set({ generatedContent: c }),
isLoading: false,
setLoading: (b) => set({ isLoading: b }),
massFiles: [],
addMassFiles: (files) =>
set((s) => ({ massFiles: [...s.massFiles, ...files] })),
removeMassFile: (id) =>
set((s) => ({ massFiles: s.massFiles.filter((f) => f.id !== id) })),
updateMassFile: (id, updates) =>
set((s) => ({
massFiles: s.massFiles.map((f) =>
f.id === id ? { ...f, ...updates } : f
),
})),
clearMassFiles: () => set({ massFiles: [], selectedMassFileIds: new Set() }),
selectedMassFileIds: new Set(),
toggleMassFileSelection: (id) =>
set((s) => {
const next = new Set(s.selectedMassFileIds)
if (next.has(id)) {
next.delete(id)
} else {
next.add(id)
}
return { selectedMassFileIds: next }
}),
selectAllMassFiles: () =>
set((s) => ({
selectedMassFileIds: new Set(s.massFiles.map((f) => f.id)),
})),
clearMassFileSelection: () => set({ selectedMassFileIds: new Set() }),
}))