gilded / client /src /components /ServerList.jsx
OmegaOne
Upload 41 files
0a8fe79 verified
import React from 'react';
function ServerIcon({ server, isActive, onClick }) {
const initials = server.name
.split(' ')
.map((w) => w[0])
.slice(0, 2)
.join('')
.toUpperCase();
return (
<div className="relative flex items-center justify-center mb-2 group">
{/* Active indicator bar */}
<div
className={`absolute left-0 w-1 rounded-r-full bg-[#FFD700] transition-all duration-200 ${
isActive ? 'h-10' : 'h-0 group-hover:h-5'
}`}
/>
<button
onClick={onClick}
title={server.name}
className={`w-12 h-12 flex items-center justify-center transition-all duration-200 overflow-hidden ${
isActive
? 'rounded-2xl bg-[#FFD700]'
: 'rounded-full hover:rounded-2xl bg-[#2f2f35] hover:bg-[#FFD700]'
}`}
>
{server.icon ? (
<img
src={server.icon}
alt={server.name}
className="w-full h-full object-cover"
/>
) : (
<span
className={`text-sm font-bold transition-colors duration-200 ${
isActive ? 'text-[#0e0e10]' : 'text-gray-300 group-hover:text-[#0e0e10]'
}`}
>
{initials}
</span>
)}
</button>
</div>
);
}
export default function ServerList({
servers,
activeServer,
onSelectServer,
onOpenDMs,
onCreateServer,
onOpenUserSettings,
user,
}) {
const dmActive = activeServer === null;
return (
<div className="w-[72px] bg-[#111114] flex flex-col items-center py-3 overflow-y-auto scrollbar-hide">
{/* DM Button */}
<div className="relative flex items-center justify-center mb-2 group">
<div
className={`absolute left-0 w-1 rounded-r-full bg-[#FFD700] transition-all duration-200 ${
dmActive ? 'h-10' : 'h-0 group-hover:h-5'
}`}
/>
<button
onClick={onOpenDMs}
title="Direct Messages"
className={`w-12 h-12 flex items-center justify-center transition-all duration-200 ${
dmActive
? 'rounded-2xl bg-[#FFD700]'
: 'rounded-full hover:rounded-2xl bg-[#2f2f35] hover:bg-[#FFD700]'
}`}
>
<svg
className={`w-6 h-6 transition-colors duration-200 ${
dmActive ? 'text-[#0e0e10]' : 'text-gray-300 group-hover:text-[#0e0e10]'
}`}
fill="currentColor"
viewBox="0 0 24 24"
>
<path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H5.17L4 17.17V4h16v12z" />
<path d="M7 9h2v2H7zm4 0h2v2h-2zm4 0h2v2h-2z" />
</svg>
</button>
</div>
{/* Divider */}
<div className="w-8 h-0.5 bg-[#FFD700]/30 rounded-full mb-2" />
{/* Server Icons */}
<div className="flex-1 w-full flex flex-col items-center overflow-y-auto scrollbar-hide">
{servers.map((server) => (
<ServerIcon
key={server.id}
server={server}
isActive={activeServer?.id === server.id}
onClick={() => onSelectServer(server)}
/>
))}
</div>
{/* Divider */}
<div className="w-8 h-0.5 bg-[#2f2f35] rounded-full my-2" />
{/* Create Server Button */}
<button
onClick={onCreateServer}
title="Create a Server"
className="w-12 h-12 rounded-full bg-[#2f2f35] hover:bg-[#22c55e] hover:rounded-2xl flex items-center justify-center transition-all duration-200 group mb-2"
>
<svg
className="w-6 h-6 text-[#22c55e] group-hover:text-white transition-colors duration-200"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
strokeWidth={2}
>
<path strokeLinecap="round" strokeLinejoin="round" d="M12 4v16m8-8H4" />
</svg>
</button>
{/* User Avatar */}
<button
onClick={onOpenUserSettings}
title={user?.username || 'Settings'}
className="w-12 h-12 rounded-full overflow-hidden bg-[#2f2f35] hover:rounded-2xl transition-all duration-200 flex items-center justify-center"
>
{user?.avatar ? (
<img
src={user.avatar}
alt={user.username}
className="w-full h-full object-cover"
/>
) : (
<span className="text-sm font-bold text-gray-300">
{user?.username?.charAt(0)?.toUpperCase() || '?'}
</span>
)}
</button>
</div>
);
}