sync: Auto-sync from Mikes-MacBook-Air.local at 2026-03-09 08:14:13

Synced files:
- Session logs updated
- Latest context and credentials
- Command/directive updates

Machine: Mikes-MacBook-Air.local
Timestamp: 2026-03-09 08:14:13

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 08:14:13 -07:00
parent f81872784b
commit a1a19f8c00
59 changed files with 14435 additions and 1 deletions

View File

@@ -0,0 +1,160 @@
import { useState, useCallback, useMemo } from 'react';
import type { WizardStep } from '@/types/quote';
/**
* Wizard steps configuration for the 7-step MSP Quote Wizard
*/
const WIZARD_STEPS: Omit<WizardStep, 'isComplete' | 'isActive'>[] = [
{
id: 'company',
title: 'Company Profile',
description: 'Tell us about your business',
},
{
id: 'gps',
title: 'GPS Monitoring',
description: 'Select your monitoring tier',
},
{
id: 'support',
title: 'Support Plan',
description: 'Choose your support level',
},
{
id: 'voip',
title: 'VoIP Phone System',
description: 'Business phone options',
},
{
id: 'web-email',
title: 'Web & Email',
description: 'Hosting and email services',
},
{
id: 'summary',
title: 'Review Quote',
description: 'Review your selections',
},
{
id: 'contact',
title: 'Get Your Quote',
description: 'Submit your information',
},
];
export interface UseWizardReturn {
currentStep: number;
steps: WizardStep[];
totalSteps: number;
isFirstStep: boolean;
isLastStep: boolean;
goToStep: (step: number) => void;
nextStep: () => void;
prevStep: () => void;
markStepComplete: (stepIndex: number) => void;
markStepIncomplete: (stepIndex: number) => void;
resetWizard: () => void;
progress: number;
canProceed: boolean;
setCanProceed: (canProceed: boolean) => void;
currentStepId: string;
getStepByIndex: (index: number) => WizardStep | undefined;
}
export function useWizard(): UseWizardReturn {
const [currentStep, setCurrentStep] = useState(0);
const [completedSteps, setCompletedSteps] = useState<Set<number>>(new Set());
const [canProceed, setCanProceed] = useState(true);
const totalSteps = WIZARD_STEPS.length;
const isFirstStep = currentStep === 0;
const isLastStep = currentStep === totalSteps - 1;
const steps: WizardStep[] = useMemo(() => {
return WIZARD_STEPS.map((step, index) => ({
...step,
isComplete: completedSteps.has(index),
isActive: index === currentStep,
}));
}, [currentStep, completedSteps]);
const currentStepId = useMemo(() => {
return WIZARD_STEPS[currentStep]?.id || '';
}, [currentStep]);
const progress = useMemo(() => {
// Progress based on current step position (0 to 100)
return Math.round((currentStep / (totalSteps - 1)) * 100);
}, [currentStep, totalSteps]);
const goToStep = useCallback(
(step: number) => {
if (step >= 0 && step < totalSteps) {
// Allow going back to any previous step
// Only allow going forward to completed steps or the next step
if (step <= currentStep || completedSteps.has(step - 1) || step === currentStep + 1) {
setCurrentStep(step);
}
}
},
[totalSteps, currentStep, completedSteps]
);
const nextStep = useCallback(() => {
if (!isLastStep && canProceed) {
// Mark current step as complete when moving forward
setCompletedSteps((prev) => new Set(prev).add(currentStep));
setCurrentStep((prev) => prev + 1);
}
}, [currentStep, isLastStep, canProceed]);
const prevStep = useCallback(() => {
if (!isFirstStep) {
setCurrentStep((prev) => prev - 1);
}
}, [isFirstStep]);
const markStepComplete = useCallback((stepIndex: number) => {
setCompletedSteps((prev) => new Set(prev).add(stepIndex));
}, []);
const markStepIncomplete = useCallback((stepIndex: number) => {
setCompletedSteps((prev) => {
const newSet = new Set(prev);
newSet.delete(stepIndex);
return newSet;
});
}, []);
const resetWizard = useCallback(() => {
setCurrentStep(0);
setCompletedSteps(new Set());
setCanProceed(true);
}, []);
const getStepByIndex = useCallback(
(index: number): WizardStep | undefined => {
return steps[index];
},
[steps]
);
return {
currentStep,
steps,
totalSteps,
isFirstStep,
isLastStep,
goToStep,
nextStep,
prevStep,
markStepComplete,
markStepIncomplete,
resetWizard,
progress,
canProceed,
setCanProceed,
currentStepId,
getStepByIndex,
};
}