mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-06-13 08:15:21 +02:00
* feat: add backend foundations * feat: add text chat UI * chore: simplify the reload behaviour * fix: fix upgrade banner to be triggered after package upload * feat: simplify TesterPanel design * chore: fix formatting and generate client * chore: fix tracing for text chat mode * fix: fix revert and edit CTA * refactor: refactor TesterPanel into smaller components * feat: enable runtime transition of nodes * fix: fix review comments
106 lines
3.3 KiB
TypeScript
106 lines
3.3 KiB
TypeScript
'use client';
|
|
|
|
import { createContext, useContext, useEffect, useState } from 'react';
|
|
|
|
export type TooltipKey = 'web_call' | 'customize_workflow';
|
|
export type OnboardingActionKey = 'web_call_started';
|
|
|
|
interface OnboardingState {
|
|
seenTooltips: TooltipKey[];
|
|
completedActions: OnboardingActionKey[];
|
|
}
|
|
|
|
interface OnboardingContextType {
|
|
hasSeenTooltip: (key: TooltipKey) => boolean;
|
|
markTooltipSeen: (key: TooltipKey) => void;
|
|
hasCompletedAction: (key: OnboardingActionKey) => boolean;
|
|
markActionCompleted: (key: OnboardingActionKey) => void;
|
|
resetOnboarding: () => void;
|
|
}
|
|
|
|
const ONBOARDING_STORAGE_KEY = 'dograh_onboarding_state';
|
|
|
|
const defaultState: OnboardingState = {
|
|
seenTooltips: [],
|
|
completedActions: [],
|
|
};
|
|
|
|
const OnboardingContext = createContext<OnboardingContextType | undefined>(undefined);
|
|
|
|
export const OnboardingProvider = ({ children }: { children: React.ReactNode }) => {
|
|
const [onboardingState, setOnboardingState] = useState<OnboardingState>(() => {
|
|
// Initialize state from localStorage on first render
|
|
if (typeof window !== 'undefined') {
|
|
const savedState = localStorage.getItem(ONBOARDING_STORAGE_KEY);
|
|
if (savedState) {
|
|
try {
|
|
const parsed = JSON.parse(savedState);
|
|
return { ...defaultState, ...parsed };
|
|
} catch (error) {
|
|
console.error('Failed to parse onboarding state:', error);
|
|
}
|
|
}
|
|
}
|
|
return defaultState;
|
|
});
|
|
|
|
// Save state to localStorage whenever it changes
|
|
useEffect(() => {
|
|
if (typeof window !== 'undefined') {
|
|
localStorage.setItem(ONBOARDING_STORAGE_KEY, JSON.stringify(onboardingState));
|
|
}
|
|
}, [onboardingState]);
|
|
|
|
const hasSeenTooltip = (key: TooltipKey): boolean => {
|
|
return onboardingState.seenTooltips.includes(key);
|
|
};
|
|
|
|
const markTooltipSeen = (key: TooltipKey) => {
|
|
setOnboardingState(prev => ({
|
|
...prev,
|
|
seenTooltips: prev.seenTooltips.includes(key)
|
|
? prev.seenTooltips
|
|
: [...prev.seenTooltips, key]
|
|
}));
|
|
};
|
|
|
|
const hasCompletedAction = (key: OnboardingActionKey): boolean => {
|
|
return onboardingState.completedActions.includes(key);
|
|
};
|
|
|
|
const markActionCompleted = (key: OnboardingActionKey) => {
|
|
setOnboardingState(prev => ({
|
|
...prev,
|
|
completedActions: prev.completedActions.includes(key)
|
|
? prev.completedActions
|
|
: [...prev.completedActions, key]
|
|
}));
|
|
};
|
|
|
|
const resetOnboarding = () => {
|
|
setOnboardingState(defaultState);
|
|
localStorage.removeItem(ONBOARDING_STORAGE_KEY);
|
|
};
|
|
|
|
return (
|
|
<OnboardingContext.Provider
|
|
value={{
|
|
hasSeenTooltip,
|
|
markTooltipSeen,
|
|
hasCompletedAction,
|
|
markActionCompleted,
|
|
resetOnboarding
|
|
}}
|
|
>
|
|
{children}
|
|
</OnboardingContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const useOnboarding = () => {
|
|
const context = useContext(OnboardingContext);
|
|
if (!context) {
|
|
throw new Error('useOnboarding must be used within an OnboardingProvider');
|
|
}
|
|
return context;
|
|
};
|