Files
GNX-WEB/gnx-react/components/shared/layout/Preloader.tsx
Iliyan Angelov f962401565 update
2025-10-10 02:01:46 +03:00

152 lines
4.3 KiB
TypeScript

"use client";
import { useState, useEffect } from "react";
import { usePathname } from "next/navigation";
import Image from "next/image";
import "./Preloader.css";
interface PreloaderProps {
children: React.ReactNode;
}
const Preloader = ({ children }: PreloaderProps) => {
const [isLoading, setIsLoading] = useState(true);
const [isMounted, setIsMounted] = useState(false);
const [progress, setProgress] = useState(0);
const pathname = usePathname();
// Initial mount - show preloader on first load
useEffect(() => {
setIsMounted(true);
setIsLoading(true);
setProgress(0);
// Simulate loading progress
const progressInterval = setInterval(() => {
setProgress((prev) => {
if (prev >= 90) {
clearInterval(progressInterval);
return 90;
}
return prev + Math.random() * 15 + 5;
});
}, 50);
// Complete loading after minimum duration
const completeTimer = setTimeout(() => {
setProgress(100);
setTimeout(() => {
setIsLoading(false);
}, 200);
}, 600);
return () => {
clearInterval(progressInterval);
clearTimeout(completeTimer);
};
}, []);
// Handle route changes
useEffect(() => {
if (!isMounted) return;
// Show preloader on route change
setIsLoading(true);
setProgress(0);
// Simulate loading progress
const progressInterval = setInterval(() => {
setProgress((prev) => {
if (prev >= 90) {
clearInterval(progressInterval);
return 90;
}
return prev + Math.random() * 20 + 10;
});
}, 40);
// Complete loading
const completeTimer = setTimeout(() => {
setProgress(100);
setTimeout(() => {
setIsLoading(false);
}, 150);
}, 400);
return () => {
clearInterval(progressInterval);
clearTimeout(completeTimer);
};
}, [pathname, isMounted]);
return (
<>
{isLoading && (
<div className="gnx-preloader-overlay">
{/* Geometric background pattern */}
<div className="gnx-preloader-bg-pattern"></div>
<div className="gnx-preloader-container">
{/* Logo with professional wrapper */}
<div className="gnx-preloader-logo">
<div className="gnx-logo-wrapper">
<div className="gnx-logo-border"></div>
<Image
src="/images/logo.png"
alt="GNX Logo"
width={100}
height={75}
className="gnx-logo-image"
priority
unoptimized
/>
</div>
</div>
{/* Enterprise branding */}
<div className="gnx-enterprise-brand">
<h1 className="gnx-brand-title">GNX Enterprise</h1>
<p className="gnx-brand-subtitle">Digital Transformation Solutions</p>
</div>
{/* Professional progress indicator */}
<div className="gnx-progress-container">
<div className="gnx-progress-bar">
<div
className="gnx-progress-fill"
style={{ width: `${progress}%` }}
>
<div className="gnx-progress-shine"></div>
</div>
</div>
<div className="gnx-progress-info">
<span className="gnx-progress-text">Loading</span>
<span className="gnx-progress-percentage">{Math.round(progress)}%</span>
</div>
</div>
{/* Professional loading indicator */}
<div className="gnx-loading-indicator">
<div className="gnx-spinner">
<div className="gnx-spinner-ring"></div>
<div className="gnx-spinner-ring"></div>
<div className="gnx-spinner-ring"></div>
</div>
</div>
{/* Corporate footer */}
<div className="gnx-preloader-footer">
<p className="gnx-footer-text">Powered by Advanced Technology</p>
</div>
</div>
</div>
)}
<div className={isLoading ? "gnx-content-hidden" : "gnx-content-visible"}>
{children}
</div>
</>
);
};
export default Preloader;