QuickActionFab.jsx
1 import { useMemo } from "react"; 2 import { SpeedDial, SpeedDialAction, SpeedDialIcon, styled, useMediaQuery, useTheme } from "@mui/material"; 3 import { 4 Assignment, Psychology, Hub, Person, Groups, 5 } from "@mui/icons-material"; 6 import { useNavigate } from "react-router-dom"; 7 import useAuth from "app/hooks/useAuth"; 8 9 const StyledSpeedDial = styled(SpeedDial)(({ theme }) => ({ 10 position: "fixed", 11 bottom: theme.spacing(3), 12 right: theme.spacing(3), 13 zIndex: theme.zIndex.speedDial, 14 "& .MuiFab-primary": { 15 width: 56, 16 height: 56, 17 boxShadow: "0 8px 24px -6px rgba(99,102,241,0.45)", 18 }, 19 "& .MuiSpeedDialAction-staticTooltipLabel": { 20 width: 150, 21 maxWidth: "none", 22 textAlign: "center", 23 whiteSpace: "nowrap", 24 fontWeight: 500, 25 }, 26 })); 27 28 export default function QuickActionFab() { 29 const { user } = useAuth(); 30 const navigate = useNavigate(); 31 const theme = useTheme(); 32 const isMobile = useMediaQuery(theme.breakpoints.down("sm")); 33 34 const actions = useMemo(() => { 35 if (!user || user.is_restricted) return []; 36 const items = [ 37 { icon: <Assignment />, name: "New Project", path: "/projects/new" }, 38 ]; 39 if (user.is_admin) { 40 items.push( 41 { icon: <Psychology />, name: "New LLM", path: "/llms/new" }, 42 { icon: <Hub />, name: "New Embedding", path: "/embeddings/new" }, 43 { icon: <Person />, name: "New User", path: "/users/new" }, 44 { icon: <Groups />, name: "New Team", path: "/teams/new" }, 45 ); 46 } 47 return items; 48 }, [user]); 49 50 if (actions.length === 0 || isMobile) return null; 51 52 // If there's only one action, clicking the FAB goes directly to it 53 if (actions.length === 1) { 54 return ( 55 <StyledSpeedDial 56 ariaLabel="Quick create" 57 icon={<SpeedDialIcon />} 58 onClick={() => navigate(actions[0].path)} 59 open={false} 60 /> 61 ); 62 } 63 64 return ( 65 <StyledSpeedDial 66 ariaLabel="Quick create" 67 icon={<SpeedDialIcon />} 68 FabProps={{ color: "primary" }} 69 > 70 {actions.map((action) => ( 71 <SpeedDialAction 72 key={action.name} 73 icon={action.icon} 74 tooltipTitle={action.name} 75 tooltipOpen 76 onClick={() => navigate(action.path)} 77 /> 78 ))} 79 </StyledSpeedDial> 80 ); 81 }