47 lines
1.7 KiB
TypeScript
47 lines
1.7 KiB
TypeScript
import { Activity, Bot, Boxes, ChartNoAxesColumnIncreasing, KeyRound, Network, Sparkles } from "lucide-react";
|
|
import type { LauncherServiceView } from "../../entities/service/types";
|
|
import { cn } from "../../shared/lib/cn";
|
|
import { ServiceStatusBadge } from "../../shared/ui/StatusBadge";
|
|
|
|
export function ServiceRail({
|
|
services,
|
|
selectedServiceId,
|
|
onSelect,
|
|
}: {
|
|
services: LauncherServiceView[];
|
|
selectedServiceId?: string;
|
|
onSelect: (serviceId: string) => void;
|
|
}) {
|
|
return (
|
|
<div className="service-rail" aria-label="Доступные сервисы">
|
|
{services.map((service) => (
|
|
<button
|
|
key={service.id}
|
|
className={cn("service-tile", selectedServiceId === service.id && "service-tile--active")}
|
|
onClick={() => onSelect(service.id)}
|
|
type="button"
|
|
>
|
|
<span className="service-tile__media" style={{ "--tile-accent": service.accentColor ?? "#B5FF5A" } as React.CSSProperties}>
|
|
<ServiceIcon slug={service.slug} />
|
|
</span>
|
|
<span className="service-tile__content">
|
|
<strong>{service.title}</strong>
|
|
<small>{service.subtitle}</small>
|
|
</span>
|
|
<ServiceStatusBadge status={service.status} />
|
|
</button>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function ServiceIcon({ slug }: { slug: string }) {
|
|
if (slug.includes("task")) return <ChartNoAxesColumnIncreasing size={18} />;
|
|
if (slug.includes("1c")) return <Boxes size={18} />;
|
|
if (slug.includes("tender")) return <KeyRound size={18} />;
|
|
if (slug.includes("twin")) return <Activity size={18} />;
|
|
if (slug.includes("digital-modules")) return <Sparkles size={18} />;
|
|
if (slug.includes("internal")) return <Network size={18} />;
|
|
return <Bot size={18} />;
|
|
}
|