172 lines
5.5 KiB
TypeScript
172 lines
5.5 KiB
TypeScript
import { cn } from "@/lib/utils";
|
|
import { ProgressBar } from "./progress-bar";
|
|
import { useEffect, useState } from "react";
|
|
|
|
interface OverlayLoaderProps {
|
|
text?: string;
|
|
className?: string;
|
|
show: boolean;
|
|
showProgress?: boolean;
|
|
duration?: number;
|
|
extra_info?: string;
|
|
onProgressComplete?: () => void;
|
|
}
|
|
|
|
export const OverlayLoader = ({
|
|
text,
|
|
className,
|
|
show,
|
|
showProgress = false,
|
|
duration = 10,
|
|
onProgressComplete,
|
|
extra_info,
|
|
}: OverlayLoaderProps) => {
|
|
const [isVisible, setIsVisible] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if (show) {
|
|
setIsVisible(true);
|
|
} else {
|
|
setIsVisible(false);
|
|
}
|
|
}, [show]);
|
|
|
|
if (!show) return null;
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
zIndex: 1000,
|
|
}}
|
|
className={cn(
|
|
"fixed inset-0 bg-black/70 z-50 flex items-center justify-center transition-opacity duration-300",
|
|
isVisible ? "opacity-100" : "opacity-0"
|
|
)}
|
|
>
|
|
<div
|
|
className={cn(
|
|
"flex flex-col items-center justify-center px-6 pt-6 pb-10 rounded-xl bg-white shadow-2xl relative min-h-[347px]",
|
|
"min-w-[280px] sm:min-w-[447px] border border-white/10 transition-all duration-400 ease-out",
|
|
isVisible ? "opacity-100 scale-100" : "opacity-0 scale-90",
|
|
className
|
|
)}
|
|
>
|
|
<div
|
|
className="overlay-loader-dots shrink-0"
|
|
role="status"
|
|
aria-label="Loading"
|
|
/>
|
|
{showProgress ? (
|
|
<div className="w-full space-y-6 pt-4">
|
|
<ProgressBar duration={duration} onComplete={onProgressComplete} />
|
|
{text && (
|
|
<div className="space-y-1">
|
|
<p className="text-[#191919] text-base text-center font-medium font-inter">
|
|
{text}
|
|
</p>
|
|
{extra_info && (
|
|
<p className="text-[#191919]/80 text-xs text-center font-medium font-inter">
|
|
{extra_info}
|
|
</p>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
) : (
|
|
<>
|
|
<p className="text-[#191919] text-base text-center font-medium font-inter">
|
|
{text}
|
|
</p>
|
|
{extra_info && (
|
|
<p className="text-[#191919]/80 text-xs text-center font-medium font-inter">
|
|
{extra_info}
|
|
</p>
|
|
)}
|
|
</>
|
|
)}
|
|
<svg
|
|
className="absolute left-0 bottom-0"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="447"
|
|
height="277"
|
|
viewBox="0 0 447 277"
|
|
fill="none"
|
|
>
|
|
<g filter="url(#filter0_d_4852_6112)">
|
|
<path
|
|
d="M674.5 748.5C668.101 804.091 669 808.5 657.5 832L639 887.5C627 972.5 668.5 1143.5 785 1158.5C984.755 1184.22 877.602 926.811 837.653 808.716C843.652 768.181 841.852 633.973 786.657 421.42C717.663 155.729 278.698 139.89 18.7199 302.37C-241.259 464.851 -399.894 486.766 -478.239 422.953C-544.734 368.793 -537.234 154.707 -464.24 75L-757.716 82.1532C-760.716 183.831 -739.218 390.764 -726.719 430.617C-715.665 465.864 -652.725 581.857 -516.736 619.156C-390.988 653.646 -209.56 584.814 -169.765 572.66C-136.5 562.5 97.7134 443.561 210.704 380.545C699.164 216.532 682.499 679.012 674.5 748.5Z"
|
|
fill="url(#paint0_radial_4852_6112)"
|
|
shapeRendering="crispEdges"
|
|
/>
|
|
</g>
|
|
<defs>
|
|
<filter
|
|
id="filter0_d_4852_6112"
|
|
x="-833"
|
|
y="0"
|
|
width="1810.32"
|
|
height="1235.29"
|
|
filterUnits="userSpaceOnUse"
|
|
colorInterpolationFilters="sRGB"
|
|
>
|
|
<feFlood floodOpacity="0" result="BackgroundImageFix" />
|
|
<feColorMatrix
|
|
in="SourceAlpha"
|
|
type="matrix"
|
|
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
|
result="hardAlpha"
|
|
/>
|
|
<feOffset />
|
|
<feGaussianBlur stdDeviation="37.5" />
|
|
<feComposite in2="hardAlpha" operator="out" />
|
|
<feColorMatrix
|
|
type="matrix"
|
|
values="0 0 0 0 0.85098 0 0 0 0 0.839216 0 0 0 0 0.996078 0 0 0 1 0"
|
|
/>
|
|
<feBlend
|
|
mode="normal"
|
|
in2="BackgroundImageFix"
|
|
result="effect1_dropShadow_4852_6112"
|
|
/>
|
|
<feBlend
|
|
mode="normal"
|
|
in="SourceGraphic"
|
|
in2="effect1_dropShadow_4852_6112"
|
|
result="shape"
|
|
/>
|
|
</filter>
|
|
<radialGradient
|
|
id="paint0_radial_4852_6112"
|
|
cx="0"
|
|
cy="0"
|
|
r="1"
|
|
gradientTransform="matrix(-987.419 -112.408 219.823 -2016.77 351.693 300.327)"
|
|
gradientUnits="userSpaceOnUse"
|
|
>
|
|
<stop stopColor="#D9D6FE" />
|
|
<stop offset="1" stopColor="white" stopOpacity="0" />
|
|
</radialGradient>
|
|
</defs>
|
|
</svg>
|
|
</div>
|
|
|
|
<style jsx>{`
|
|
.overlay-loader-dots {
|
|
width: 50px;
|
|
aspect-ratio: 1;
|
|
--_c: no-repeat radial-gradient(farthest-side, #7a5af8 92%, #0000);
|
|
background: var(--_c) top, var(--_c) left, var(--_c) right,
|
|
var(--_c) bottom;
|
|
background-size: 12px 12px;
|
|
animation: overlay-loader-l7 1s infinite;
|
|
}
|
|
@keyframes overlay-loader-l7 {
|
|
to {
|
|
transform: rotate(0.5turn);
|
|
}
|
|
}
|
|
`}</style>
|
|
</div>
|
|
);
|
|
};
|