feature flags
This commit is contained in:
@@ -152,7 +152,6 @@ export function DebugModeToggle({ show }: DebugModeToggleProps) {
|
||||
timestamp: new Date().toISOString(),
|
||||
environment: {
|
||||
mode: process.env.NODE_ENV,
|
||||
appMode: process.env.NEXT_PUBLIC_GRIDPILOT_MODE,
|
||||
version: process.env.NEXT_PUBLIC_APP_VERSION,
|
||||
},
|
||||
browser: {
|
||||
|
||||
@@ -53,7 +53,6 @@ interface ErrorStats {
|
||||
};
|
||||
environment: {
|
||||
mode: string;
|
||||
appMode: string;
|
||||
version?: string;
|
||||
buildTime?: string;
|
||||
};
|
||||
@@ -141,7 +140,6 @@ export function ErrorAnalyticsDashboard({
|
||||
},
|
||||
environment: {
|
||||
mode: process.env.NODE_ENV || 'unknown',
|
||||
appMode: process.env.NEXT_PUBLIC_GRIDPILOT_MODE || 'pre-launch',
|
||||
version: process.env.NEXT_PUBLIC_APP_VERSION,
|
||||
buildTime: process.env.NEXT_PUBLIC_BUILD_TIME,
|
||||
},
|
||||
@@ -432,10 +430,6 @@ export function ErrorAnalyticsDashboard({
|
||||
stats.environment.mode === 'development' ? 'text-green-400' : 'text-yellow-400'
|
||||
}`}>{stats.environment.mode}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-500">App Mode</span>
|
||||
<span className="text-blue-400 font-mono">{stats.environment.appMode}</span>
|
||||
</div>
|
||||
{stats.environment.version && (
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-500">Version</span>
|
||||
|
||||
@@ -1,47 +1,57 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect, ReactNode } from 'react';
|
||||
import { FeatureFlagService } from '@/lib/feature/FeatureFlagService';
|
||||
|
||||
/**
|
||||
* ModeGuard - Conditional rendering component based on application mode
|
||||
* ModeGuard - Conditional rendering component based on feature availability
|
||||
*
|
||||
* Usage:
|
||||
* <ModeGuard mode="pre-launch">
|
||||
* <PreLaunchContent />
|
||||
* <ModeGuard feature="platform.dashboard">
|
||||
* <DashboardContent />
|
||||
* </ModeGuard>
|
||||
*
|
||||
* <ModeGuard mode="alpha">
|
||||
* <FullPlatformContent />
|
||||
* <ModeGuard feature="alpha_features">
|
||||
* <AlphaContent />
|
||||
* </ModeGuard>
|
||||
*/
|
||||
|
||||
export type GuardMode = 'pre-launch' | 'alpha';
|
||||
|
||||
interface ModeGuardProps {
|
||||
mode: GuardMode;
|
||||
feature: string;
|
||||
children: ReactNode;
|
||||
fallback?: ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Client-side mode guard component
|
||||
* Note: For initial page load, rely on middleware for route protection
|
||||
* This component is for conditional UI rendering within accessible pages
|
||||
* Client-side feature guard component
|
||||
* Uses API-driven feature flags instead of environment mode
|
||||
*/
|
||||
export function ModeGuard({ mode, children, fallback = null }: ModeGuardProps) {
|
||||
export function ModeGuard({ feature, children, fallback = null }: ModeGuardProps) {
|
||||
const [isMounted, setIsMounted] = useState(false);
|
||||
const [currentMode, setCurrentMode] = useState<GuardMode>('pre-launch');
|
||||
const [isEnabled, setIsEnabled] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setIsMounted(true);
|
||||
setCurrentMode(getClientMode());
|
||||
}, []);
|
||||
|
||||
// Check feature availability using API-driven service
|
||||
const checkFeature = async () => {
|
||||
try {
|
||||
const service = await FeatureFlagService.fromAPI();
|
||||
setIsEnabled(service.isEnabled(feature));
|
||||
} catch (error) {
|
||||
console.error('Error checking feature:', error);
|
||||
setIsEnabled(false);
|
||||
}
|
||||
};
|
||||
|
||||
checkFeature();
|
||||
}, [feature]);
|
||||
|
||||
if (!isMounted) {
|
||||
return <>{fallback}</>;
|
||||
}
|
||||
|
||||
if (currentMode !== mode) {
|
||||
if (!isEnabled) {
|
||||
return <>{fallback}</>;
|
||||
}
|
||||
|
||||
@@ -49,40 +59,57 @@ export function ModeGuard({ mode, children, fallback = null }: ModeGuardProps) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mode on client side from injected environment variable
|
||||
* Falls back to 'pre-launch' if not available
|
||||
* Hook to check feature availability in client components
|
||||
*/
|
||||
function getClientMode(): GuardMode {
|
||||
if (typeof window === 'undefined') {
|
||||
return 'pre-launch';
|
||||
}
|
||||
|
||||
const mode = process.env.NEXT_PUBLIC_GRIDPILOT_MODE;
|
||||
|
||||
if (mode === 'alpha') {
|
||||
return 'alpha';
|
||||
}
|
||||
|
||||
return 'pre-launch';
|
||||
export function useFeature(feature: string): boolean {
|
||||
const [isEnabled, setIsEnabled] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const checkFeature = async () => {
|
||||
try {
|
||||
const service = await FeatureFlagService.fromAPI();
|
||||
setIsEnabled(service.isEnabled(feature));
|
||||
} catch (error) {
|
||||
console.error('Error checking feature:', error);
|
||||
setIsEnabled(false);
|
||||
}
|
||||
};
|
||||
|
||||
checkFeature();
|
||||
}, [feature]);
|
||||
|
||||
return isEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to get current mode in client components
|
||||
* Hook to check multiple features
|
||||
*/
|
||||
export function useAppMode(): GuardMode {
|
||||
return getClientMode();
|
||||
}
|
||||
export function useFeatures(features: string[]): Record<string, boolean> {
|
||||
const [featureStates, setFeatureStates] = useState<Record<string, boolean>>({});
|
||||
|
||||
/**
|
||||
* Hook to check if in pre-launch mode
|
||||
*/
|
||||
export function useIsPreLaunch(): boolean {
|
||||
return getClientMode() === 'pre-launch';
|
||||
}
|
||||
useEffect(() => {
|
||||
const checkFeatures = async () => {
|
||||
try {
|
||||
const service = await FeatureFlagService.fromAPI();
|
||||
const states: Record<string, boolean> = {};
|
||||
|
||||
features.forEach(feature => {
|
||||
states[feature] = service.isEnabled(feature);
|
||||
});
|
||||
|
||||
setFeatureStates(states);
|
||||
} catch (error) {
|
||||
console.error('Error checking features:', error);
|
||||
const states: Record<string, boolean> = {};
|
||||
features.forEach(feature => {
|
||||
states[feature] = false;
|
||||
});
|
||||
setFeatureStates(states);
|
||||
}
|
||||
};
|
||||
|
||||
checkFeatures();
|
||||
}, [features]);
|
||||
|
||||
/**
|
||||
* Hook to check if in alpha mode
|
||||
*/
|
||||
export function useIsAlpha(): boolean {
|
||||
return getClientMode() === 'alpha';
|
||||
return featureStates;
|
||||
}
|
||||
Reference in New Issue
Block a user