import React, { useEffect, useRef, useState, useCallback } from 'react'; import './CybersecMenu.css'; interface Notification { id: number; title: string; message: string; removing: boolean; } const CybersecMenu: React.FC = () => { const canvasRef = useRef(null); const animFrameRef = useRef(0); const smokeOffsetRef = useRef(0); const titleRef = useRef(null); const [notification, setNotification] = useState(null); const notifIdRef = useRef(0); const notifTimerRef = useRef | null>(null); const showNotification = useCallback((title: string, message: string) => { if (notifTimerRef.current) clearTimeout(notifTimerRef.current); const id = ++notifIdRef.current; setNotification({ id, title, message, removing: false }); notifTimerRef.current = setTimeout(() => { setNotification(prev => prev?.id === id ? { ...prev, removing: true } : prev); setTimeout(() => setNotification(prev => prev?.id === id ? null : prev), 300); }, 3000); }, []); const selectLevel = useCallback((level: number | string) => { const levelNames: Record = { 1: 'Phishing – Fake emails & links', 2: 'Skimming – ATM/card fraud', 3: 'Password cracking – Brute force & dictionary', 4: 'Social engineering – Manipulation', 'deepfake': 'Voice deepfake – AI-generated speech', }; showNotification(`>> LEVEL ${level} SELECTED`, levelNames[level]); }, [showNotification]); const openWiki = useCallback(() => { showNotification('>> ACCESSING WIKI', 'Security knowledge base loading...'); }, [showNotification]); const openQuiz = useCallback(() => { showNotification('>> INITIATING QUIZ', 'Test your skills module loading...'); }, [showNotification]); // Keyboard navigation useEffect(() => { const handleKey = (e: KeyboardEvent) => { const map: Record void> = { '1': () => selectLevel(1), '2': () => selectLevel(2), '3': () => selectLevel(3), '4': () => selectLevel(4), '5': () => selectLevel('deepfake'), 'w': openWiki, 'W': openWiki, 'q': openQuiz, 'Q': openQuiz, }; map[e.key]?.(); }; window.addEventListener('keydown', handleKey); return () => window.removeEventListener('keydown', handleKey); }, [selectLevel, openWiki, openQuiz]); // Glitch effect on title useEffect(() => { const interval = setInterval(() => { if (Math.random() > 0.9 && titleRef.current) { const rx = (Math.random() * 10 - 5).toFixed(1); const rx2 = (Math.random() * 10 - 5).toFixed(1); titleRef.current.style.textShadow = `${rx}px 0 #FF0040, ${rx2}px 0 #00FFFF`; setTimeout(() => { if (titleRef.current) titleRef.current.style.textShadow = '0 0 30px rgba(0,255,255,0.5)'; }, 100); } }, 2000); return () => clearInterval(interval); }, []); // Particle canvas useEffect(() => { const canvas = canvasRef.current; if (!canvas) return; const ctx = canvas.getContext('2d'); if (!ctx) return; const resize = () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; }; resize(); const COLORS = ['#00FF41', '#FF00FF', '#00FFFF', '#FF6600']; class Particle { x = 0; y = 0; size = 0; speedX = 0; speedY = 0; opacity = 0; color = ''; life = 0; maxLife = 0; constructor() { this.reset(); } reset() { this.x = Math.random() * canvas.width; this.y = Math.random() * canvas.height; this.size = Math.random() * 3 + 1; this.speedX = (Math.random() - 0.5) * 0.5; this.speedY = (Math.random() - 0.5) * 0.5; this.opacity = Math.random() * 0.5 + 0.1; this.color = COLORS[Math.floor(Math.random() * COLORS.length)]; this.life = 0; this.maxLife = Math.random() * 200 + 100; } update() { this.x += this.speedX; this.y += this.speedY; this.life++; if (this.x < 0) this.x = canvas.width; if (this.x > canvas.width) this.x = 0; if (this.y < 0) this.y = canvas.height; if (this.y > canvas.height) this.y = 0; if (this.life > this.maxLife) this.reset(); } draw() { ctx.save(); ctx.globalAlpha = this.opacity * (1 - this.life / this.maxLife); ctx.fillStyle = this.color; ctx.shadowBlur = 10; ctx.shadowColor = this.color; ctx.beginPath(); ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); ctx.fill(); ctx.restore(); } } const count = Math.min(80, Math.floor((canvas.width * canvas.height) / 15000)); let particles = Array.from({ length: count }, () => new Particle()); const onVis = () => { if (document.hidden) { cancelAnimationFrame(animFrameRef.current); } else { animate(); } }; document.addEventListener('visibilitychange', onVis); const onResize = () => { resize(); particles = Array.from({ length: Math.min(80, Math.floor((canvas.width * canvas.height) / 15000)) }, () => new Particle()); }; window.addEventListener('resize', onResize); function drawSmoke() { smokeOffsetRef.current += 0.2; const so = smokeOffsetRef.current; const layerColors = ['#00FF41', '#FF00FF', '#00FFFF']; for (let layer = 0; layer < 3; layer++) { ctx.save(); ctx.globalAlpha = 0.03 - layer * 0.008; const grad = ctx.createRadialGradient( canvas.width * 0.3 + Math.sin(so * 0.01 + layer) * 200, canvas.height * 0.5 + Math.cos(so * 0.015 + layer) * 100, 0, canvas.width * 0.5, canvas.height * 0.5, canvas.width * 0.8 ); grad.addColorStop(0, layerColors[layer]); grad.addColorStop(1, '#0a0a0a'); ctx.fillStyle = grad; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.restore(); } } function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); drawSmoke(); particles.forEach(p => { p.update(); p.draw(); }); ctx.save(); ctx.strokeStyle = 'rgba(0,255,255,0.05)'; ctx.lineWidth = 0.5; for (let i = 0; i < particles.length; i++) { for (let j = i + 1; j < particles.length; j++) { const dx = particles[i].x - particles[j].x; const dy = particles[i].y - particles[j].y; const dist = Math.sqrt(dx * dx + dy * dy); if (dist < 100) { ctx.globalAlpha = (1 - dist / 100) * 0.2; ctx.beginPath(); ctx.moveTo(particles[i].x, particles[i].y); ctx.lineTo(particles[j].x, particles[j].y); ctx.stroke(); } } } ctx.restore(); animFrameRef.current = requestAnimationFrame(animate); } animate(); return () => { cancelAnimationFrame(animFrameRef.current); window.removeEventListener('resize', onResize); document.removeEventListener('visibilitychange', onVis); }; }, []); const menuItems = [ { level: 1 as number | string, cls: 'csm-level-1', icon: '🔒', title: 'Level 1', desc: 'Phishing – Fake emails & links' }, { level: 2 as number | string, cls: 'csm-level-2', icon: '⌨️', title: 'Level 2', desc: 'Skimming – ATM/card fraud' }, { level: 3 as number | string, cls: 'csm-level-3', icon: '🖥️', title: 'Level 3', desc: 'Password cracking – Brute force & dictionary' }, { level: 4 as number | string, cls: 'csm-level-4', icon: '🛡️', title: 'Level 4', desc: 'Social engineering – Manipulation' }, { level: 'deepfake', cls: 'csm-deepfake', icon: '🎭', title: 'Deepfake', desc: 'Voice deepfake – AI-generated speech' }, ]; return (
{/* Header */}

CYBERSEC TRAINING

[ TACTICAL SECURITY SIMULATION ]
{/* Character */}
{/* Hood/Head Silhouette */} {/* Hood Inner Shadow */} {/* Goggles/Mask */} {/* Goggle Lenses */} {/* Glowing Eyes */} {/* Eye Details */} {/* Goggle Frame Details */} {/* Goggle Side Lights */} {/* Shoulders/Torso */} {/* Jacket Details */} {/* Collar */} {/* Holographic Tablet */} 01001 {/* Hand */} {/* Circuit Patterns */} {/* Chin/Mouth */}
{/* Right Side Menu */}
{menuItems.map(item => (
selectLevel(item.level)}>
{item.icon}
{item.title}
{item.desc}
))}
{/* Bottom Container */}
📖 WIKI
Security knowledge base
QUIZ
Test your skills
{/* Notification */} {notification && (
{notification.title}
{notification.message}
)}
); }; export default CybersecMenu;