diff --git a/frontend/src/app/api/edge-flags/route.ts b/frontend/src/app/api/edge-flags/route.ts index 1f27ebee..f59a2507 100644 --- a/frontend/src/app/api/edge-flags/route.ts +++ b/frontend/src/app/api/edge-flags/route.ts @@ -3,7 +3,11 @@ import { maintenanceNoticeFlag } from '@/lib/edge-flags'; export const runtime = 'edge'; export async function GET() { - const maintenanceNotice = await maintenanceNoticeFlag(); - - return Response.json(maintenanceNotice); + try { + const maintenanceNotice = await maintenanceNoticeFlag(); + return Response.json(maintenanceNotice); + } catch (error) { + console.error('[API] Error in edge flags route:', error); + return Response.json({ enabled: false }, { status: 500 }); + } } \ No newline at end of file diff --git a/frontend/src/components/dashboard/layout-content.tsx b/frontend/src/components/dashboard/layout-content.tsx index 0e237633..186ef736 100644 --- a/frontend/src/components/dashboard/layout-content.tsx +++ b/frontend/src/components/dashboard/layout-content.tsx @@ -1,10 +1,8 @@ 'use client'; -import { useEffect, useState } from 'react'; +import { useEffect } from 'react'; import { SidebarLeft, FloatingMobileMenuButton } from '@/components/sidebar/sidebar-left'; import { SidebarInset, SidebarProvider } from '@/components/ui/sidebar'; -// import { PricingAlert } from "@/components/billing/pricing-alert" -import { MaintenanceAlert } from '@/components/maintenance-alert'; import { useAccounts } from '@/hooks/use-accounts'; import { useAuth } from '@/components/AuthProvider'; import { useMaintenanceNoticeQuery } from '@/hooks/react-query/edge-flags'; @@ -14,13 +12,12 @@ import { useApiHealth } from '@/hooks/react-query'; import { MaintenancePage } from '@/components/maintenance/maintenance-page'; import { DeleteOperationProvider } from '@/contexts/DeleteOperationContext'; import { StatusOverlay } from '@/components/ui/status-overlay'; -import { MaintenanceNotice } from './maintenance-notice'; -import { MaintenanceBanner } from './maintenance-banner'; import { useProjects, useThreads } from '@/hooks/react-query/sidebar/use-sidebar'; import { useIsMobile } from '@/hooks/use-mobile'; import { useAgents } from '@/hooks/react-query/agents/use-agents'; import { SubscriptionProvider } from '@/contexts/SubscriptionContext'; +import { MaintenanceAlert } from '../maintenance-alert'; interface DashboardLayoutContentProps { children: React.ReactNode; @@ -29,21 +26,18 @@ interface DashboardLayoutContentProps { export default function DashboardLayoutContent({ children, }: DashboardLayoutContentProps) { - // const [showPricingAlert, setShowPricingAlert] = useState(false) - const [showMaintenanceAlert, setShowMaintenanceAlert] = useState(false); const { data: accounts } = useAccounts(); const personalAccount = accounts?.find((account) => account.personal_account); const { user, isLoading } = useAuth(); const router = useRouter(); const isMobile = useIsMobile(); - const { data: maintenanceNotice } = useMaintenanceNoticeQuery(); + const { data: maintenanceNotice, isLoading: maintenanceLoading } = useMaintenanceNoticeQuery(); const { data: healthData, isLoading: isCheckingHealth, error: healthError, } = useApiHealth(); - // Prefetch sidebar data for better mobile experience const { data: projects } = useProjects(); const { data: threads } = useThreads(); const { data: agentsResponse } = useAgents({ @@ -53,11 +47,10 @@ export default function DashboardLayoutContent({ }); useEffect(() => { - // setShowPricingAlert(false) if (maintenanceNotice?.enabled) { - setShowMaintenanceAlert(true); + // setShowMaintenanceAlert(true); // This line was removed } else { - setShowMaintenanceAlert(false); + // setShowMaintenanceAlert(false); // This line was removed } }, [maintenanceNotice]); @@ -86,8 +79,8 @@ export default function DashboardLayoutContent({ let mantenanceBanner: React.ReactNode | null = null; - // Show loading state while checking auth or health - if (isLoading || isCheckingHealth) { + // Show loading state while checking auth, health, or maintenance status + if (isLoading || isCheckingHealth || maintenanceLoading) { return (
@@ -100,6 +93,11 @@ export default function DashboardLayoutContent({ return null; } + // Show maintenance page if maintenance mode is enabled + if (maintenanceNotice?.enabled) { + return {}} closeable={false} />; + } + // Show maintenance page if API is not healthy (but not during initial loading) if (!isCheckingHealth && !isApiHealthy) { return ; @@ -122,11 +120,11 @@ export default function DashboardLayoutContent({ accountId={personalAccount?.account_id} /> */} - + /> */} {/* Status overlay for deletion operations */} diff --git a/frontend/src/components/maintenance-alert.tsx b/frontend/src/components/maintenance-alert.tsx index 73f17a75..885ba9f2 100644 --- a/frontend/src/components/maintenance-alert.tsx +++ b/frontend/src/components/maintenance-alert.tsx @@ -37,11 +37,6 @@ export function MaintenanceAlert({ animate={{ opacity: 1, scale: 1 }} transition={{ type: 'spring', damping: 30, stiffness: 300 }} > - {/* Background pattern */} -
-
-
- {closeable && ( )} - -
-
+
+
@@ -74,7 +68,7 @@ export function MaintenanceAlert({ transition={{ delay: 0.2 }} > - High Demand Notice + Maintenance Notice @@ -84,28 +78,11 @@ export function MaintenanceAlert({ transition={{ delay: 0.3 }} > - Due to exceptionally high demand, our service is currently - experiencing slower response times. We recommend returning - tomorrow when our systems will be operating at normal capacity. - - Thank you for your understanding. We will notify you via email - once the service is fully operational again. - + We are currently performing maintenance on our system. Please + check back later. - - - - - Explore Self-Hosted Version - - diff --git a/frontend/src/hooks/react-query/edge-flags/index.ts b/frontend/src/hooks/react-query/edge-flags/index.ts index 9a7ab0d5..3877dcfd 100644 --- a/frontend/src/hooks/react-query/edge-flags/index.ts +++ b/frontend/src/hooks/react-query/edge-flags/index.ts @@ -3,7 +3,7 @@ import { createQueryHook, createQueryKeys } from '@/hooks/use-query'; import { IMaintenanceNotice } from '@/lib/edge-flags'; -const maintenanceNoticeKeysBase = ['maintenance-notice'] as const; +const maintenanceNoticeKeysBase = ['maintenanceNotice'] as const; export const maintenanceNoticeKeys = createQueryKeys({ all: maintenanceNoticeKeysBase, @@ -13,7 +13,8 @@ export const useMaintenanceNoticeQuery = createQueryHook( maintenanceNoticeKeys.all, async (): Promise => { const response = await fetch('/api/edge-flags'); - return response.json(); + const data = await response.json(); + return data; }, { staleTime: 30 * 1000, diff --git a/frontend/src/lib/edge-flags.ts b/frontend/src/lib/edge-flags.ts index 7e40b0f7..cac7c1f7 100644 --- a/frontend/src/lib/edge-flags.ts +++ b/frontend/src/lib/edge-flags.ts @@ -27,16 +27,29 @@ export const maintenanceNoticeFlag = flag({ 'maintenance-notice_enabled', ]); - if (!flags['maintenance-notice_enabled']) { + if (!flags || Object.keys(flags).length === 0) { return { enabled: false } as const; } - const startTime = new Date(flags['maintenance-notice_start-time']); - const endTime = new Date(flags['maintenance-notice_end-time']); + const enabled = flags['maintenance-notice_enabled']; + + if (!enabled) { + return { enabled: false } as const; + } + + const startTimeRaw = flags['maintenance-notice_start-time']; + const endTimeRaw = flags['maintenance-notice_end-time']; + + if (!startTimeRaw || !endTimeRaw) { + return { enabled: false } as const; + } + + const startTime = new Date(startTimeRaw); + const endTime = new Date(endTimeRaw); if (isNaN(startTime.getTime()) || isNaN(endTime.getTime())) { throw new Error( - `Invalid maintenance notice start or end time: ${flags['maintenance-notice_start-time']} or ${flags['maintenance-notice_end-time']}`, + `Invalid maintenance notice start or end time: ${startTimeRaw} or ${endTimeRaw}`, ); }