diff --git a/src/components/WalletManagement/Notification/NotificationCenter.tsx b/src/components/WalletManagement/Notification/NotificationCenter.tsx new file mode 100644 index 0000000000000000000000000000000000000000..88d541b8f486c95b6c88ea689a8caaa11ef852e1 --- /dev/null +++ b/src/components/WalletManagement/Notification/NotificationCenter.tsx @@ -0,0 +1,51 @@ +// NotificationCenter.tsx + +import React, { useState } from 'react'; +import NotificationList from './NotificationList'; +import { useSpring, animated } from 'react-spring'; +import { FaBell } from 'react-icons/fa'; + +interface NotificationCenterProps {} + +const NotificationCenter: React.FC<NotificationCenterProps> = () => { + const [showNotifications, setShowNotifications] = useState(false); + const [unreadCount, setUnreadCount] = useState(3); // Replace with your logic for unread notifications + + const toggleNotifications = () => { + setShowNotifications(!showNotifications); + // Reset unread count when notifications are opened + if (showNotifications) { + setUnreadCount(0); + } + }; + + const notificationProps = useSpring({ + opacity: showNotifications ? 1 : 0, + height: showNotifications ? 'auto' : 0, + }); + + return ( + <div className="relative inline-block text-left"> + <button + type="button" + onClick={toggleNotifications} + className="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 hover:text-gray-500 " + > + <span className='text-2xl text-white hover:scale-125'> + <FaBell/> + </span> + {unreadCount > 0 && ( + <span className="absolute top-0 right-0 inline-block px-2 py-1 text-xs font-bold text-white bg-red rounded-full"> + {unreadCount} + </span> + )} + </button> + + <animated.div style={notificationProps}> + {showNotifications && <NotificationList onClose={toggleNotifications} />} + </animated.div> + </div> + ); +}; + +export default NotificationCenter; diff --git a/src/components/WalletManagement/Notification/NotificationList.tsx b/src/components/WalletManagement/Notification/NotificationList.tsx new file mode 100644 index 0000000000000000000000000000000000000000..cb67b4871b0d64d2ec1788a9ef785323484fa6df --- /dev/null +++ b/src/components/WalletManagement/Notification/NotificationList.tsx @@ -0,0 +1,94 @@ +// NotificationList.tsx + +import React, { useState } from 'react'; +import { useSpring, animated } from 'react-spring'; +import { FaXmark, FaCircleXmark } from 'react-icons/fa6'; + +interface Notification { + id: number; + amount: number; + from: string; +} + +interface NotificationListProps { + onClose: () => void; +} + +const NotificationList: React.FC<NotificationListProps> = ({ onClose }) => { + const randomMessagesBefore = [ + 'Good news! ', + 'Wow! ', + 'Exciting! ', + 'Amazing! ', + 'Guess what? ', + ]; + + const randomMessagesAfter = [ + ' has been credited to your account.', + ' is now available in your balance.', + ' has just landed in your wallet.', + ' has been received successfully.', + ' is waiting for you in your account.', + ]; + + const getRandomMessage = (messages: string[]) => { + const randomIndex = Math.floor(Math.random() * messages.length); + return messages[randomIndex]; + }; + + const [notifications, setNotifications] = useState<Notification[]>([ + { id: 1, amount: 300000, from: 'Rifqi' }, + { id: 2, amount: 3, from: 'Rifqi' }, + { id: 3, amount: 0, from: 'Rifqi' }, + // Add more notifications as needed + ]); + + const handleDelete = (id: number) => { + const updatedNotifications = notifications.filter((notification) => notification.id !== id); + setNotifications(updatedNotifications); + }; + + const notificationListProps = useSpring({ + opacity: 1, + from: { opacity: 0 }, + }); + + return ( + <animated.div style={notificationListProps}> + <div className="absolute right-0 mt-2 w-96 bg-white border border-gray-200 shadow-lg rounded-md overflow-y-auto max-h-60"> + <div className="flex justify-between p-2 text-black items-center"> + <p className='font-bold text-2xl ml-2'>Notifications</p> + <button + onClick={onClose} + className="text-gray-400 font-extralight hover:text-gray-500 focus:outline-none" + > + <FaXmark /> + </button> + </div> + + <div className="flex flex-col"> + {notifications.map((notification) => ( + <div key={notification.id} className="flex items-center justify-between p-4 border-b"> + <div className='flex flex-col'> + <p className="text-sm text-greytext mr-4"> + {getRandomMessage(randomMessagesBefore)} <span className='text-darkgreen'>Rp{new Intl.NumberFormat().format(notification.amount)}</span> {getRandomMessage(randomMessagesAfter)} + </p> + <p className="text-xs font-thin text-greytext mr-4 text-black">From: {notification.from}</p> + </div> + <button + onClick={() => handleDelete(notification.id)} + className="text-red hover:text-darkred focus:outline-none" + > + <span className='text-lg'> + <FaCircleXmark /> + </span> + </button> + </div> + ))} + </div> + </div> + </animated.div> + ); +}; + +export default NotificationList; diff --git a/src/components/WalletManagement/TopUp/TopUp.tsx b/src/components/WalletManagement/TopUp/TopUp.tsx index 99cde089fd1b75033d92394d58f7db6b8da990bc..acbb220e8a640342332736b735c1a3a57047d9f3 100644 --- a/src/components/WalletManagement/TopUp/TopUp.tsx +++ b/src/components/WalletManagement/TopUp/TopUp.tsx @@ -1,9 +1,10 @@ import React, { useState } from "react"; -import { ToastContainer, toast } from "react-toastify"; +import { ToastContainer, toast, TypeOptions } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import { FaWallet } from 'react-icons/fa6'; import TopUpSingle from "./TopUpSingle"; import ButtonNumber from "../ButtonNumber"; +import NotificationCenter from "../Notification/NotificationCenter"; import BCA from '../../../assets/bca.png'; import Mandiri from '../../../assets/mandiri.png'; import BRI from '../../../assets/briva.png'; @@ -18,6 +19,7 @@ const TopUp = () => { const [bankAccountNumber, setBankAccountNumber] = useState(''); const [popUp, setPopUp] = useState(false) + const formatNumber = (value) => { return Intl.NumberFormat().format(value); }; @@ -60,12 +62,17 @@ const TopUp = () => { <> <ToastContainer /> <div> - <div className="text-3xl text-white mx-auto my-auto font-semibold rounded-lg flex items-center justify-start p-5 max-w-screen-2xl bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-darkgreen via-lightgreen to-verylightgreen"> - <FaWallet className="mr-2" /> Current Balance: <span className="font-normal">350.000</span> + <div className="text-xl md:text-3xl text-white mx-auto my-auto font-semibold rounded-lg flex items-center justify-between p-2 md:p-5 max-w-screen-2xl bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-darkgreen via-lightgreen to-verylightgreen"> + <div className="flex items-center space-x-4"> + <FaWallet className="mr-2" /> + <span> + Current Balance: <span className="font-thin">350.000</span> + </span> + </div> + <NotificationCenter /> </div> <div className="rounded-xl border border-darkgreen mt-4 shadow-lg flex wrap md:flex-col flex-col my-0 mx-auto p-5 max-w-screen-2xl"> <h1 className="text-4xl font-semibold mb-2">Top-Up Amount:</h1> - <div className="mb-4"> <label> <input @@ -150,7 +157,7 @@ const TopUp = () => { </div> {isTopUpValid && ( <div> - <button onClick={() => setPopUp(true)} className="flex items-center mt-5 cursor-pointer hover:bg-lightgreen text-lg mx-auto my-auto font-bold border-2 border-white text-white text-center items-center bg-darkgreen rounded-lg p-5 max-w-screen-sm">TRANSFER</button> + <button onClick={() => setPopUp(true)} className="flex items-center mt-5 cursor-pointer hover:bg-lightgreen text-lg mx-auto my-auto font-bold border-2 border-white text-white text-center items-center bg-darkgreen rounded-lg p-5 max-w-screen-sm">TOP-UP</button> {popUp && <Modal setPopUp={setPopUp} handleValid={handleTopUpValid} modalTitle={"TOP-UP"} modalText={"top-up"} amount={`${topUpAmount}`} modalTextIng={"top-up"} prePositionWord={"to"}/>} </div> )} diff --git a/src/components/WalletManagement/Transfer/Transfer.tsx b/src/components/WalletManagement/Transfer/Transfer.tsx index 25d8ed7ec917b58517ece64ed9092f48d348c582..c1271e544308683df31317eb25d3e9c7e36452e3 100644 --- a/src/components/WalletManagement/Transfer/Transfer.tsx +++ b/src/components/WalletManagement/Transfer/Transfer.tsx @@ -3,6 +3,7 @@ import { ToastContainer, toast } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import { FaWallet } from 'react-icons/fa6'; import Logo from '../../../assets/logo-color.svg' +import NotificationCenter from "../Notification/NotificationCenter"; import ButtonNumber from "../ButtonNumber"; import ReceiptSingle from "./ReceiptSingle"; import Modal from "../Modal"; @@ -84,8 +85,14 @@ const Transfer = () => { <> <ToastContainer /> <div> - <div className="text-3xl text-white mx-auto my-auto font-semibold rounded-lg flex items-center justify-start p-5 max-w-screen-2xl bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-darkgreen via-lightgreen to-verylightgreen"> - <FaWallet className="mr-2" /> Current Balance: <span className="font-thin">350.000</span> + <div className="text-xl md:text-3xl text-white mx-auto my-auto font-semibold rounded-lg flex items-center justify-between p-2 md:p-5 max-w-screen-2xl bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-darkgreen via-lightgreen to-verylightgreen"> + <div className="flex items-center space-x-4"> + <FaWallet className="mr-2" /> + <span> + Current Balance: <span className="font-thin">350.000</span> + </span> + </div> + <NotificationCenter /> </div> <div className="rounded-xl border border-darkgreen mt-4 shadow-lg flex wrap md:flex-col flex-col my-0 mx-auto p-5 max-w-screen-2xl"> <h1 className="text-4xl font-semibold mb-2">Transfer Amount:</h1>