10 changed files with 238 additions and 31 deletions
@ -0,0 +1,35 @@ |
|||||||
|
import { Navigate } from 'react-router-dom'; |
||||||
|
import { isAppEnabled } from '../utils/appFilter'; |
||||||
|
|
||||||
|
interface AppRouteGuardProps { |
||||||
|
appId: string; |
||||||
|
children: React.ReactNode; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Guards app routes based on magic code settings |
||||||
|
* - Videos app: falls back to disabled if no magic code |
||||||
|
* - Other apps: always enabled unless magic code disables them |
||||||
|
*/ |
||||||
|
export function AppRouteGuard({ appId, children }: AppRouteGuardProps) { |
||||||
|
if (!isAppEnabled(appId)) { |
||||||
|
return ( |
||||||
|
<div className="min-h-[calc(100vh-60px)] flex items-center justify-center bg-background"> |
||||||
|
<div className="text-center p-6"> |
||||||
|
<h1 className="text-2xl font-bold text-foreground mb-2">App Not Available</h1> |
||||||
|
<p className="text-muted-foreground mb-4"> |
||||||
|
This app is not enabled for your current settings. |
||||||
|
</p> |
||||||
|
<a |
||||||
|
href="/" |
||||||
|
className="inline-block px-4 py-2 bg-primary text-primary-foreground rounded-full font-semibold text-sm hover:bg-primary/90 transition-all" |
||||||
|
> |
||||||
|
Go Home |
||||||
|
</a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
return <>{children}</>; |
||||||
|
} |
||||||
@ -0,0 +1,35 @@ |
|||||||
|
import { APPS, App } from '../config/apps'; |
||||||
|
import { getMagicCodeSettings } from '../services/magicCodeService'; |
||||||
|
|
||||||
|
/** |
||||||
|
* Get enabled apps based on magic code settings |
||||||
|
* - If magic code is applied: use enabledApps from magic code (empty array = all apps enabled) |
||||||
|
* - If no magic code: videos app falls back to disabled, other apps are enabled |
||||||
|
*/ |
||||||
|
export function getEnabledApps(): App[] { |
||||||
|
const magicCodeSettings = getMagicCodeSettings(); |
||||||
|
|
||||||
|
// If magic code is applied, use its enabled apps
|
||||||
|
if (magicCodeSettings?.enabledApps !== null && magicCodeSettings?.enabledApps !== undefined) { |
||||||
|
const enabledAppIds = magicCodeSettings.enabledApps; |
||||||
|
|
||||||
|
// Empty array means all apps enabled (including videos)
|
||||||
|
if (enabledAppIds.length === 0) { |
||||||
|
return APPS.filter(app => !app.disabled); |
||||||
|
} |
||||||
|
|
||||||
|
// Return only apps that are in the enabled list
|
||||||
|
return APPS.filter(app => enabledAppIds.includes(app.id) && !app.disabled); |
||||||
|
} |
||||||
|
|
||||||
|
// No magic code: videos falls back to disabled, other apps are enabled
|
||||||
|
return APPS.filter(app => app.id !== 'videos' && !app.disabled); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Check if a specific app is enabled |
||||||
|
*/ |
||||||
|
export function isAppEnabled(appId: string): boolean { |
||||||
|
const enabledApps = getEnabledApps(); |
||||||
|
return enabledApps.some(app => app.id === appId); |
||||||
|
} |
||||||
Loading…
Reference in new issue