ATlast — you'll never need to find your favorites on another platform again. Find your favs in the ATmosphere.
atproto

fixed menu behind dashboard

Changed files
+79 -51
src
+76 -48
src/components/AppHeader.tsx
··· 1 1 import { useState, useEffect, useRef } from "react"; 2 + import { createPortal } from "react-dom"; 2 3 import { Heart, Home, LogOut, ChevronDown } from "lucide-react"; 3 4 import ThemeControls from "./ThemeControls"; 4 5 import FireflyLogo from "../assets/at-firefly-logo.svg?react"; ··· 33 34 onToggleMotion, 34 35 }: AppHeaderProps) { 35 36 const [showMenu, setShowMenu] = useState(false); 37 + const [menuPosition, setMenuPosition] = useState({ top: 0, right: 0 }); 36 38 const menuRef = useRef<HTMLDivElement>(null); 39 + const buttonRef = useRef<HTMLButtonElement>(null); 37 40 38 41 useEffect(() => { 39 42 function handleClickOutside(event: MouseEvent) { 40 - if (menuRef.current && !menuRef.current.contains(event.target as Node)) { 43 + if ( 44 + menuRef.current && 45 + !menuRef.current.contains(event.target as Node) && 46 + buttonRef.current && 47 + !buttonRef.current.contains(event.target as Node) 48 + ) { 41 49 setShowMenu(false); 42 50 } 43 51 } ··· 45 53 return () => document.removeEventListener("mousedown", handleClickOutside); 46 54 }, []); 47 55 56 + useEffect(() => { 57 + if (showMenu && buttonRef.current) { 58 + const rect = buttonRef.current.getBoundingClientRect(); 59 + setMenuPosition({ 60 + top: rect.bottom + 8, 61 + right: window.innerWidth - rect.right, 62 + }); 63 + } 64 + }, [showMenu]); 65 + 48 66 return ( 49 - <div className="bg-white dark:bg-slate-900 border-b-2 border-cyan-500/30 dark:border-purple-500/30 backdrop-blur-xl relative z-[100]"> 67 + <div className="bg-white dark:bg-slate-900 border-b-2 border-cyan-500/30 dark:border-purple-500/30 backdrop-blur-xl relative z-50"> 50 68 <div className="max-w-6xl mx-auto px-4 py-1"> 51 69 <div className="flex items-center justify-between"> 52 70 <button ··· 69 87 /> 70 88 )} 71 89 {session && ( 72 - <div className="relative z-[9999]" ref={menuRef}> 90 + <> 73 91 <button 92 + ref={buttonRef} 74 93 onClick={() => setShowMenu(!showMenu)} 75 94 className="flex items-center space-x-3 px-3 py-1 rounded-lg hover:bg-purple-50 dark:hover:bg-slate-800 transition-colors focus:outline-none focus:ring-2 focus:ring-orange-500 dark:focus:ring-amber-400" 76 95 > ··· 95 114 /> 96 115 </button> 97 116 98 - {showMenu && ( 99 - <div className="absolute right-0 mt-2 w-64 bg-white dark:bg-slate-900 rounded-lg shadow-lg border-2 border-cyan-500/30 dark:border-purple-500/30 py-2 z-[9999]"> 100 - <div className="px-4 py-3"> 101 - <div className="font-semibold text-purple-950 dark:text-cyan-50"> 102 - {session?.displayName || session.handle} 103 - </div> 104 - <div className="text-sm text-purple-750 dark:text-cyan-250"> 105 - @{session?.handle} 106 - </div> 107 - </div> 108 - <button 109 - onClick={() => { 110 - setShowMenu(false); 111 - onNavigate("home"); 112 - }} 113 - className="w-full flex items-center space-x-3 px-4 py-2 hover:bg-purple-50 dark:hover:bg-slate-800 transition-colors text-left" 114 - > 115 - <Home className="w-4 h-4 text-purple-950 dark:text-cyan-50" /> 116 - <span className="text-purple-950 dark:text-cyan-50"> 117 - Dashboard 118 - </span> 119 - </button> 120 - <button 121 - onClick={() => { 122 - setShowMenu(false); 123 - onNavigate("login"); 124 - }} 125 - className="w-full flex items-center space-x-3 px-4 py-2 hover:bg-purple-50 dark:hover:bg-slate-800 transition-colors text-left" 126 - > 127 - <Heart className="w-4 h-4 text-purple-950 dark:text-cyan-50" /> 128 - <span className="text-purple-950 dark:text-cyan-50"> 129 - Login screen 130 - </span> 131 - </button> 132 - <button 133 - onClick={() => { 134 - setShowMenu(false); 135 - onLogout(); 117 + {showMenu && 118 + createPortal( 119 + <div 120 + ref={menuRef} 121 + className="fixed w-64 bg-white dark:bg-slate-900 rounded-lg shadow-2xl border-2 border-cyan-500/30 dark:border-purple-500/30 py-2 z-[9999]" 122 + style={{ 123 + top: `${menuPosition.top}px`, 124 + right: `${menuPosition.right}px`, 136 125 }} 137 - className="w-full flex items-center space-x-3 px-4 py-2 hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors text-left text-red-600 dark:text-red-400" 138 126 > 139 - <LogOut className="w-4 h-4" /> 140 - <span>Log out</span> 141 - </button> 142 - </div> 143 - )} 144 - </div> 127 + <div className="px-4 py-3"> 128 + <div className="font-semibold text-purple-950 dark:text-cyan-50"> 129 + {session?.displayName || session.handle} 130 + </div> 131 + <div className="text-sm text-purple-750 dark:text-cyan-250"> 132 + @{session?.handle} 133 + </div> 134 + </div> 135 + <button 136 + onClick={() => { 137 + setShowMenu(false); 138 + onNavigate("home"); 139 + }} 140 + className="w-full flex items-center space-x-3 px-4 py-2 hover:bg-purple-50 dark:hover:bg-slate-800 transition-colors text-left" 141 + > 142 + <Home className="w-4 h-4 text-purple-950 dark:text-cyan-50" /> 143 + <span className="text-purple-950 dark:text-cyan-50"> 144 + Dashboard 145 + </span> 146 + </button> 147 + <button 148 + onClick={() => { 149 + setShowMenu(false); 150 + onNavigate("login"); 151 + }} 152 + className="w-full flex items-center space-x-3 px-4 py-2 hover:bg-purple-50 dark:hover:bg-slate-800 transition-colors text-left" 153 + > 154 + <Heart className="w-4 h-4 text-purple-950 dark:text-cyan-50" /> 155 + <span className="text-purple-950 dark:text-cyan-50"> 156 + Login screen 157 + </span> 158 + </button> 159 + <button 160 + onClick={() => { 161 + setShowMenu(false); 162 + onLogout(); 163 + }} 164 + className="w-full flex items-center space-x-3 px-4 py-2 hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors text-left text-red-600 dark:text-red-400" 165 + > 166 + <LogOut className="w-4 h-4" /> 167 + <span>Log out</span> 168 + </button> 169 + </div>, 170 + document.body, 171 + )} 172 + </> 145 173 )} 146 174 </div> 147 175 </div>
+3 -3
src/components/SetupWizard.tsx
··· 281 281 onChange={(e) => 282 282 setAutomationFrequency( 283 283 e.target.value as 284 - | "weekly" 285 - | "monthly" 286 - | "quarterly", 284 + | "Weekly" 285 + | "Monthly" 286 + | "Quarterly", 287 287 ) 288 288 } 289 289 className="mt-2 px-3 py-2 bg-white dark:bg-slate-800 border border-cyan-500/30 dark:border-purple-500/30 rounded-lg text-sm w-full text-purple-950 dark:text-cyan-50 hover:border-cyan-400 dark:hover:border-purple-400 focus:outline-none focus:ring-2 focus:ring-orange-500 dark:focus:ring-amber-400 transition-colors"