Add discord shield to navbar (vibe-kanban) (#927)
* ✅ Discord shield added to navbar with: - **Desktop badge**: Discord shield visible on sm+ screens, positioned before the dropdown menu - **Mobile fallback**: Discord link added to dropdown menu for small screens - **Consistent styling**: Uses `h-5` height and proper spacing (`ml-2 mr-1`) - **Accessibility**: Includes proper `aria-label` and `alt` text The implementation follows the existing code patterns and maintains readability as requested. * ✅ Fixed both issues: - **Vertical centering**: Changed from `block` to `flex items-center` to properly align with other navbar buttons - **Theme adaptation**: Added `dark:brightness-90 dark:contrast-125` to subtly adjust the shield colors in dark mode for better visibility The Discord shield now properly aligns with other navbar elements and adapts to both light and dark themes. * ✅ Updated Discord shield with theme colors and positioning: - **Theme colors**: Custom badge using `bg-background`, `text-foreground` for left side and `bg-success`, `text-success-foreground` for right side - **Position**: Moved to right of logo (left side of navbar) instead of right side - **Design**: Clean two-part badge with "discord" label and "online" status that adapts to theme automatically The Discord badge now uses your app's theme colors and is positioned next to the logo for better visual hierarchy. * ✅ Discord online count implemented with: - **Live data**: Fetches real member count from Discord Widget API - **Auto-refresh**: Updates every 60 seconds for live feel - **Graceful fallback**: Shows "online" if API unavailable - **Theme integration**: Maintains your custom success/background colors - **Accessibility**: Includes `aria-live="polite"` for screen readers - **Formatted display**: Shows count as "1,234 online" with proper locale formatting The Discord badge now displays the actual number of online members from your server while maintaining the theme colors and positioning next to the logo. * Cleanup script changes for task attempt 230fa5cc-96f7-4fdb-a549-c2ea46b9e88e * ✅ Fixed positioning - Added `flex items-center` to the container so the logo and Discord badge sit side by side horizontally instead of stacking vertically. * ✅ Added Discord logo from simple-icons: - **Added simple-icons dependency** via pnpm - **Imported Discord icon** from `simple-icons` package - **Replaced "discord" text** with actual Discord SVG logo - **Maintained theme colors** - icon uses `currentColor` so it adapts to theme automatically - **Proper sizing** - `h-4 w-4` matches other navbar icons The Discord badge now displays the official Discord logo instead of text, while maintaining the live member count and theme integration. * Cleanup script changes for task attempt 230fa5cc-96f7-4fdb-a549-c2ea46b9e88e * manual style improvement
This commit is contained in:
committed by
GitHub
parent
613caf91d6
commit
c8e660c7da
@@ -51,10 +51,11 @@
|
||||
"react-hotkeys-hook": "^5.1.0",
|
||||
"react-i18next": "^15.7.3",
|
||||
"react-router-dom": "^6.8.1",
|
||||
"react-use-websocket": "^4.7.0",
|
||||
"react-virtuoso": "^4.14.0",
|
||||
"react-window": "^1.8.11",
|
||||
"rfc6902": "^5.1.2",
|
||||
"react-use-websocket": "^4.7.0",
|
||||
"simple-icons": "^15.16.0",
|
||||
"tailwind-merge": "^2.2.0",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"vibe-kanban-web-companion": "^0.0.4",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
import { useCallback } from 'react';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { siDiscord } from 'simple-icons';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
DropdownMenu,
|
||||
@@ -13,6 +14,7 @@ import {
|
||||
Settings,
|
||||
BookOpen,
|
||||
MessageCircleQuestion,
|
||||
MessageCircle,
|
||||
Menu,
|
||||
Plus,
|
||||
} from 'lucide-react';
|
||||
@@ -24,6 +26,8 @@ import { useProject } from '@/contexts/project-context';
|
||||
import { showProjectForm } from '@/lib/modals';
|
||||
import { useOpenProjectInEditor } from '@/hooks/useOpenProjectInEditor';
|
||||
|
||||
const DISCORD_GUILD_ID = '1423630976524877857';
|
||||
|
||||
const INTERNAL_NAV = [
|
||||
{ label: 'Projects', icon: FolderOpen, to: '/projects' },
|
||||
{ label: 'Settings', icon: Settings, to: '/settings' },
|
||||
@@ -40,6 +44,11 @@ const EXTERNAL_LINKS = [
|
||||
icon: MessageCircleQuestion,
|
||||
href: 'https://github.com/BloopAI/vibe-kanban/issues',
|
||||
},
|
||||
{
|
||||
label: 'Discord',
|
||||
icon: MessageCircle,
|
||||
href: 'https://discord.gg/AC4nwVtJM3',
|
||||
},
|
||||
];
|
||||
|
||||
export function Navbar() {
|
||||
@@ -47,6 +56,36 @@ export function Navbar() {
|
||||
const { projectId, project } = useProject();
|
||||
const { query, setQuery, active, clear, registerInputRef } = useSearch();
|
||||
const handleOpenInEditor = useOpenProjectInEditor(project || null);
|
||||
const [onlineCount, setOnlineCount] = useState<number | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
|
||||
const fetchCount = async () => {
|
||||
try {
|
||||
const res = await fetch(
|
||||
`https://discord.com/api/guilds/${DISCORD_GUILD_ID}/widget.json`,
|
||||
{ cache: 'no-store' }
|
||||
);
|
||||
if (!res.ok) return; // Widget disabled or temporary error; keep previous value
|
||||
const data = await res.json();
|
||||
if (!cancelled && typeof data?.presence_count === 'number') {
|
||||
setOnlineCount(data.presence_count);
|
||||
}
|
||||
} catch {
|
||||
// Network error; ignore and keep previous value
|
||||
}
|
||||
};
|
||||
|
||||
// Initial fetch + refresh every 60s
|
||||
fetchCount();
|
||||
const interval = setInterval(fetchCount, 60_000);
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
clearInterval(interval);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const setSearchBarRef = useCallback(
|
||||
(node: HTMLInputElement | null) => {
|
||||
@@ -78,10 +117,36 @@ export function Navbar() {
|
||||
<div className="border-b bg-background">
|
||||
<div className="w-full px-3">
|
||||
<div className="flex items-center h-12 py-2">
|
||||
<div className="flex-1">
|
||||
<div className="flex-1 flex items-center">
|
||||
<Link to="/projects">
|
||||
<Logo />
|
||||
</Link>
|
||||
<a
|
||||
href="https://discord.gg/AC4nwVtJM3"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="Join our Discord"
|
||||
className="hidden sm:inline-flex items-center ml-3 text-xs font-medium overflow-hidden border h-6"
|
||||
>
|
||||
<span className="bg-muted text-foreground flex items-center p-2 border-r">
|
||||
<svg
|
||||
className="h-4 w-4"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d={siDiscord.path} />
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
className=" h-full items-center flex p-2"
|
||||
aria-live="polite"
|
||||
>
|
||||
{onlineCount !== null
|
||||
? `${onlineCount.toLocaleString()} online`
|
||||
: 'online'}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<SearchBar
|
||||
|
||||
Reference in New Issue
Block a user