Commit 500717a6 by Arjun Jhukal

updated menu hover effect, button hover effect and base query

parent df8b6401
...@@ -164,7 +164,7 @@ export default async function Home() { ...@@ -164,7 +164,7 @@ export default async function Home() {
{subBanner.cta_link && ( {subBanner.cta_link && (
<Link <Link
href={subBanner.cta_link} href={subBanner.cta_link}
className="px-[18px] py-[11px] rounded-[28px] inline-block" className="ss-btn px-[18px] py-[11px] rounded-[28px] inline-block"
style={{ style={{
background: background:
index % 2 === 0 index % 2 === 0
......
...@@ -117,12 +117,30 @@ ...@@ -117,12 +117,30 @@
@apply py-2 px-4 lg:px-6 lg:py-3; @apply py-2 px-4 lg:px-6 lg:py-3;
border-radius: 27px; border-radius: 27px;
text-align: center; text-align: center;
width: 100%;
display: block; display: block;
position: relative;
overflow: hidden;
}
.ss-btn::before {
content: '';
background: rgba(255, 255, 255, 0.4);
width: 60%;
height: 100%;
top: 0%;
left: -125%;
transform: skew(45deg);
position: absolute;
transition: left 0.75s ease-in-out;
z-index: 9;
}
.ss-btn:hover::before {
left: 155%;
} }
:disabled { :disabled {
opacity: 0.5; /* opacity: 0.5; */
cursor: not-allowed; cursor: not-allowed;
} }
} }
...@@ -370,8 +388,15 @@ ...@@ -370,8 +388,15 @@
} */ } */
.active__menu { .active__menu {
background-color: #FEEFFF; background: rgba(255, 255, 255, 0.15);
color: var(--color-primary); backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.25);
border-radius: 8px;
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37),
inset 0 1px 0 0 rgba(255, 255, 255, 0.4),
0 0 20px rgba(255, 255, 255, 0.1),
} }
.active__menu * { .active__menu * {
......
...@@ -82,10 +82,67 @@ export default function AdminMenu({ open }: { open: boolean }) { ...@@ -82,10 +82,67 @@ export default function AdminMenu({ open }: { open: boolean }) {
}, },
]; ];
const [glassStyle, setGlassStyle] = React.useState({ top: 0, height: 0, opacity: 0 });
const menuListRef = React.useRef<HTMLUListElement>(null);
const handleMouseEnter = (e: React.MouseEvent<HTMLLIElement>) => {
const item = e.currentTarget;
const list = menuListRef.current;
if (item && list) {
const itemRect = item.getBoundingClientRect();
const listRect = list.getBoundingClientRect();
const topPosition = itemRect.top - listRect.top;
setGlassStyle({
top: topPosition,
height: itemRect.height,
opacity: 1,
});
}
};
const handleMouseLeave = () => {
setGlassStyle((prev) => ({ ...prev, opacity: 0 }));
};
return ( return (
<List> <List ref={menuListRef}
{menuItems.map(({ label, icon, href, active }, idx) => ( onMouseLeave={handleMouseLeave}
<ListItem key={idx}> style={{ position: 'relative' }} >
<div
style={{
position: "absolute",
left: "0",
right: "0",
top: `${glassStyle.top}px`,
height: `${glassStyle.height}px`,
background: "rgba(255, 255, 255, 0.15)",
backdropFilter: "blur(12px)",
WebkitBackdropFilter: "blur(12px)",
border: "1px solid rgba(255, 255, 255, 0.25)",
borderRadius: "8px",
boxShadow: `
0 8px 32px 0 rgba(0, 0, 0, 0.37),
inset 0 1px 0 0 rgba(255, 255, 255, 0.4),
0 0 20px rgba(255, 255, 255, 0.1)
`,
transition: "all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1)",
pointerEvents: "none",
zIndex: 1,
opacity: glassStyle.opacity,
transform:
glassStyle.opacity === 1
? "translateY(0) scale(1)"
: "translateY(0) scale(0.95)",
}}
/>
{
menuItems.map(({ label, icon, href, active }, idx) => (
<ListItem
key={idx}
onMouseEnter={handleMouseEnter}
style={{ position: "relative", zIndex: 2, padding: 0 }}
>
<Link <Link
href={href} href={href}
className={`flex gap-2 items-center px-4 py-2 ${open ? "expanded" : "collapsed" className={`flex gap-2 items-center px-4 py-2 ${open ? "expanded" : "collapsed"
...@@ -100,7 +157,8 @@ export default function AdminMenu({ open }: { open: boolean }) { ...@@ -100,7 +157,8 @@ export default function AdminMenu({ open }: { open: boolean }) {
/> />
</Link> </Link>
</ListItem> </ListItem>
))} ))
</List> }
</ List>
); );
} }
...@@ -10,6 +10,29 @@ import { usePathname } from "next/navigation"; ...@@ -10,6 +10,29 @@ import { usePathname } from "next/navigation";
export default function PrimaryMenu({ open }: { open: boolean }) { export default function PrimaryMenu({ open }: { open: boolean }) {
const { data, isLoading } = useGetAllUserMenuQuery(); const { data, isLoading } = useGetAllUserMenuQuery();
const pathname = usePathname(); const pathname = usePathname();
const [glassStyle, setGlassStyle] = React.useState({ top: 0, height: 0, opacity: 0 });
const menuListRef = React.useRef<HTMLUListElement>(null);
const handleMouseEnter = (e: React.MouseEvent<HTMLLIElement>) => {
const item = e.currentTarget;
const list = menuListRef.current;
if (item && list) {
const itemRect = item.getBoundingClientRect();
const listRect = list.getBoundingClientRect();
const topPosition = itemRect.top - listRect.top;
setGlassStyle({
top: topPosition,
height: itemRect.height,
opacity: 1,
});
}
};
const handleMouseLeave = () => {
setGlassStyle((prev) => ({ ...prev, opacity: 0 }));
};
if (isLoading) { if (isLoading) {
return ( return (
...@@ -24,18 +47,45 @@ export default function PrimaryMenu({ open }: { open: boolean }) { ...@@ -24,18 +47,45 @@ export default function PrimaryMenu({ open }: { open: boolean }) {
); );
} }
return ( return (
<List> <List
ref={menuListRef}
onMouseLeave={handleMouseLeave}
style={{ position: 'relative', }}>
<div
style={{
position: 'absolute',
left: '0',
right: '0',
top: `${glassStyle.top}px`,
height: `${glassStyle.height}px`,
background: 'rgba(255, 255, 255, 0.15)',
backdropFilter: 'blur(12px)',
WebkitBackdropFilter: 'blur(12px)',
border: '1px solid rgba(255, 255, 255, 0.25)',
borderRadius: '8px',
boxShadow: `
0 8px 32px 0 rgba(0, 0, 0, 0.37),
inset 0 1px 0 0 rgba(255, 255, 255, 0.4),
0 0 20px rgba(255, 255, 255, 0.1)
`,
transition: 'all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1)',
pointerEvents: 'none',
zIndex: 1,
opacity: glassStyle.opacity,
transform: glassStyle.opacity === 1 ? 'translateY(0) scale(1)' : 'translateY(0) scale(0.95)',
}}
/>
{data ? data?.data?.map((menu: any) => { {data ? data?.data?.map((menu: any) => {
const href = menu.slug ? `/general/${menu.slug}` : "#"; const href = menu.slug ? `/general/${menu.slug}` : "#";
const isActive = pathname.startsWith(href); const isActive = pathname.startsWith(href);
return ( return (
<ListItem key={menu?.name}> <ListItem key={menu?.name}
{/* <ListItemButton component="a" href={menu.slug ? `/general/${menu.slug}` : "#"}> onMouseEnter={handleMouseEnter}
<ListItemIcon> style={{
<ReceiptEdit size={18} /> position: 'relative',
</ListItemIcon> zIndex: 2,
<ListItemText primary={menu.name} /> padding: 0,
</ListItemButton> */} }}>
<Link href={menu.slug ? `/general/${menu.slug}` : "#"} className={`flex gap-2 items-center px-4 py-2 rounded-md transition-all ${[ <Link href={menu.slug ? `/general/${menu.slug}` : "#"} className={`flex gap-2 items-center px-4 py-2 rounded-md transition-all ${[
open ? "expanded" : "collapsed", open ? "expanded" : "collapsed",
isActive ? "active__menu " : "" isActive ? "active__menu " : ""
......
import SupportIcon from '@/app/customIcons/SupportIcon'; "use client";
import { PATH } from '@/routes/PATH';
import Private from '@/routes/Private'; import React from "react";
import { Box, Button, List, ListItem, ListItemButton, ListItemIcon, ListItemText, Typography } from '@mui/material' import {
import { Home, MessageQuestion, ReceiptEdit, RecordCircle, StatusUp, UserEdit } from '@wandersonalwes/iconsax-react'; Box,
import Link from 'next/link'; List,
import { usePathname, useRouter } from 'next/navigation'; ListItem,
import React from 'react' ListItemIcon,
import PrimaryMenu from './PrimaryMenu'; ListItemText,
} from "@mui/material";
import {
Home,
StatusUp,
MessageQuestion,
} from "@wandersonalwes/iconsax-react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import Private from "@/routes/Private";
import { PATH } from "@/routes/PATH";
import PrimaryMenu from "./PrimaryMenu";
import SupportIcon from "@/app/customIcons/SupportIcon";
// ✅ Define menu array for static items
const staticMenus = [
{
name: "Lobby",
icon: <Home size={18} />,
path: PATH.DASHBOARD.ROOT,
match: (pathname: string) => pathname === PATH.DASHBOARD.ROOT,
},
{
name: "Exclusive Games",
icon: <StatusUp size={18} />,
path: PATH.USER.GAMES.ROOT,
match: (pathname: string) => pathname.startsWith(PATH.USER.GAMES.ROOT),
},
// {
// name: "FAQ & Help",
// icon: <MessageQuestion size={18} />,
// path: "/faq",
// match: (pathname: string) => pathname.startsWith("/faq"),
// },
];
export default function UserMenu({ open }: { open: boolean }) { export default function UserMenu({ open }: { open: boolean }) {
const pathname = usePathname(); const pathname = usePathname();
const router = useRouter(); const [glassStyle, setGlassStyle] = React.useState({ top: 0, height: 0, opacity: 0 });
const menuListRef = React.useRef<HTMLUListElement>(null);
// Glass Morph Hover Effect
const handleMouseEnter = (e: React.MouseEvent<HTMLLIElement>) => {
const item = e.currentTarget;
const list = menuListRef.current;
if (item && list) {
const itemRect = item.getBoundingClientRect();
const listRect = list.getBoundingClientRect();
const topPosition = itemRect.top - listRect.top;
setGlassStyle({
top: topPosition,
height: itemRect.height,
opacity: 1,
});
}
};
const handleMouseLeave = () => {
setGlassStyle((prev) => ({ ...prev, opacity: 0 }));
};
return ( return (
<Box> <Box>
{open ? <Private> {/* Buy Coins & Withdraw */}
{open && (
<Private>
<div className="flex justify-between items-center gap-1 mb-6"> <div className="flex justify-between items-center gap-1 mb-6">
<Link href="/buy-coins" className="ss-btn bg-primary-grad" >Buy Coins</Link> <Link href="/buy-coins" className="ss-btn bg-primary-grad">
<Link href="/withdrawl" className="ss-btn bg-secondary-grad" >Withdraw</Link> Buy Coins
</Link>
<Link href="/withdrawl" className="ss-btn bg-secondary-grad">
Withdraw
</Link>
</div> </div>
</Private> : null} </Private>
)}
<div className="flex flex-col gap-16 lg:gap-28"> <div className="flex flex-col gap-16 lg:gap-28">
<List> <List
<ListItem> ref={menuListRef}
<Link onMouseLeave={handleMouseLeave}
className={`flex gap-2 items-center px-4 py-2 ${[ style={{ position: "relative" }}
open ? "expanded" : "collapsed",
pathname === PATH.DASHBOARD.ROOT ? "active__menu" : ""
].join(" ")}`}
href={PATH.DASHBOARD.ROOT}
> >
<ListItemIcon className={open ? "expanded" : "collapsed"}> {/* ✨ Glass Morphism Layer */}
<Home size={18} /> <div
</ListItemIcon> style={{
<ListItemText position: "absolute",
primary="Lobby" left: "0",
className={open ? "expanded" : "collapsed"} right: "0",
top: `${glassStyle.top}px`,
height: `${glassStyle.height}px`,
background: "rgba(255, 255, 255, 0.15)",
backdropFilter: "blur(12px)",
WebkitBackdropFilter: "blur(12px)",
border: "1px solid rgba(255, 255, 255, 0.25)",
borderRadius: "8px",
boxShadow: `
0 8px 32px 0 rgba(0, 0, 0, 0.37),
inset 0 1px 0 0 rgba(255, 255, 255, 0.4),
0 0 20px rgba(255, 255, 255, 0.1)
`,
transition: "all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1)",
pointerEvents: "none",
zIndex: 1,
opacity: glassStyle.opacity,
transform:
glassStyle.opacity === 1
? "translateY(0) scale(1)"
: "translateY(0) scale(0.95)",
}}
/> />
</Link>
</ListItem> {/* 🧩 Loop Static Menus */}
<ListItem> {staticMenus.map((menu) => {
const isActive = menu.match(pathname);
return (
<ListItem
key={menu.name}
onMouseEnter={handleMouseEnter}
style={{ position: "relative", zIndex: 2, padding: 0 }}
>
<Link <Link
className={`flex gap-2 items-center px-4 py-2 ${[ href={menu.path}
className={`flex gap-2 items-center px-4 py-2 rounded-md transition-all ${[
open ? "expanded" : "collapsed", open ? "expanded" : "collapsed",
[ isActive ? "active__menu" : "",
PATH.USER.GAMES.ROOT,
].some(path => pathname.startsWith(path)) ? "active__menu" : ""
].join(" ")}`} ].join(" ")}`}
href={PATH.USER.GAMES.ROOT}
> >
<ListItemIcon className={open ? "expanded" : "collapsed"}> <ListItemIcon>{menu.icon}</ListItemIcon>
<StatusUp size={18} />
</ListItemIcon>
<ListItemText <ListItemText
primary="Exclusive Games" primary={menu.name}
className={open ? "expanded" : "collapsed"} className={open ? "expanded" : "collapsed"}
/> />
</Link> </Link>
</ListItem> </ListItem>
);
})}
</List> </List>
{/* 🌐 Dynamic Menus */}
<PrimaryMenu open={open} /> <PrimaryMenu open={open} />
</div> </div>
{/* 💬 Support Section */}
<div className="support mt-4"> <div className="support mt-4">
<Link href={"/support"} className="ss-btn support__btn flex items-center gap-2 w-full justify-start"> <Link
href={"/support"}
className="ss-btn support__btn flex items-center gap-2 w-full justify-start"
>
<SupportIcon /> <SupportIcon />
{open ? <strong className='text-[14px] font-semibold opacity-80 !text-white'>Support</strong> : null} {open ? (
<strong className="text-[14px] font-semibold opacity-80 !text-white">
Support
</strong>
) : null}
</Link> </Link>
{open ? <div className='mt-2 text-[11px] lg:text-[12px] text-center'> {open ? (
<div className="mt-2 text-[11px] lg:text-[12px] text-center">
<div className="w-[8px] h-[8px] bg-green-500 rounded-full inline-block"></div> <div className="w-[8px] h-[8px] bg-green-500 rounded-full inline-block"></div>
<span className='opacity-70 !text-white'> 24x7 Support available</span> <span className="opacity-70 !text-white"> 24x7 Support available</span>
</div> : null} </div>
) : null}
</div> </div>
</Box> </Box>
) );
} }
...@@ -31,7 +31,7 @@ export default async function ExclusiveGamePage() { ...@@ -31,7 +31,7 @@ export default async function ExclusiveGamePage() {
src={game.thumbnail || "/assets/images/fallback.png"} src={game.thumbnail || "/assets/images/fallback.png"}
alt={game.name} alt={game.name}
fill fill
className="w-full h-[222px] object-cover group-hover:scale-105 transition-transform duration-300" className="w-full h-[222px] object-cover group-hover:scale-110 transition-transform duration-300"
/> />
</Tooltip> </Tooltip>
</ProtectedLink> </ProtectedLink>
......
...@@ -7,8 +7,8 @@ export const baseQuery = fetchBaseQuery({ ...@@ -7,8 +7,8 @@ export const baseQuery = fetchBaseQuery({
prepareHeaders(headers, { getState }) { prepareHeaders(headers, { getState }) {
const token = (getState() as RootState).auth.access_token; const token = (getState() as RootState).auth.access_token;
// headers.set("Accept", "application/json"); headers.set("Accept", "application/json");
// headers.set("Content-Type", "application/json"); headers.set("Content-Type", "application/json");
if (token) { if (token) {
headers.set("Authorization", `Bearer ${token}`); headers.set("Authorization", `Bearer ${token}`);
} }
......
...@@ -178,16 +178,38 @@ export default function Palette(mode: ThemeMode) { ...@@ -178,16 +178,38 @@ export default function Palette(mode: ThemeMode) {
MuiButton: { MuiButton: {
styleOverrides: { styleOverrides: {
root: { root: {
borderRadius: '27px', borderRadius: "27px",
padding: '12px 24px', padding: "12px 24px",
textAlign: 'center', textAlign: "center",
textTransform: 'capitalize', textTransform: "capitalize",
maxWidth: 'fit-content', width: "100%",
'&:disabled': { position: "relative",
opacity: 0.2, overflow: "hidden",
cursor: 'not-allowed', transition: "all 0.3s ease-in-out",
color: "#fff" color: "#fff",
}, "&:disabled": {
// opacity: 0.5,
cursor: "not-allowed",
},
// ✨ Shine effect (pseudo-element)
"&::before": {
content: '""',
position: "absolute",
top: 0,
left: "-120%",
width: "60%",
height: "100%",
background: "rgba(255, 255, 255, 0.4)",
transform: "skew(45deg)",
transition: "left 0.75s ease-in-out",
zIndex: 1,
},
"&:hover::before": {
left: "155%",
},
// [baseTheme.breakpoints.down("md")]: {
// padding: "8px 16px",
// },
}, },
}, },
variants: [ variants: [
...@@ -196,9 +218,9 @@ export default function Palette(mode: ThemeMode) { ...@@ -196,9 +218,9 @@ export default function Palette(mode: ThemeMode) {
style: { style: {
background: primaryGradColors[0], background: primaryGradColors[0],
color: "#fff", color: "#fff",
"&:hover": { // "&:hover": {
opacity: 0.9, // opacity: 0.9,
}, // },
}, },
}, },
{ {
...@@ -206,9 +228,9 @@ export default function Palette(mode: ThemeMode) { ...@@ -206,9 +228,9 @@ export default function Palette(mode: ThemeMode) {
style: { style: {
background: secondaryGradColors[0], background: secondaryGradColors[0],
color: "#fff", color: "#fff",
"&:hover": { // "&:hover": {
opacity: 0.9, // opacity: 0.9,
}, // },
}, },
}, },
], ],
......
...@@ -379,10 +379,29 @@ export default function Palette(mode: ThemeMode) { ...@@ -379,10 +379,29 @@ export default function Palette(mode: ThemeMode) {
textAlign: "center", textAlign: "center",
textTransform: "capitalize", textTransform: "capitalize",
width: "100%", width: "100%",
position: "relative",
overflow: "hidden",
transition: "all 0.3s ease-in-out",
"&:disabled": { "&:disabled": {
opacity: 0.5, opacity: 0.5,
cursor: "not-allowed", cursor: "not-allowed",
}, },
// ✨ Shine effect (pseudo-element)
"&::before": {
content: '""',
position: "absolute",
top: 0,
left: "-120%",
width: "60%",
height: "100%",
background: "rgba(255, 255, 255, 0.4)",
transform: "skew(45deg)",
transition: "left 0.75s ease-in-out",
zIndex: 1,
},
"&:hover::before": {
left: "155%",
},
[baseTheme.breakpoints.down("md")]: { [baseTheme.breakpoints.down("md")]: {
padding: "8px 16px", padding: "8px 16px",
}, },
...@@ -394,7 +413,9 @@ export default function Palette(mode: ThemeMode) { ...@@ -394,7 +413,9 @@ export default function Palette(mode: ThemeMode) {
style: { style: {
background: primaryGradColors[0], background: primaryGradColors[0],
color: "#fff", color: "#fff",
"&:hover": { opacity: 0.9 }, // "&:hover": {
// opacity: 0.9,
// },
}, },
}, },
{ {
...@@ -402,11 +423,14 @@ export default function Palette(mode: ThemeMode) { ...@@ -402,11 +423,14 @@ export default function Palette(mode: ThemeMode) {
style: { style: {
background: secondaryGradColors[0], background: secondaryGradColors[0],
color: "#fff", color: "#fff",
"&:hover": { opacity: 0.9 }, // "&:hover": {
// opacity: 0.9,
// },
}, },
}, },
], ],
}, },
MuiList: { MuiList: {
styleOverrides: { root: { padding: 0 } }, styleOverrides: { root: { padding: 0 } },
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment