Spaces:
Sleeping
Sleeping
| 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> | |
| ); | |
| } | |