mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-04-22 02:07:55 +00:00
feat: Add Kurdistan sun animation for swap processing
Added animated Kurdistan-themed loading indicator that displays during swap transactions: - KurdistanSun component with 21 rays (Kurdistan flag symbolism) - White center sun with glow effects - Rotating colored halos: green (outer), red (middle), yellow (inner) - Full-screen overlay with backdrop blur during processing - Fixed timing: dialog closes before animation shows 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
import React from 'react';
|
||||
|
||||
interface KurdistanSunProps {
|
||||
size?: number;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const KurdistanSun: React.FC<KurdistanSunProps> = ({ size = 200, className = '' }) => {
|
||||
return (
|
||||
<div className={`kurdistan-sun-container ${className}`} style={{ width: size, height: size }}>
|
||||
{/* Rotating colored halos */}
|
||||
<div className="sun-halos">
|
||||
{/* Green halo (outermost) */}
|
||||
<div className="halo halo-green" />
|
||||
{/* Red halo (middle) */}
|
||||
<div className="halo halo-red" />
|
||||
{/* Yellow halo (inner) */}
|
||||
<div className="halo halo-yellow" />
|
||||
</div>
|
||||
|
||||
{/* Kurdistan Sun with 21 rays */}
|
||||
<svg
|
||||
viewBox="0 0 200 200"
|
||||
className="kurdistan-sun-svg"
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
>
|
||||
{/* Sun rays (21 rays for Kurdistan flag) */}
|
||||
<g className="sun-rays">
|
||||
{Array.from({ length: 21 }).map((_, i) => {
|
||||
const angle = (i * 360) / 21;
|
||||
return (
|
||||
<line
|
||||
key={i}
|
||||
x1="100"
|
||||
y1="100"
|
||||
x2="100"
|
||||
y2="20"
|
||||
stroke="rgba(255, 255, 255, 0.9)"
|
||||
strokeWidth="3"
|
||||
strokeLinecap="round"
|
||||
transform={`rotate(${angle} 100 100)`}
|
||||
className="ray"
|
||||
style={{
|
||||
animationDelay: `${i * 0.05}s`,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</g>
|
||||
|
||||
{/* Central white circle */}
|
||||
<circle
|
||||
cx="100"
|
||||
cy="100"
|
||||
r="35"
|
||||
fill="white"
|
||||
className="sun-center"
|
||||
/>
|
||||
|
||||
{/* Inner glow */}
|
||||
<circle
|
||||
cx="100"
|
||||
cy="100"
|
||||
r="35"
|
||||
fill="url(#sunGradient)"
|
||||
className="sun-glow"
|
||||
/>
|
||||
|
||||
<defs>
|
||||
<radialGradient id="sunGradient">
|
||||
<stop offset="0%" stopColor="rgba(255, 255, 255, 0.8)" />
|
||||
<stop offset="100%" stopColor="rgba(255, 255, 255, 0.2)" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
<style>{`
|
||||
.kurdistan-sun-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.sun-halos {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.halo {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
animation: rotate-halo 3s linear infinite;
|
||||
}
|
||||
|
||||
.halo-green {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 4px solid transparent;
|
||||
border-top-color: #00FF00;
|
||||
border-bottom-color: #00FF00;
|
||||
animation-duration: 3s;
|
||||
}
|
||||
|
||||
.halo-red {
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
border: 4px solid transparent;
|
||||
border-left-color: #FF0000;
|
||||
border-right-color: #FF0000;
|
||||
animation-duration: 2.5s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
|
||||
.halo-yellow {
|
||||
width: 60%;
|
||||
height: 60%;
|
||||
border: 4px solid transparent;
|
||||
border-top-color: #FFD700;
|
||||
border-bottom-color: #FFD700;
|
||||
animation-duration: 2s;
|
||||
}
|
||||
|
||||
@keyframes rotate-halo {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.kurdistan-sun-svg {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
filter: drop-shadow(0 0 20px rgba(255, 255, 255, 0.6));
|
||||
}
|
||||
|
||||
.sun-rays {
|
||||
animation: pulse-rays 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse-rays {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
.ray {
|
||||
animation: ray-shine 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes ray-shine {
|
||||
0%, 100% {
|
||||
opacity: 0.9;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.sun-center {
|
||||
filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.8));
|
||||
}
|
||||
|
||||
.sun-glow {
|
||||
animation: pulse-glow 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse-glow {
|
||||
0%, 100% {
|
||||
opacity: 0.6;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -10,6 +10,7 @@ import { usePolkadot } from '@/contexts/PolkadotContext';
|
||||
import { useWallet } from '@/contexts/WalletContext';
|
||||
import { ASSET_IDS, formatBalance, parseAmount } from '@/lib/wallet';
|
||||
import { useToast } from '@/hooks/use-toast';
|
||||
import { KurdistanSun } from './KurdistanSun';
|
||||
|
||||
const TokenSwap = () => {
|
||||
const { api, isApiReady, selectedAccount } = usePolkadot();
|
||||
@@ -330,6 +331,7 @@ const TokenSwap = () => {
|
||||
}
|
||||
|
||||
setIsSwapping(true);
|
||||
setShowConfirm(false); // Close dialog before transaction starts
|
||||
try {
|
||||
const amountIn = parseAmount(fromAmount, 12);
|
||||
const minAmountOut = parseAmount(
|
||||
@@ -447,7 +449,6 @@ const TokenSwap = () => {
|
||||
description: `Swapped ${fromAmount} ${fromToken} for ~${toAmount} ${toToken}`,
|
||||
});
|
||||
|
||||
setShowConfirm(false);
|
||||
setFromAmount('');
|
||||
|
||||
// Refresh balances without page reload
|
||||
@@ -513,6 +514,18 @@ const TokenSwap = () => {
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
{/* Kurdistan Sun Animation Overlay during swap (only after confirm dialog is closed) */}
|
||||
{isSwapping && !showConfirm && (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-sm">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<KurdistanSun size={300} />
|
||||
<p className="text-white text-xl font-semibold animate-pulse">
|
||||
Processing your swap...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="lg:col-span-2 space-y-6">
|
||||
<Card className="p-6">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
|
||||
Reference in New Issue
Block a user