Skip to content

Commit 79a933b

Browse files
committed
feat: read feature flags, store in context
1 parent ecb58fe commit 79a933b

File tree

2 files changed

+67
-6
lines changed

2 files changed

+67
-6
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { ReactNode, createContext, useContext, useEffect, useReducer, useMemo } from 'react';
2+
import { useFeatureFlagEnabled } from 'posthog-js/react';
3+
import { Loader } from '@/components/ui/loader';
4+
5+
type PostHogFeatureFlagStatus = 'idle' | 'pending' | 'success';
6+
7+
interface PostHogFeatureFlagState {
8+
status: PostHogFeatureFlagStatus;
9+
onboarding: {
10+
enabled: boolean;
11+
};
12+
}
13+
14+
type PostHogFeatureFlagAction = { type: 'LOADING' } | { type: 'LOADED'; onboardingEnabled: boolean };
15+
16+
function postHogFeatureFlagReducer(
17+
_state: PostHogFeatureFlagState,
18+
action: PostHogFeatureFlagAction,
19+
): PostHogFeatureFlagState {
20+
switch (action.type) {
21+
case 'LOADING':
22+
return { status: 'pending', onboarding: { enabled: false } };
23+
case 'LOADED':
24+
return { status: 'success', onboarding: { enabled: action.onboardingEnabled } };
25+
}
26+
}
27+
28+
const initialState: PostHogFeatureFlagState = {
29+
status: 'idle',
30+
onboarding: { enabled: false },
31+
};
32+
33+
const PostHogFeatureFlagContext = createContext<PostHogFeatureFlagState>(initialState);
34+
35+
export const usePostHogFeatureFlags = () => useContext(PostHogFeatureFlagContext);
36+
37+
export const PostHogFeatureFlagProvider = ({ children }: { children: ReactNode }) => {
38+
const onboardingFlag = useFeatureFlagEnabled('cosmo-onboarding-v1');
39+
const [state, dispatch] = useReducer(postHogFeatureFlagReducer, initialState);
40+
41+
useEffect(() => {
42+
if (onboardingFlag === undefined) {
43+
dispatch({ type: 'LOADING' });
44+
} else {
45+
dispatch({ type: 'LOADED', onboardingEnabled: onboardingFlag });
46+
}
47+
}, [onboardingFlag]);
48+
49+
if (state.status !== 'success') {
50+
return (
51+
<div className="fixed inset-0 flex items-center justify-center bg-background">
52+
<Loader />
53+
</div>
54+
);
55+
}
56+
57+
return <PostHogFeatureFlagContext.Provider value={state}>{children}</PostHogFeatureFlagContext.Provider>;
58+
};

studio/src/pages/_app.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { TooltipProvider } from '@/components/ui/tooltip';
88
import { AppPropsWithLayout } from '@/lib/page';
99
import '@graphiql/plugin-explorer/dist/style.css';
1010
import { QueryClient, QueryClientProvider, focusManager } from '@tanstack/react-query';
11+
import { PostHogFeatureFlagProvider } from '@/components/posthog-feature-flag-provider';
1112
import 'graphiql/graphiql.css';
1213
import App, { AppContext, AppInitialProps } from 'next/app';
1314
import 'react-date-range/dist/styles.css'; // main css file
@@ -71,12 +72,14 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
7172
<PostHogProvider client={posthog}>
7273
<ThemeProvider attribute="class" defaultTheme="light" enableSystem>
7374
<QueryClientProvider client={queryClient}>
74-
<AppProvider>
75-
<TooltipProvider>
76-
<Toaster />
77-
{getLayout(<Component {...pageProps} />)}
78-
</TooltipProvider>
79-
</AppProvider>
75+
<PostHogFeatureFlagProvider>
76+
<AppProvider>
77+
<TooltipProvider>
78+
<Toaster />
79+
{getLayout(<Component {...pageProps} />)}
80+
</TooltipProvider>
81+
</AppProvider>
82+
</PostHogFeatureFlagProvider>
8083
</QueryClientProvider>
8184
</ThemeProvider>
8285
</PostHogProvider>

0 commit comments

Comments
 (0)