Files
iiEasy/components/SafetyDiagram.tsx

84 lines
4.3 KiB
TypeScript
Executable File

import React from 'react';
import { ArrowLeftIcon } from './icons';
const DiagramNode: React.FC<{ label: string; className?: string; children?: React.ReactNode }> = ({ label, className = '', children }) => (
<div className={`absolute ${className}`}>
<div className="relative w-[220px] h-[220px]">
<div className="absolute left-1/2 top-1/2 flex h-[150px] w-[150px] -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full bg-slate-100 text-center text-xl font-semibold text-slate-700">
<span>{label}</span>
</div>
{children}
</div>
</div>
);
const OrbitingLabel: React.FC<{ label: string; className?: string }> = ({ label, className = '' }) => (
<div className={`absolute bg-slate-50 uppercase px-4 py-2 rounded-lg font-mono text-xs text-slate-600 text-center whitespace-nowrap ${className}`}>
{label}
</div>
);
const AnimatedArrowCircle: React.FC<{ duration?: string, direction?: 'normal' | 'reverse' }> = ({ duration = '30s', direction = 'normal' }) => (
<div
className="absolute inset-[-5px] border-2 border-dashed border-green-500 rounded-full"
style={{
borderColor: '#22c55e transparent transparent transparent',
animation: `spin ${duration} linear infinite`,
animationDirection: direction,
}}
>
<div className={`absolute top-0 left-1/2 -translate-x-1/2 -translate-y-full ${direction === 'reverse' ? '-rotate-90' : 'rotate-90'}`}>
<div className="h-0 w-0" style={{
borderStyle: 'solid',
borderWidth: '0 4px 7px 4px',
borderColor: 'transparent transparent #22c55e transparent',
}}></div>
</div>
</div>
);
const ConnectingArrow: React.FC<{ className?: string, rotation?: string }> = ({ className = '', rotation = '0deg' }) => (
<div className={`absolute flex items-center flex-col gap-y-1 w-10 text-slate-400 ${className}`} style={{ transform: `rotate(${rotation})` }}>
<div className="animate-safety-arrow"><ArrowLeftIcon className="w-4 h-4 rotate-180" /></div>
<div className="animate-safety-arrow" style={{animationDelay: '1s'}}><ArrowLeftIcon className="w-4 h-4 rotate-180" /></div>
</div>
);
const SafetyDiagram: React.FC = () => {
return (
<div className="relative w-full max-w-5xl mx-auto my-12" style={{ aspectRatio: '1920 / 1080' }}>
<div className="relative w-full h-full font-mono uppercase scale-[0.5] sm:scale-[0.6] md:scale-[0.75] lg:scale-[0.9] xl:scale-100 origin-top-left">
<DiagramNode label="Teach" className="left-[440px] top-[76px]">
<AnimatedArrowCircle duration="30s" direction="normal" />
<OrbitingLabel label="Filter Data" className="left-1/2 top-[-20px] -translate-x-1/2 -translate-y-full" />
<OrbitingLabel label="Human Values" className="left-[-20px] top-1/2 -translate-x-full -translate-y-1/2" />
<OrbitingLabel label="Company Policies" className="left-1/2 bottom-[-20px] -translate-x-1/2 translate-y-full" />
</DiagramNode>
<DiagramNode label="Test" className="left-[1030px] top-[76px]">
<AnimatedArrowCircle duration="40s" direction="reverse" />
<OrbitingLabel label="Red Teaming" className="left-1/2 top-[-20px] -translate-x-1/2 -translate-y-full" />
<OrbitingLabel label="Preparedness Evals" className="right-[-20px] top-1/2 translate-x-full -translate-y-1/2" />
<OrbitingLabel label="System Cards" className="left-1/2 bottom-[-20px] -translate-x-1/2 translate-y-full" />
</DiagramNode>
<DiagramNode label="Share" className="left-[735px] top-[552px]">
<AnimatedArrowCircle duration="35s" direction="normal" />
<OrbitingLabel label="Safety Committees" className="left-1/2 top-[-20px] -translate-x-1/2 -translate-y-full" />
<OrbitingLabel label="Feedback" className="left-[-20px] top-1/2 -translate-x-full -translate-y-1/2" />
<OrbitingLabel label="Alpha / Beta" className="right-[-20px] top-1/2 translate-x-full -translate-y-1/2" />
</DiagramNode>
{/* Connecting Arrows */}
<ConnectingArrow className="left-[940px] top-[282px]" />
<ConnectingArrow className="left-[1090px] top-[525px]" rotation="-55deg" />
<ConnectingArrow className="left-[790px] top-[525px] rotate-[55deg]" />
</div>
</div>
);
};
export default SafetyDiagram;