feat: Sort projects alphabetically in the dashboard and fix layout

This commit is contained in:
Dries Augustyns
2026-02-20 16:01:57 +01:00
parent 5fa9b9dda5
commit 64bd094b47
+12 -7
View File
@@ -22,7 +22,7 @@ import {
import Image from 'next/image'; import Image from 'next/image';
import Link from 'next/link'; import Link from 'next/link';
import {useRouter} from 'next/router'; import {useRouter} from 'next/router';
import {useCallback, useEffect, useRef, useState} from 'react'; import {useCallback, useEffect, useMemo, useRef, useState} from 'react';
interface DashboardLayoutProps { interface DashboardLayoutProps {
children: React.ReactNode; children: React.ReactNode;
@@ -74,6 +74,11 @@ export function DashboardLayout({children}: DashboardLayoutProps) {
const mobileProjectMenuRef = useRef<HTMLDivElement>(null); const mobileProjectMenuRef = useRef<HTMLDivElement>(null);
const mobileUserMenuRef = useRef<HTMLDivElement>(null); const mobileUserMenuRef = useRef<HTMLDivElement>(null);
// Sort projects alphabetically by name
const sortedProjects = useMemo(() => {
return [...availableProjects].sort((a, b) => a.name.localeCompare(b.name));
}, [availableProjects]);
// Handle click outside for project menu // Handle click outside for project menu
useEffect(() => { useEffect(() => {
function handleClickOutside(event: MouseEvent) { function handleClickOutside(event: MouseEvent) {
@@ -179,8 +184,8 @@ export function DashboardLayout({children}: DashboardLayoutProps) {
{/* Project Dropdown */} {/* Project Dropdown */}
{showProjectMenu && ( {showProjectMenu && (
<div className="absolute top-full left-0 right-0 mt-1 bg-white border border-neutral-200 rounded-lg shadow-lg z-50 py-1"> <div className="absolute top-full left-0 right-0 mt-1 bg-white border border-neutral-200 rounded-lg shadow-lg z-50 py-1 max-h-[400px] overflow-y-auto min-w-full w-max">
{availableProjects.map(project => ( {sortedProjects.map(project => (
<button <button
key={project.id} key={project.id}
onClick={e => { onClick={e => {
@@ -189,14 +194,14 @@ export function DashboardLayout({children}: DashboardLayoutProps) {
setActiveProject(project); setActiveProject(project);
setShowProjectMenu(false); setShowProjectMenu(false);
}} }}
className="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-neutral-50 transition-colors" className="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-neutral-50 transition-colors whitespace-nowrap"
> >
<div className="h-6 w-6 rounded bg-neutral-900 text-white flex items-center justify-center text-xs font-medium"> <div className="h-6 w-6 rounded bg-neutral-900 text-white flex items-center justify-center text-xs font-medium flex-shrink-0">
{project.name.charAt(0).toUpperCase()} {project.name.charAt(0).toUpperCase()}
</div> </div>
<span className="text-neutral-900 text-left flex-1">{project.name}</span> <span className="text-neutral-900 text-left flex-1">{project.name}</span>
{activeProject?.id === project.id && ( {activeProject?.id === project.id && (
<div className="ml-auto h-1.5 w-1.5 rounded-full bg-neutral-900" /> <div className="ml-auto h-1.5 w-1.5 rounded-full bg-neutral-900 flex-shrink-0" />
)} )}
</button> </button>
))} ))}
@@ -204,7 +209,7 @@ export function DashboardLayout({children}: DashboardLayoutProps) {
<Link <Link
href="/projects/create" href="/projects/create"
onClick={() => setShowProjectMenu(false)} onClick={() => setShowProjectMenu(false)}
className="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-neutral-50 transition-colors text-neutral-700" className="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-neutral-50 transition-colors text-neutral-700 whitespace-nowrap"
> >
<Plus className="h-4 w-4" /> <Plus className="h-4 w-4" />
<span>Create project</span> <span>Create project</span>