/** * Main compliance composable */ import { computed, type ComputedRef } from 'vue' import { useComplianceStore, type ComplianceStore } from '../plugin' import type { SDKState, SDKAction, SDKStep } from '@breakpilot/compliance-sdk-types' import { SDK_STEPS } from '@breakpilot/compliance-sdk-types' export interface UseComplianceReturn { // Store state: SDKState dispatch: (action: SDKAction) => void store: ComplianceStore // Status isReady: ComputedRef error: ComputedRef // Progress completionPercentage: ComputedRef phase1Completion: ComputedRef phase2Completion: ComputedRef completedSteps: ComputedRef // Navigation currentStep: ComputedRef nextStep: ComputedRef previousStep: ComputedRef canGoNext: ComputedRef canGoPrevious: ComputedRef goToStep: (stepId: string) => void goNext: () => void goPrevious: () => void // Actions completeStep: (stepId: string) => void resetProgress: () => void saveState: () => Promise } export function useCompliance(): UseComplianceReturn { const store = useComplianceStore() const { state, dispatch, client } = store // Status const isReady = computed(() => store.isReady) const error = computed(() => store.error) // Progress calculations const completedSteps = computed(() => state.completedSteps) const completionPercentage = computed(() => { return Math.round((state.completedSteps.length / SDK_STEPS.length) * 100) }) const phase1Completion = computed(() => { const phase1Steps = SDK_STEPS.filter(s => s.phase === 1) const completed = phase1Steps.filter(s => state.completedSteps.includes(s.id)) return Math.round((completed.length / phase1Steps.length) * 100) }) const phase2Completion = computed(() => { const phase2Steps = SDK_STEPS.filter(s => s.phase === 2) const completed = phase2Steps.filter(s => state.completedSteps.includes(s.id)) return Math.round((completed.length / phase2Steps.length) * 100) }) // Navigation const currentStep = computed(() => SDK_STEPS.find(s => s.id === state.currentStep)) const currentIndex = computed(() => SDK_STEPS.findIndex(s => s.id === state.currentStep)) const nextStep = computed(() => { const idx = currentIndex.value return idx < SDK_STEPS.length - 1 ? SDK_STEPS[idx + 1] : undefined }) const previousStep = computed(() => { const idx = currentIndex.value return idx > 0 ? SDK_STEPS[idx - 1] : undefined }) const canGoNext = computed(() => currentIndex.value < SDK_STEPS.length - 1) const canGoPrevious = computed(() => currentIndex.value > 0) const goToStep = (stepId: string): void => { dispatch({ type: 'SET_CURRENT_STEP', payload: stepId }) } const goNext = (): void => { if (nextStep.value) { goToStep(nextStep.value.id) } } const goPrevious = (): void => { if (previousStep.value) { goToStep(previousStep.value.id) } } // Actions const completeStep = (stepId: string): void => { if (!state.completedSteps.includes(stepId)) { dispatch({ type: 'COMPLETE_STEP', payload: stepId }) } } const resetProgress = (): void => { dispatch({ type: 'RESET_PROGRESS' }) } const saveState = async (): Promise => { await client.saveState(state) } return { state, dispatch, store, isReady, error, completionPercentage, phase1Completion, phase2Completion, completedSteps, currentStep, nextStep, previousStep, canGoNext, canGoPrevious, goToStep, goNext, goPrevious, completeStep, resetProgress, saveState, } }