248 lines
6.8 KiB
TypeScript
248 lines
6.8 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { FaMicrochip, FaCode, FaNetworkWired, FaAtom } from "react-icons/fa";
|
|
|
|
export const AppLoader = () => {
|
|
const [progress, setProgress] = useState(0);
|
|
const [phase, setPhase] = useState(0);
|
|
|
|
useEffect(() => {
|
|
const phases = [
|
|
{ progress: 25, delay: 400 },
|
|
{ progress: 50, delay: 300 },
|
|
{ progress: 75, delay: 400 },
|
|
{ progress: 100, delay: 300 },
|
|
];
|
|
|
|
let timeouts: NodeJS.Timeout[] = [];
|
|
let currentDelay = 0;
|
|
|
|
phases.forEach((p, i) => {
|
|
currentDelay += p.delay;
|
|
timeouts.push(
|
|
setTimeout(() => {
|
|
setProgress(p.progress);
|
|
setPhase(i);
|
|
}, currentDelay),
|
|
);
|
|
});
|
|
|
|
return () => timeouts.forEach(clearTimeout);
|
|
}, []);
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
position: "fixed",
|
|
top: 0,
|
|
left: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
backgroundColor: "#0a0a0f",
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
zIndex: 9999,
|
|
overflow: "hidden",
|
|
}}
|
|
>
|
|
{/* Background grid effect */}
|
|
<div
|
|
style={{
|
|
position: "absolute",
|
|
top: 0,
|
|
left: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
backgroundImage: `
|
|
linear-gradient(rgba(59, 130, 246, 0.05) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(59, 130, 246, 0.05) 1px, transparent 1px)
|
|
`,
|
|
backgroundSize: "40px 40px",
|
|
animation: "gridMove 20s linear infinite",
|
|
}}
|
|
/>
|
|
|
|
{/* Glowing orbs */}
|
|
<div
|
|
style={{
|
|
position: "absolute",
|
|
width: "300px",
|
|
height: "300px",
|
|
borderRadius: "50%",
|
|
background:
|
|
"radial-gradient(circle, rgba(59,130,246,0.15) 0%, transparent 70%)",
|
|
filter: "blur(40px)",
|
|
animation: "orbFloat 6s ease-in-out infinite",
|
|
top: "20%",
|
|
left: "30%",
|
|
}}
|
|
/>
|
|
<div
|
|
style={{
|
|
position: "absolute",
|
|
width: "250px",
|
|
height: "250px",
|
|
borderRadius: "50%",
|
|
background:
|
|
"radial-gradient(circle, rgba(139,92,246,0.12) 0%, transparent 70%)",
|
|
filter: "blur(40px)",
|
|
animation: "orbFloat 8s ease-in-out infinite reverse",
|
|
bottom: "20%",
|
|
right: "30%",
|
|
}}
|
|
/>
|
|
|
|
{/* Main content */}
|
|
<div style={{ position: "relative", zIndex: 1, textAlign: "center" }}>
|
|
{/* Logo with animation */}
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
gap: "16px",
|
|
marginBottom: "40px",
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
animation: "logoSpin 3s ease-in-out infinite",
|
|
}}
|
|
>
|
|
<FaAtom size={48} style={{ color: "#3b82f6" }} />
|
|
</div>
|
|
<h1
|
|
style={{
|
|
fontSize: "42px",
|
|
fontWeight: 800,
|
|
background:
|
|
"linear-gradient(135deg, #3b82f6 0%, #8b5cf6 50%, #06b6d4 100%)",
|
|
WebkitBackgroundClip: "text",
|
|
WebkitTextFillColor: "transparent",
|
|
letterSpacing: "4px",
|
|
animation: "titleGlow 2s ease-in-out infinite",
|
|
}}
|
|
>
|
|
HellreigN
|
|
</h1>
|
|
</div>
|
|
|
|
{/* Loading icons animation */}
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
gap: "24px",
|
|
marginBottom: "40px",
|
|
}}
|
|
>
|
|
{[
|
|
{ icon: FaMicrochip, delay: "0s" },
|
|
{ icon: FaNetworkWired, delay: "0.2s" },
|
|
{ icon: FaCode, delay: "0.4s" },
|
|
].map(({ icon: Icon, delay }, i) => (
|
|
<div
|
|
key={i}
|
|
style={{
|
|
width: "50px",
|
|
height: "50px",
|
|
borderRadius: "12px",
|
|
border: `2px solid ${
|
|
phase >= i
|
|
? "rgba(59, 130, 246, 0.6)"
|
|
: "rgba(255,255,255,0.1)"
|
|
}`,
|
|
display: "flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
backgroundColor:
|
|
phase >= i ? "rgba(59, 130, 246, 0.1)" : "transparent",
|
|
animation: `iconPop 0.5s ease-out ${delay} both`,
|
|
transition: "all 0.3s ease",
|
|
}}
|
|
>
|
|
<Icon
|
|
size={22}
|
|
style={{
|
|
color: phase >= i ? "#3b82f6" : "#555",
|
|
transition: "color 0.3s ease",
|
|
}}
|
|
/>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{/* Progress bar */}
|
|
<div
|
|
style={{
|
|
width: "320px",
|
|
height: "4px",
|
|
backgroundColor: "rgba(255,255,255,0.1)",
|
|
borderRadius: "2px",
|
|
overflow: "hidden",
|
|
marginBottom: "16px",
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
height: "100%",
|
|
width: `${progress}%`,
|
|
background:
|
|
"linear-gradient(90deg, #3b82f6 0%, #8b5cf6 50%, #06b6d4 100%)",
|
|
borderRadius: "2px",
|
|
transition: "width 0.4s ease",
|
|
boxShadow: "0 0 20px rgba(59, 130, 246, 0.5)",
|
|
}}
|
|
/>
|
|
</div>
|
|
|
|
{/* Status text */}
|
|
<div
|
|
style={{
|
|
fontSize: "13px",
|
|
color: "rgba(255,255,255,0.5)",
|
|
fontFamily: "monospace",
|
|
letterSpacing: "2px",
|
|
}}
|
|
>
|
|
{phase === 0 && "INITIALIZING CORE..."}
|
|
{phase === 1 && "LOADING AGENTS..."}
|
|
{phase === 2 && "ESTABLISHING CONNECTIONS..."}
|
|
{phase === 3 && "READY"}
|
|
</div>
|
|
</div>
|
|
|
|
{/* CSS Animations */}
|
|
<style>{`
|
|
@keyframes gridMove {
|
|
0% { transform: translate(0, 0); }
|
|
100% { transform: translate(40px, 40px); }
|
|
}
|
|
|
|
@keyframes orbFloat {
|
|
0%, 100% { transform: translate(0, 0) scale(1); }
|
|
50% { transform: translate(30px, -30px) scale(1.1); }
|
|
}
|
|
|
|
@keyframes logoSpin {
|
|
0%, 100% { transform: rotate(0deg) scale(1); }
|
|
25% { transform: rotate(-10deg) scale(1.05); }
|
|
75% { transform: rotate(10deg) scale(1.05); }
|
|
}
|
|
|
|
@keyframes titleGlow {
|
|
0%, 100% { filter: brightness(1); }
|
|
50% { filter: brightness(1.3); }
|
|
}
|
|
|
|
@keyframes iconPop {
|
|
0% { transform: scale(0.5) translateY(10px); opacity: 0; }
|
|
100% { transform: scale(1) translateY(0); opacity: 1; }
|
|
}
|
|
`}</style>
|
|
</div>
|
|
);
|
|
};
|