ajustes no nav bar

This commit is contained in:
Gabriel Santana de Menezes 2026-05-03 21:54:01 -04:00
parent f14742b312
commit 2bf3635d4d

View file

@ -32,7 +32,7 @@ const dropdownItemClassName = ({ isActive }: { isActive: boolean }) =>
"flex w-full items-center gap-3 rounded-xl px-3 py-2.5 text-sm font-bold transition-all duration-200", "flex w-full items-center gap-3 rounded-xl px-3 py-2.5 text-sm font-bold transition-all duration-200",
isActive isActive
? "bg-brand/10 text-brand" ? "bg-brand/10 text-brand"
: "text-text-muted hover:bg-surface-muted hover:text-text-main" : "text-text-muted hover:bg-surface-muted hover:text-text-main",
); );
export function AppShell() { export function AppShell() {
@ -87,16 +87,16 @@ export function AppShell() {
<div className="relative"> <div className="relative">
<button <button
onClick={() => setShowOrgSwitcher(!showOrgSwitcher)} onClick={() => setShowOrgSwitcher(!showOrgSwitcher)}
className="flex items-center gap-2 rounded-xl border border-border-soft bg-surface-muted/50 px-4 py-2 text-sm font-bold transition-all hover:bg-surface-muted group" className="flex w-48 items-center gap-2 rounded-xl border border-border-soft bg-surface-muted/50 px-4 py-2 text-sm font-bold transition-all hover:bg-surface-muted group"
> >
<div className="flex h-6 w-6 items-center justify-center rounded-lg bg-brand/10 text-brand group-hover:bg-brand group-hover:text-white transition-all"> <div className="flex h-6 w-6 items-center justify-center rounded-lg bg-brand/10 text-brand group-hover:bg-brand group-hover:text-white transition-all">
<Building2 size={14} /> <Building2 size={14} />
</div> </div>
<div className="text-left hidden sm:block"> <div className="text-left hidden sm:block flex-1 min-w-0">
<span className="block text-xs text-text-main leading-tight truncate max-w-[120px]"> <span className="block text-xs text-text-main leading-tight truncate">
{activeOrg?.name || "Selecionar Org"} {activeOrg?.name || "Selecionar Org"}
</span> </span>
<span className="block text-[10px] text-text-muted font-black uppercase tracking-tighter leading-none"> <span className="block text-[10px] text-text-muted font-black uppercase tracking-tighter leading-none truncate">
{activeOrg?.roles[0] || "Visitante"} {activeOrg?.roles[0] || "Visitante"}
</span> </span>
</div> </div>
@ -118,7 +118,7 @@ export function AppShell() {
<motion.div <motion.div
initial={{ opacity: 0, y: 10 }} initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
className="absolute left-0 mt-2 z-50 w-64 rounded-2xl border border-border-soft bg-surface p-2 shadow-xl shadow-brand/10" className="absolute left-0 mt-2 z-50 w-48 rounded-2xl border border-border-soft bg-surface p-2 shadow-xl shadow-brand/10"
> >
<div className="px-3 py-2 text-[10px] font-black uppercase tracking-widest text-text-muted"> <div className="px-3 py-2 text-[10px] font-black uppercase tracking-widest text-text-muted">
Suas Organizações Suas Organizações
@ -185,13 +185,13 @@ export function AppShell() {
<NavLink <NavLink
to="/" to="/"
className={({ isActive }) => { className={({ isActive }) => {
const isBoardActive = window.location.pathname === '/board'; const isBoardActive = window.location.pathname === "/board";
const active = isActive || isBoardActive; const active = isActive || isBoardActive;
return cn( return cn(
"inline-flex items-center gap-2 rounded-xl px-4 py-2 text-sm font-semibold transition-all duration-200", "inline-flex items-center gap-2 rounded-xl px-4 py-2 text-sm font-semibold transition-all duration-200",
active || showTasksDropdown active || showTasksDropdown
? "bg-brand text-white shadow-md shadow-brand/20" ? "bg-brand text-white shadow-md shadow-brand/20"
: "text-text-muted hover:bg-surface-muted hover:text-text-main" : "text-text-muted hover:bg-surface-muted hover:text-text-main",
); );
}} }}
onClick={(e) => { onClick={(e) => {
@ -201,33 +201,41 @@ export function AppShell() {
> >
<ListTodo size={18} /> <ListTodo size={18} />
Tarefas Tarefas
<ChevronDown size={14} className={cn("transition-transform", showTasksDropdown && "rotate-180")} /> <ChevronDown
size={14}
className={cn(
"transition-transform",
showTasksDropdown && "rotate-180",
)}
/>
</NavLink> </NavLink>
{showTasksDropdown && ( {showTasksDropdown && (
<> <>
<div <div
className="fixed inset-0 z-40" className="fixed inset-0 z-40"
onClick={() => setShowTasksDropdown(false)} onClick={() => setShowTasksDropdown(false)}
/> />
<motion.div <motion.div
initial={{ opacity: 0, y: 10 }} initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
className="absolute left-0 mt-2 z-50 w-48 rounded-2xl border border-border-soft bg-surface p-2 shadow-xl shadow-brand/10" className="absolute left-0 mt-2 z-50 w-48 rounded-2xl border border-border-soft bg-surface p-2 shadow-xl shadow-brand/10"
> >
<NavLink <NavLink
to="/" to="/"
end end
onClick={() => setShowTasksDropdown(false)} onClick={() => setShowTasksDropdown(false)}
className={dropdownItemClassName} className={dropdownItemClassName}
> >
<ListTodo size={18} /> <ListTodo size={18} />
Minhas Tarefas Minhas Tarefas
</NavLink> </NavLink>
<NavLink <NavLink
to="/board" to="/board"
onClick={() => setShowTasksDropdown(false)} onClick={() => setShowTasksDropdown(false)}
className={(props) => cn(dropdownItemClassName(props), "mt-1")} className={(props) =>
cn(dropdownItemClassName(props), "mt-1")
}
> >
<Columns size={18} /> <Columns size={18} />
Quadro Quadro
@ -247,14 +255,16 @@ export function AppShell() {
<NavLink <NavLink
to="/organizations" to="/organizations"
className={({ isActive }) => { className={({ isActive }) => {
const isRequestsActive = window.location.pathname === '/requests'; const isRequestsActive =
const isAdminActive = window.location.pathname === '/admin'; window.location.pathname === "/requests";
const active = isActive || isRequestsActive || isAdminActive; const isAdminActive = window.location.pathname === "/admin";
const active =
isActive || isRequestsActive || isAdminActive;
return cn( return cn(
"inline-flex items-center gap-2 rounded-xl px-4 py-2 text-sm font-semibold transition-all duration-200", "inline-flex items-center gap-2 rounded-xl px-4 py-2 text-sm font-semibold transition-all duration-200",
active || showOrgDropdown active || showOrgDropdown
? "bg-brand text-white shadow-md shadow-brand/20" ? "bg-brand text-white shadow-md shadow-brand/20"
: "text-text-muted hover:bg-surface-muted hover:text-text-main" : "text-text-muted hover:bg-surface-muted hover:text-text-main",
); );
}} }}
onClick={(e) => { onClick={(e) => {
@ -264,46 +274,58 @@ export function AppShell() {
> >
<Building2 size={18} /> <Building2 size={18} />
Organizações Organizações
<ChevronDown size={14} className={cn("transition-transform", showOrgDropdown && "rotate-180")} /> <ChevronDown
size={14}
className={cn(
"transition-transform",
showOrgDropdown && "rotate-180",
)}
/>
</NavLink> </NavLink>
{showOrgDropdown && ( {showOrgDropdown && (
<> <>
<div <div
className="fixed inset-0 z-40" className="fixed inset-0 z-40"
onClick={() => setShowOrgDropdown(false)} onClick={() => setShowOrgDropdown(false)}
/> />
<motion.div <motion.div
initial={{ opacity: 0, y: 10 }} initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
className="absolute right-0 mt-2 z-50 w-56 rounded-2xl border border-border-soft bg-surface p-2 shadow-xl shadow-brand/10" className="absolute right-0 mt-2 z-50 w-56 rounded-2xl border border-border-soft bg-surface p-2 shadow-xl shadow-brand/10"
> >
<NavLink <NavLink
to="/organizations" to="/organizations"
onClick={() => setShowOrgDropdown(false)} onClick={() => setShowOrgDropdown(false)}
className={dropdownItemClassName} className={dropdownItemClassName}
> >
<Building2 size={18} /> <Building2 size={18} />
Minhas Organizações Minhas Organizações
</NavLink> </NavLink>
<NavLink <NavLink
to="/requests" to="/requests"
onClick={() => setShowOrgDropdown(false)} onClick={() => setShowOrgDropdown(false)}
className={(props) => cn(dropdownItemClassName(props), "mt-1")} className={(props) =>
cn(dropdownItemClassName(props), "mt-1")
}
> >
<Clock size={18} /> <Clock size={18} />
Solicitações Minhas Solicitações
</NavLink> </NavLink>
{user?.organizations.some( {user?.organizations.some(
(org) => org.roles.includes("OWNER") || org.roles.includes("ADMIN") (org) =>
org.roles.includes("OWNER") ||
org.roles.includes("ADMIN"),
) && ( ) && (
<NavLink <NavLink
to="/admin" to="/admin"
onClick={() => setShowOrgDropdown(false)} onClick={() => setShowOrgDropdown(false)}
className={(props) => cn(dropdownItemClassName(props), "mt-1")} className={(props) =>
cn(dropdownItemClassName(props), "mt-1")
}
> >
<Settings size={18} /> <Settings size={18} />
Gestão da Org Solicitações Pendentes
</NavLink> </NavLink>
)} )}
</motion.div> </motion.div>
@ -343,10 +365,12 @@ export function AppShell() {
<button <button
onClick={() => setShowTasksDropdown(!showTasksDropdown)} onClick={() => setShowTasksDropdown(!showTasksDropdown)}
className={cn( className={cn(
navLinkClassName({ navLinkClassName({
isActive: window.location.pathname === '/' || window.location.pathname === '/board' isActive:
window.location.pathname === "/" ||
window.location.pathname === "/board",
}), }),
"flex-col gap-0.5 py-1" "flex-col gap-0.5 py-1",
)} )}
> >
<ListTodo size={20} /> <ListTodo size={20} />
@ -355,28 +379,30 @@ export function AppShell() {
{showTasksDropdown && ( {showTasksDropdown && (
<> <>
<div <div
className="fixed inset-0 z-40" className="fixed inset-0 z-40"
onClick={() => setShowTasksDropdown(false)} onClick={() => setShowTasksDropdown(false)}
/> />
<motion.div <motion.div
initial={{ opacity: 0, y: -10, scale: 0.95 }} initial={{ opacity: 0, y: -10, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }} animate={{ opacity: 1, y: 0, scale: 1 }}
className="absolute bottom-full left-1/2 -translate-x-1/2 mb-4 z-50 w-40 rounded-2xl border border-border-soft bg-surface p-1 shadow-2xl" className="absolute bottom-full left-1/2 -translate-x-1/2 mb-4 z-50 w-40 rounded-2xl border border-border-soft bg-surface p-1 shadow-2xl"
> >
<NavLink <NavLink
to="/" to="/"
end end
onClick={() => setShowTasksDropdown(false)} onClick={() => setShowTasksDropdown(false)}
className={dropdownItemClassName} className={dropdownItemClassName}
> >
<ListTodo size={18} /> <ListTodo size={18} />
Lista Lista
</NavLink> </NavLink>
<NavLink <NavLink
to="/board" to="/board"
onClick={() => setShowTasksDropdown(false)} onClick={() => setShowTasksDropdown(false)}
className={(props) => cn(dropdownItemClassName(props), "mt-1")} className={(props) =>
cn(dropdownItemClassName(props), "mt-1")
}
> >
<Columns size={18} /> <Columns size={18} />
Quadro Quadro
@ -395,12 +421,13 @@ export function AppShell() {
<button <button
onClick={() => setShowOrgDropdown(!showOrgDropdown)} onClick={() => setShowOrgDropdown(!showOrgDropdown)}
className={cn( className={cn(
navLinkClassName({ navLinkClassName({
isActive: window.location.pathname === '/organizations' || isActive:
window.location.pathname === '/requests' || window.location.pathname === "/organizations" ||
window.location.pathname === '/admin' window.location.pathname === "/requests" ||
window.location.pathname === "/admin",
}), }),
"flex-col gap-0.5 py-1" "flex-col gap-0.5 py-1",
)} )}
> >
<Building2 size={20} /> <Building2 size={20} />
@ -409,38 +436,44 @@ export function AppShell() {
{showOrgDropdown && ( {showOrgDropdown && (
<> <>
<div <div
className="fixed inset-0 z-40" className="fixed inset-0 z-40"
onClick={() => setShowOrgDropdown(false)} onClick={() => setShowOrgDropdown(false)}
/> />
<motion.div <motion.div
initial={{ opacity: 0, y: -10, scale: 0.95 }} initial={{ opacity: 0, y: -10, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }} animate={{ opacity: 1, y: 0, scale: 1 }}
className="absolute bottom-full left-1/2 -translate-x-1/2 mb-4 z-50 w-48 rounded-2xl border border-border-soft bg-surface p-1 shadow-2xl" className="absolute bottom-full left-1/2 -translate-x-1/2 mb-4 z-50 w-48 rounded-2xl border border-border-soft bg-surface p-1 shadow-2xl"
> >
<NavLink <NavLink
to="/organizations" to="/organizations"
onClick={() => setShowOrgDropdown(false)} onClick={() => setShowOrgDropdown(false)}
className={dropdownItemClassName} className={dropdownItemClassName}
> >
<Building2 size={18} /> <Building2 size={18} />
Minhas Orgs Minhas Orgs
</NavLink> </NavLink>
<NavLink <NavLink
to="/requests" to="/requests"
onClick={() => setShowOrgDropdown(false)} onClick={() => setShowOrgDropdown(false)}
className={(props) => cn(dropdownItemClassName(props), "mt-1")} className={(props) =>
cn(dropdownItemClassName(props), "mt-1")
}
> >
<Clock size={18} /> <Clock size={18} />
Pedidos Pedidos
</NavLink> </NavLink>
{user?.organizations.some( {user?.organizations.some(
(org) => org.roles.includes("OWNER") || org.roles.includes("ADMIN") (org) =>
org.roles.includes("OWNER") ||
org.roles.includes("ADMIN"),
) && ( ) && (
<NavLink <NavLink
to="/admin" to="/admin"
onClick={() => setShowOrgDropdown(false)} onClick={() => setShowOrgDropdown(false)}
className={(props) => cn(dropdownItemClassName(props), "mt-1")} className={(props) =>
cn(dropdownItemClassName(props), "mt-1")
}
> >
<Settings size={18} /> <Settings size={18} />
Gestão Gestão