rc
This commit is contained in:
parent
533eb76c76
commit
8b47de1c57
55
app/callout.tsx
Normal file
55
app/callout.tsx
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import React, { useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
const CalloutModal = ({ isOpen, onClose, item, onSubmit }) => {
|
||||
const [tokenId, setTokenId] = useState('');
|
||||
|
||||
const handleTokenChange = (e) => {
|
||||
setTokenId(e.target.value);
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
onSubmit(tokenId);
|
||||
onClose();
|
||||
};
|
||||
|
||||
return isOpen ? (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 modal-bg"
|
||||
>
|
||||
<div className="bg-white p-4 rounded shadow-lg w-11/12 max-w-md modal">
|
||||
|
||||
<div className="flex items-start">
|
||||
<h2 className="text-xl font-bold mb-2">Make a new call!</h2>
|
||||
<button
|
||||
className="p-1 ml-auto bg-transparent border-0 text-black float-right text-3xl leading-none font-semibold outline-none focus:outline-none"
|
||||
onClick={onClose}
|
||||
>
|
||||
<span className="bg-transparent text-white h-10 w-6 text-2xl block outline-none focus:outline-none">x</span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<p className="text-lg mb-4">Type in a tokens short code, that you will think boom anytime soon</p>
|
||||
<input
|
||||
type="text"
|
||||
value={tokenId}
|
||||
onChange={handleTokenChange}
|
||||
className="w-full p-2 mb-4 border rounded glassmorphism"
|
||||
placeholder="Enter token short code"
|
||||
/>
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded w-full glassmorphism"
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
) : null;
|
||||
};
|
||||
|
||||
export default CalloutModal;
|
||||
|
|
@ -14,7 +14,7 @@ body {
|
|||
|
||||
:root {
|
||||
|
||||
--glassmorphism-gradient: linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(0, 0, 0, 0.1) 100%);
|
||||
--glassmorphism-gradient: linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0%, rgba(0, 0, 0, 0.2) 100%);
|
||||
--glassmorphism-gradient-hover: linear-gradient(135deg, rgba(255, 255, 255, 0.3) 0%, rgba(0, 0, 0, 0.3) 100%);
|
||||
--glassmorphism-bg: rgba(255, 255, 255, 0.03);
|
||||
--glassmorphism-blur: 10px;
|
||||
|
|
@ -60,12 +60,14 @@ body {
|
|||
justify-content: center; /* Center vertically */
|
||||
align-items: center; /* Center horizontally */
|
||||
position: relative;
|
||||
transition: background-image 0.3s ease, box-shadow 0.3s ease, border 0.3s ease, backdrop-filter 0.3s ease;
|
||||
transition:{duration:1}
|
||||
|
||||
}
|
||||
|
||||
.leaderboard-card:hover{
|
||||
background: var(--glassmorphism-gradient-hover), var(--glassmorphism-bg);
|
||||
transition:{duration:1}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -84,4 +86,23 @@ body {
|
|||
justify-content: center; /* Center vertically */
|
||||
width: 100%;
|
||||
position:relative; /* Adjust padding as needed */
|
||||
}
|
||||
|
||||
|
||||
.modal {
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(0, 0, 0, 1) 100%), var(--glassmorphism-bg);
|
||||
backdrop-filter: blur(var(--glassmorphism-blur));
|
||||
border: 1px solid var(--glassmorphism-border);
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 1);
|
||||
overflow: hidden;
|
||||
transition: background 0.3s ease, box-shadow 0.3s ease, border 0.3s ease;
|
||||
}
|
||||
|
||||
.modal-bg {
|
||||
background: linear-gradient(135deg, rgba(100, 100, 100, 0.02) 0%, rgba(0, 0, 0, 0.1) 100%), var(--glassmorphism-bg);
|
||||
backdrop-filter: blur(var(--glassmorphism-blur));
|
||||
border: 1px solid var(--glassmorphism-border);
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 1);
|
||||
overflow: hidden;
|
||||
transition: background 0.3s ease, box-shadow 0.3s ease, border 0.3s ease;
|
||||
}
|
||||
|
|
@ -1,32 +1,80 @@
|
|||
// Modal.js
|
||||
|
||||
import React from 'react';
|
||||
import React, { useEffect,useState} from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
const Modal = ({ isOpen, onClose, item }) => {
|
||||
|
||||
const [details, setDetails] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen && item) {
|
||||
const fetchDetails = async () => {
|
||||
try {
|
||||
const response = await fetch(`https://api.callfi.io/get_user_callouts.php?tag=${item.username}`);
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
const data = await response.json();
|
||||
setDetails(data);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch user details:', error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchDetails();
|
||||
}
|
||||
}, [isOpen, item]);
|
||||
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center overflow-x-hidden overflow-y-auto outline-none focus:outline-none">
|
||||
<div className="relative w-auto max-w-3xl mx-auto my-6">
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }} className="fixed inset-0 z-50 flex items-center justify-center overflow-x-hidden overflow-y-auto outline-none focus:outline-none modal-bg" onClick={onClose}>
|
||||
<div className="relative w-auto max-w-3xl mx-auto my-6 modal">
|
||||
{/* Modal content */}
|
||||
<div className="relative flex flex-col bg-white border-0 rounded-lg shadow-lg outline-none focus:outline-none">
|
||||
<div className="relative flex flex-col border-0 rounded-lg shadow-lg outline-none focus:outline-none">
|
||||
{/* Header */}
|
||||
<div className="flex items-start justify-between p-5 border-b border-solid rounded-t border-blueGray-200">
|
||||
<h3 className="text-3xl font-semibold">{item.username}s Details</h3>
|
||||
<button
|
||||
<h3 className="text-3xl font-semibold">{item.username}s Callouts</h3>
|
||||
{/* <button
|
||||
className="p-1 ml-auto bg-transparent border-0 text-black float-right text-3xl leading-none font-semibold outline-none focus:outline-none"
|
||||
onClick={onClose}
|
||||
>
|
||||
>
|
||||
<span className="bg-transparent text-black h-6 w-6 text-2xl block outline-none focus:outline-none">×</span>
|
||||
</button>
|
||||
</button>*/}
|
||||
</div>
|
||||
{/* Body */}
|
||||
<div className="relative p-6 flex-auto">
|
||||
<p className="my-4 text-blueGray-500 text-lg leading-relaxed">{item.username} has {item.points} points.</p>
|
||||
<p className={`my-4 text-blueGray-500 text-2xl font-bold leading-relaxed ${
|
||||
parseFloat(item.points) > 0 ? 'text-green-500' : 'text-red-500'
|
||||
}`}>Total Gains : {parseFloat(item.points).toFixed(2)} x</p>
|
||||
</div>
|
||||
<div className="relative p-6 flex-auto">
|
||||
{details != null ? (
|
||||
<div>
|
||||
{details.map((detail) => (
|
||||
<p
|
||||
key={detail.token}
|
||||
className={`my-4 text-lg leading-relaxed ${
|
||||
parseFloat(detail.gains) > 0 ? 'text-green-500' : 'text-red-400'
|
||||
}`}
|
||||
>
|
||||
{detail.token}: {parseFloat(detail.gains).toFixed(2)}x [
|
||||
{parseFloat(detail.price_at_creation).toFixed(8) + ' => ' + parseFloat(detail.price_now).toFixed(8)}]
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<p>Loading...</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
25
app/page.tsx
25
app/page.tsx
|
|
@ -6,6 +6,10 @@ import { PrivyProvider, usePrivy } from "@privy-io/react-auth";
|
|||
import { FaTwitter, FaWallet } from "react-icons/fa";
|
||||
import { CheckIcon } from "@heroicons/react/outline";
|
||||
import Modal from './modal';
|
||||
import CalloutModal from './callout';
|
||||
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
|
||||
// Helper functions to generate pseudo data
|
||||
const generateRandomName = () => {
|
||||
|
|
@ -32,6 +36,7 @@ function Home() {
|
|||
const [leaderboardData, setLeaderboardData] = useState([]);
|
||||
const [isJoined, setIsJoined] = useState(false);
|
||||
const [selectedItem, setSelectedItem] = useState(null); // State to store selected leaderboard item
|
||||
const [newCallModalOpen, setNewCallModalOpen] = useState(false);
|
||||
|
||||
// Function to handle opening modal and setting selected item
|
||||
const openModal = (item) => {
|
||||
|
|
@ -45,6 +50,19 @@ function Home() {
|
|||
setModalOpen(false);
|
||||
};
|
||||
|
||||
const openNewCallModal = () => {
|
||||
setNewCallModalOpen(true);
|
||||
};
|
||||
|
||||
const closeNewCallModal = () => {
|
||||
setNewCallModalOpen(false);
|
||||
};
|
||||
|
||||
const handleNewCallSubmit = (tokenId) => {
|
||||
const twitterIntentURL = `https://x.com/intent/tweet?text=%24${tokenId}%20is%20Booming%20rn%21%20See%20ya%20on%20the%20moon%21%0A%0A%23CallFi%20%23CallingIt`;
|
||||
window.open(twitterIntentURL, '_blank');
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (darkMode) {
|
||||
document.documentElement.classList.add("dark");
|
||||
|
|
@ -182,8 +200,8 @@ function Home() {
|
|||
<div className="note-card glassmorphism mb-4 p-4 text-center rounded-lg px-20 py-5">
|
||||
<h2 className="text-2xl font-bold mb-2">Feeling Lucky?</h2>
|
||||
<p className="text-lg mb-4">Make a callout to a token you believe in!!</p>
|
||||
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded glassmorphism">
|
||||
<a href="https://x.com/intent/tweet?text=%24COC%20is%20Booming%20rn%21%20See%20ya%20on%20the%20moon%21%0A%0A%23CallFi%20%23CallingIt" target="_blank" rel="noopener noreferrer">CALL OUT!</a>
|
||||
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded glassmorphism" onClick={openNewCallModal}>
|
||||
CALL OUT!
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -217,15 +235,18 @@ function Home() {
|
|||
<div className="w-full p-4 flex flex-col items-center justify-center">
|
||||
<div className="w-full max-w-4xl">
|
||||
{leaderboardData.map((item) => (
|
||||
<motion.div key ="id" whileHover={{scale:1.1, transition:{duration:0.2}}}>
|
||||
<div key={item["id"]} className={`leaderboard-card glassmorphism ${item["points"] >= 0 ? 'positive' : 'negative'} mx-auto mb-4`} onClick={() => openModal(item)}>
|
||||
<p className="text-center font-bold">{item["username"]}</p>
|
||||
<p className="text-center">{parseFloat(item["points"]).toFixed(2)}x</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
{/* Modal */}
|
||||
<Modal isOpen={modalOpen} onClose={closeModal} item={selectedItem} />
|
||||
<CalloutModal isOpen={newCallModalOpen} onClose={closeNewCallModal} onSubmit={handleNewCallSubmit} />
|
||||
|
||||
{/* Rest of your Home component */}
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 780 KiB After Width: | Height: | Size: 1.9 MiB |
BIN
public/black_backe.jpg
Normal file
BIN
public/black_backe.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.3 MiB |
BIN
public/black_backg.jpg
Normal file
BIN
public/black_backg.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 780 KiB |
BIN
public/black_backs.jpg
Normal file
BIN
public/black_backs.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 558 KiB |
Loading…
Reference in New Issue
Block a user