← 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() }),
}))