refactor(admin-nav): unify sidebar nav groups to match Payload native style

Replace custom BEM classes and SCSS with Payload's native nav-group CSS
classes for Community and YouTube dashboard nav links. Removes emojis,
adds collapsible toggle with chevron, matches the native sidebar UX.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martin Porwoll 2026-02-13 14:25:57 +00:00
parent 826e404955
commit 84685778c3
4 changed files with 63 additions and 240 deletions

View file

@ -1,88 +0,0 @@
.community-nav-links {
padding: 0 var(--base);
margin-top: var(--base);
border-top: 1px solid var(--theme-elevation-100);
padding-top: var(--base);
&__header {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--theme-elevation-500);
}
&__icon {
font-size: 14px;
}
&__title {
flex: 1;
}
&__list {
display: flex;
flex-direction: column;
gap: 2px;
}
&__link {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
border-radius: 4px;
text-decoration: none;
color: var(--theme-elevation-800);
font-size: 13px;
transition: all 0.15s ease;
&:hover {
background-color: var(--theme-elevation-50);
color: var(--theme-elevation-900);
}
&--active {
background-color: var(--theme-elevation-100);
color: var(--theme-text);
font-weight: 500;
&:hover {
background-color: var(--theme-elevation-150);
}
}
}
&__link-icon {
font-size: 16px;
width: 20px;
text-align: center;
}
&__link-label {
flex: 1;
}
}
// Dark mode adjustments
[data-theme='dark'] {
.community-nav-links {
&__link {
&:hover {
background-color: var(--theme-elevation-100);
}
&--active {
background-color: var(--theme-elevation-150);
&:hover {
background-color: var(--theme-elevation-200);
}
}
}
}
}

View file

@ -1,50 +1,46 @@
'use client'
import React from 'react'
import React, { useState } from 'react'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import './CommunityNavLinks.scss'
export const CommunityNavLinks: React.FC = () => {
const pathname = usePathname()
const [open, setOpen] = useState(true)
const links = [
{
href: '/admin/views/community/inbox',
label: 'Community Inbox',
icon: '📥',
},
{
href: '/admin/views/community/analytics',
label: 'Community Analytics',
icon: '📊',
},
{ href: '/admin/views/community/inbox', label: 'Community Inbox' },
{ href: '/admin/views/community/analytics', label: 'Community Analytics' },
]
return (
<div className="community-nav-links">
<div className="community-nav-links__header">
<span className="community-nav-links__icon">💬</span>
<span className="community-nav-links__title">Community</span>
</div>
<nav className="community-nav-links__list">
{links.map((link) => {
const isActive = pathname === link.href
return (
<Link
key={link.href}
href={link.href}
target="_blank"
rel="noopener noreferrer"
className={`community-nav-links__link ${isActive ? 'community-nav-links__link--active' : ''}`}
>
<span className="community-nav-links__link-icon">{link.icon}</span>
<span className="community-nav-links__link-label">{link.label}</span>
<div className="nav-group">
<button
className={`nav-group__toggle ${open ? 'nav-group__toggle--open' : ''}`}
type="button"
onClick={() => setOpen(!open)}
>
<div className="nav-group__label">Community Dashboards</div>
<div className="nav-group__indicator">
<svg
className="icon icon--chevron nav-group__indicator"
height="100%"
style={{ transform: open ? 'rotate(180deg)' : 'rotate(0deg)' }}
viewBox="0 0 20 20"
width="100%"
xmlns="http://www.w3.org/2000/svg"
>
<path className="stroke" d="M14 8L10 12L6 8" strokeLinecap="square" />
</svg>
</div>
</button>
{open && (
<div className="nav-group__content">
{links.map((link) => (
<Link key={link.href} href={link.href} className="nav__link">
<span className="nav__link-label">{link.label}</span>
</Link>
)
})}
</nav>
))}
</div>
)}
</div>
)
}

View file

@ -1,87 +0,0 @@
.yt-nav-links {
padding: 0 var(--base);
margin-top: var(--base);
border-top: 1px solid var(--theme-elevation-100);
padding-top: var(--base);
&__header {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--theme-elevation-500);
}
&__icon {
font-size: 14px;
}
&__title {
flex: 1;
}
&__list {
display: flex;
flex-direction: column;
gap: 2px;
}
&__link {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
border-radius: 4px;
text-decoration: none;
color: var(--theme-elevation-800);
font-size: 13px;
transition: all 0.15s ease;
&:hover {
background-color: var(--theme-elevation-50);
color: var(--theme-elevation-900);
}
&--active {
background-color: var(--theme-elevation-100);
color: var(--theme-text);
font-weight: 500;
&:hover {
background-color: var(--theme-elevation-150);
}
}
}
&__link-icon {
font-size: 16px;
width: 20px;
text-align: center;
}
&__link-label {
flex: 1;
}
}
[data-theme='dark'] {
.yt-nav-links {
&__link {
&:hover {
background-color: var(--theme-elevation-100);
}
&--active {
background-color: var(--theme-elevation-150);
&:hover {
background-color: var(--theme-elevation-200);
}
}
}
}
}

View file

@ -1,43 +1,45 @@
'use client'
import React from 'react'
import React, { useState } from 'react'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import './YouTubeAnalyticsNavLinks.scss'
export const YouTubeAnalyticsNavLinks: React.FC = () => {
const pathname = usePathname()
const [open, setOpen] = useState(true)
const links = [
{
href: '/admin/youtube-analytics',
label: 'YouTube Analytics',
icon: '📈',
},
{ href: '/admin/youtube-analytics', label: 'YouTube Analytics' },
]
return (
<div className="yt-nav-links">
<div className="yt-nav-links__header">
<span className="yt-nav-links__icon">🎬</span>
<span className="yt-nav-links__title">YouTube</span>
</div>
<nav className="yt-nav-links__list">
{links.map((link) => {
const isActive = pathname === link.href
return (
<Link
key={link.href}
href={link.href}
className={`yt-nav-links__link ${isActive ? 'yt-nav-links__link--active' : ''}`}
>
<span className="yt-nav-links__link-icon">{link.icon}</span>
<span className="yt-nav-links__link-label">{link.label}</span>
<div className="nav-group">
<button
className={`nav-group__toggle ${open ? 'nav-group__toggle--open' : ''}`}
type="button"
onClick={() => setOpen(!open)}
>
<div className="nav-group__label">YouTube Dashboards</div>
<div className="nav-group__indicator">
<svg
className="icon icon--chevron nav-group__indicator"
height="100%"
style={{ transform: open ? 'rotate(180deg)' : 'rotate(0deg)' }}
viewBox="0 0 20 20"
width="100%"
xmlns="http://www.w3.org/2000/svg"
>
<path className="stroke" d="M14 8L10 12L6 8" strokeLinecap="square" />
</svg>
</div>
</button>
{open && (
<div className="nav-group__content">
{links.map((link) => (
<Link key={link.href} href={link.href} className="nav__link">
<span className="nav__link-label">{link.label}</span>
</Link>
)
})}
</nav>
))}
</div>
)}
</div>
)
}