1"use client";
2import { ChevronDown } from 'lucide-react'
3import React, { useEffect, useState } from 'react'
4import { motion, useMotionValue, useTransform } from "framer-motion";
5const steps = ["Buyers", "Platform", "Your Account"];
6const transactionData = [
7 { id: "#9125", name: "Jack", status: "Completed", amount: 1025.00, color: "bg-green-200" },
8 { id: "#9126", name: "Emma", status: "Pending", amount: 2020.00, color: "bg-purple-300" },
9];
10export const PaymentAnimation = () => {
11 const [activeTransactionIndex, setActiveTransactionIndex] = useState(0);
12 const totallength = 270;
13 const [showcommision, setShowCommision] = useState(false);
14 const commision = 2;
15 const ANIMATION_DURATION = 6000;
16 const SHOW_START = 0.3 * ANIMATION_DURATION;
17 const SHOW_DURATION = (0.45 - 0.3) * ANIMATION_DURATION;
18 const y = useMotionValue(0);
19 const midpoint = totallength / 2;
20
21 const showAmountOpacity = useTransform(
22 y,
23 [0, midpoint * 0.9, midpoint],
24 [1, 1, 0]
25 );
26
27 const showCommissionOpacity = useTransform(
28 y,
29 [midpoint, midpoint * 1.1, totallength],
30 [0, 1, 1]
31 );
32 useEffect(() => {
33 let showTimeout: ReturnType<typeof setTimeout>;
34 let hideTimeout: ReturnType<typeof setTimeout>;
35 let transactionTimeout: ReturnType<typeof setTimeout>;
36
37 const loop = () => {
38 showTimeout = setTimeout(() => setShowCommision(true), SHOW_START);
39
40 hideTimeout = setTimeout(() => setShowCommision(false), SHOW_START + SHOW_DURATION);
41 transactionTimeout = setTimeout(() => {
42 setActiveTransactionIndex(prev => (prev + 1) % transactionData.length);
43 }, ANIMATION_DURATION);
44 };
45
46 loop();
47 const interval = setInterval(loop, ANIMATION_DURATION);
48
49 return () => {
50 clearTimeout(showTimeout);
51 clearTimeout(hideTimeout);
52 clearTimeout(transactionTimeout);
53 clearInterval(interval);
54 };
55 }, []);
56
57
58
59 return (
60 <div className='relative min-h-[420px] flex justify-center bg-dot-design top-30'>
61 <motion.div
62 className='flex flex-col items-center gap-2 h-[410px] border border-black/50 w-70 rounded-[10px] p-3 bg-dot-pattern'>
63 <div className="relative w-full h-full flex flex-col justify-center h-[80px]">
64 <div
65 className="absolute top-2 left-2 w-full rounded-2xl bg-white border border-black/10"
66 style={{
67 height: "100%",
68 zIndex: 0,
69 }}
70 ></div>
71 <motion.div
72 initial={{ opacity: 0, y: 20 }}
73 animate={{ opacity: 1, y: 0 }}
74 exit={{ opacity: 0, y: -20 }}
75 transition={{ duration: 0.5 }}
76 className='relative flex justify-between items-center bg-white w-full rounded-2xl border border-black/6 shadow-[0_1px_2px_rgba(0,0,0,0.06),0_4px_12px_rgba(0,0,0,0.08)]'>
77 <div className='relative w-1/2 flex flex-col gap-2.5 pl-4 pb-2 pt-2'>
78 <div className='flex gap-2'>
79 <p className='text-black/70'>{transactionData[activeTransactionIndex].id}</p>
80 <p className='text-gray-500'>{transactionData[activeTransactionIndex].name}</p>
81 </div>
82 <div className={`${transactionData[activeTransactionIndex].color} w-fit px-2 py-2 rounded-md text-black text-xs font-semibold`}>
83 {transactionData[activeTransactionIndex].status}
84 </div>
85 </div>
86 <div className='w-1/2 flex justify-center text-black/70 font-semibold'>
87 ₹{transactionData[activeTransactionIndex].amount}
88 </div>
89
90 </motion.div>
91 <motion.div
92 style={{ y }}
93 initial={{ y: 0, opacity: 0 }}
94 animate={{
95 y: [0, totallength / 2, totallength / 2, totallength, totallength, 0],
96 opacity: [1, 1, 1, 1, 0, 0]
97 }}
98 transition={{
99 duration: 6,
100 times: [0, 0.3, 0.45, 0.75, 0.90, 1],
101 ease: "easeInOut",
102 repeat: Infinity
103 }}
104 className="absolute h-5 w-14 flex items-center px-2 top-24 rounded-md bg-black text-white text-xs z-100">
105 <div className="relative h-4 w-full flex items-center justify-center">
106 <motion.p
107 style={{ opacity: showAmountOpacity }}
108 className="absolute inset-0 text-center"
109 >
110 ₹{transactionData[activeTransactionIndex].amount}
111 </motion.p>
112
113 <motion.p
114 style={{ opacity: showCommissionOpacity }}
115 className="absolute inset-0 text-center"
116 >
117 ₹
118 {transactionData[activeTransactionIndex].amount *
119 (1 - commision / 100)}
120 </motion.p>
121 </div>
122 </motion.div>
123 </div>
124 <div className='relative h-full w-full flex flex-col items-center gap-2 pt-3'>
125 <div className='relative border border-dashed border-black/30 bg-white w-fit rounded-full p-0.5'>
126 <div className='bg-blue-500 rounded-full w-fit px-5 py-1 text-white text-xs font-semibold'>
127 <p>Buyers</p>
128 </div>
129 </div>
130 <div className="relative flex flex-col items-center text-black/60">
131 {Array.from({ length: 5 }).map((_, i) => (
132 <motion.div key={i}>
133 <ChevronDown size={16} />
134 </motion.div>
135 ))}
136 </div>
137 <div className='relative border border-dashed border-black/30 bg-white w-fit rounded-full p-0.5'>
138 <div className='bg-blue-500 rounded-full w-fit px-5 py-1 text-white text-xs font-semibold'>
139 <p>Platform</p>
140 </div>
141 {showcommision &&
142 <div className='absolute flex gap-1 bg-black top-[2px] left-25 w-fit -right-22 rounded-md px-2 py-1 text-xs text-white'>
143 {"-"}{commision}%
144 </div>
145 }
146 </div>
147 <div className="relative flex flex-col items-center text-black/60">
148 {Array.from({ length: 5 }).map((_, i) => (
149 <motion.div key={i}>
150 <ChevronDown size={16} />
151 </motion.div>
152 ))}
153 </div>
154 <div className='relative border border-dashed border-black/30 bg-white w-fit rounded-full p-0.5'>
155 <div className='bg-blue-500 rounded-full w-fit px-5 py-1 text-white text-xs font-semibold'>
156 <p>Your Account</p>
157 </div>
158 </div>
159 </div>
160 </motion.div>
161 </div>
162 )
163}
164
165export default PaymentAnimation;
166