diff --git a/api/services/campaign/rate_limiter.py b/api/services/campaign/rate_limiter.py
index c6fb54b..5bbfcea 100644
--- a/api/services/campaign/rate_limiter.py
+++ b/api/services/campaign/rate_limiter.py
@@ -13,7 +13,7 @@ class RateLimiter:
def __init__(self):
self.redis_client: Optional[aioredis.Redis] = None
- self.stale_call_timeout = 300 # 5 minutes in seconds
+ self.stale_call_timeout = 1200 # 20 minutes in seconds
async def _get_redis(self) -> aioredis.Redis:
"""Get or create Redis connection"""
diff --git a/ui/src/components/layout/AppLayout.tsx b/ui/src/components/layout/AppLayout.tsx
index d13605e..7598659 100644
--- a/ui/src/components/layout/AppLayout.tsx
+++ b/ui/src/components/layout/AppLayout.tsx
@@ -1,12 +1,27 @@
"use client";
+import { Menu } from "lucide-react";
import { usePathname } from "next/navigation";
import React, { ReactNode } from "react";
-import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
+import { Button } from "@/components/ui/button";
+import { SidebarInset, SidebarProvider, useSidebar } from "@/components/ui/sidebar";
import { AppSidebar } from "./AppSidebar";
+function MobileHeader() {
+ const { toggleSidebar } = useSidebar();
+
+ return (
+
+ );
+}
+
interface AppLayoutProps {
children: ReactNode;
headerActions?: ReactNode;
@@ -36,6 +51,7 @@ const AppLayout: React.FC = ({
+
{/* Optional header area for specific pages */}
{headerActions && (
diff --git a/ui/src/components/layout/AppSidebar.tsx b/ui/src/components/layout/AppSidebar.tsx
index 8f0c476..dee75a7 100644
--- a/ui/src/components/layout/AppSidebar.tsx
+++ b/ui/src/components/layout/AppSidebar.tsx
@@ -70,7 +70,7 @@ const StackTeamSwitcher = React.lazy(() =>
export function AppSidebar() {
const pathname = usePathname();
const router = useRouter();
- const { state } = useSidebar();
+ const { state, isMobile, setOpenMobile } = useSidebar();
const { provider, getSelectedTeam, logout, user } = useAuth();
const { config } = useAppConfig();
@@ -167,6 +167,12 @@ export function AppSidebar() {
},
];
+ const handleMobileNavClick = () => {
+ if (isMobile) {
+ setOpenMobile(false);
+ }
+ };
+
const SidebarLink = ({ item }: { item: typeof overviewSection[0] }) => {
const isItemActive = isActive(item.url);
const Icon = item.icon;
@@ -183,7 +189,7 @@ export function AppSidebar() {
isItemActive && "bg-accent text-accent-foreground"
)}
>
-
+
{item.title}
@@ -205,7 +211,7 @@ export function AppSidebar() {
isItemActive && "bg-accent text-accent-foreground"
)}
>
-
+
{item.title}