mirror of https://github.com/kortix-ai/suna.git
fix: fix maintenance mode
This commit is contained in:
parent
3ff1b99bd4
commit
43aacce5e2
|
@ -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 });
|
||||
}
|
||||
}
|
|
@ -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 (
|
||||
<div className="flex items-center justify-center min-h-screen">
|
||||
<Loader2 className="h-8 w-8 animate-spin text-primary" />
|
||||
|
@ -100,6 +93,11 @@ export default function DashboardLayoutContent({
|
|||
return null;
|
||||
}
|
||||
|
||||
// Show maintenance page if maintenance mode is enabled
|
||||
if (maintenanceNotice?.enabled) {
|
||||
return <MaintenanceAlert open={true} onOpenChange={() => {}} closeable={false} />;
|
||||
}
|
||||
|
||||
// Show maintenance page if API is not healthy (but not during initial loading)
|
||||
if (!isCheckingHealth && !isApiHealthy) {
|
||||
return <MaintenancePage />;
|
||||
|
@ -122,11 +120,11 @@ export default function DashboardLayoutContent({
|
|||
accountId={personalAccount?.account_id}
|
||||
/> */}
|
||||
|
||||
<MaintenanceAlert
|
||||
{/* <MaintenanceAlert
|
||||
open={showMaintenanceAlert}
|
||||
onOpenChange={setShowMaintenanceAlert}
|
||||
closeable={true}
|
||||
/>
|
||||
/> */}
|
||||
|
||||
{/* Status overlay for deletion operations */}
|
||||
<StatusOverlay />
|
||||
|
|
|
@ -37,11 +37,6 @@ export function MaintenanceAlert({
|
|||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{ type: 'spring', damping: 30, stiffness: 300 }}
|
||||
>
|
||||
{/* Background pattern */}
|
||||
<div className="absolute inset-0 bg-accent/20 opacity-20">
|
||||
<div className="absolute inset-0 bg-grid-white/10 [mask-image:radial-gradient(white,transparent_85%)]" />
|
||||
</div>
|
||||
|
||||
{closeable && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
|
@ -53,7 +48,6 @@ export function MaintenanceAlert({
|
|||
<span className="sr-only">Close</span>
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<AlertDialogHeader className="gap-6 px-8 pt-10 pb-6 relative z-10">
|
||||
<motion.div
|
||||
className="flex items-center justify-center"
|
||||
|
@ -61,8 +55,8 @@ export function MaintenanceAlert({
|
|||
animate={{ y: 0, opacity: 1 }}
|
||||
transition={{ delay: 0.1 }}
|
||||
>
|
||||
<div className="flex size-16 items-center justify-center rounded-full bg-gradient-to-t from-primary/20 to-secondary/10 backdrop-blur-md">
|
||||
<div className="flex size-12 items-center justify-center rounded-full bg-gradient-to-t from-primary to-primary/80 shadow-md">
|
||||
<div className="flex size-16 items-center justify-center rounded-full bg-gradient-to-t from-amber-500/20 to-amber-600/10 backdrop-blur-md">
|
||||
<div className="flex size-12 items-center justify-center rounded-full bg-gradient-to-t from-amber-500 to-amber-600 shadow-md">
|
||||
<Clock className="h-6 w-6 text-white" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -74,7 +68,7 @@ export function MaintenanceAlert({
|
|||
transition={{ delay: 0.2 }}
|
||||
>
|
||||
<AlertDialogTitle className="text-2xl font-bold text-center text-primary bg-clip-text">
|
||||
High Demand Notice
|
||||
Maintenance Notice
|
||||
</AlertDialogTitle>
|
||||
</motion.div>
|
||||
|
||||
|
@ -84,28 +78,11 @@ export function MaintenanceAlert({
|
|||
transition={{ delay: 0.3 }}
|
||||
>
|
||||
<AlertDialogDescription className="text-base text-center leading-relaxed">
|
||||
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.
|
||||
<span className="mt-4 block font-medium text-primary">
|
||||
Thank you for your understanding. We will notify you via email
|
||||
once the service is fully operational again.
|
||||
</span>
|
||||
We are currently performing maintenance on our system. Please
|
||||
check back later.
|
||||
</AlertDialogDescription>
|
||||
</motion.div>
|
||||
</AlertDialogHeader>
|
||||
|
||||
<AlertDialogFooter className="p-8 pt-4 border-t border-border/40 bg-background/40 backdrop-blur-sm">
|
||||
<Link
|
||||
href="https://github.com/kortix-ai/suna"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="mx-auto w-full flex items-center justify-center gap-3 bg-gradient-to-tr from-primary to-primary/80 hover:opacity-90 text-white font-medium rounded-full px-8 py-3 transition-all hover:shadow-md"
|
||||
>
|
||||
<Github className="h-5 w-5 transition-transform group-hover:scale-110" />
|
||||
<span>Explore Self-Hosted Version</span>
|
||||
</Link>
|
||||
</AlertDialogFooter>
|
||||
</motion.div>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
|
|
|
@ -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<IMaintenanceNotice> => {
|
||||
const response = await fetch('/api/edge-flags');
|
||||
return response.json();
|
||||
const data = await response.json();
|
||||
return data;
|
||||
},
|
||||
{
|
||||
staleTime: 30 * 1000,
|
||||
|
|
|
@ -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}`,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue