Files
glchat/web/src/pages/app/GuildRail.tsx
T

59 lines
2.3 KiB
TypeScript
Raw Normal View History

import { useTranslation } from 'react-i18next';
import { NavLink } from 'react-router';
import { Avatar } from '@/components/ui/Avatar';
interface GuildRailProps {
guilds: { id: string; name: string }[];
selectedGuildId: string | null;
canCreate: boolean;
onCreate: () => void;
}
/** Левая рейка: иконки серверов-инициалов и кнопка создания сервера. */
export function GuildRail({ guilds, selectedGuildId, canCreate, onCreate }: GuildRailProps) {
const { t } = useTranslation();
return (
<nav
aria-label={t('guilds.railLabel')}
className="flex w-[72px] shrink-0 flex-col items-center gap-2 overflow-y-auto border-r border-border/40 bg-surface-2/60 py-3"
>
<ul className="gl-stagger flex flex-col items-center gap-2" data-testid="guild-rail">
{guilds.map((guild) => {
const active = guild.id === selectedGuildId;
return (
<li key={guild.id}>
<NavLink
to={`/app/${guild.id}`}
title={guild.name}
aria-label={t('guilds.switchTo', { name: guild.name })}
aria-current={active ? 'page' : undefined}
className={`relative block rounded-[var(--radius-md)] transition-[border-radius,background-color,transform] duration-[var(--duration-fast)] ${
active
? 'gl-ring rounded-[var(--radius-lg)]'
: 'hover:-translate-y-0.5 hover:rounded-[var(--radius-lg)] active:translate-y-0'
}`}
>
<Avatar name={guild.name} seed={guild.id} size="lg" shape="square" />
</NavLink>
</li>
);
})}
</ul>
{canCreate ? (
<button
type="button"
onClick={onCreate}
aria-label={t('guilds.add')}
title={t('guilds.add')}
className="flex h-14 w-14 items-center justify-center rounded-[var(--radius-md)] border border-dashed border-border bg-surface-1 text-2xl text-success transition-[border-radius,border-color,transform] duration-[var(--duration-fast)] hover:-translate-y-0.5 hover:rounded-[var(--radius-lg)] hover:border-success active:translate-y-0"
>
+
</button>
) : null}
</nav>
);
}