Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 19 additions & 22 deletions frontend/src/pages/AboutPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ const additionalFeatures = [
const AboutPage = () => {
return (
<>
<section className="min-h-screen w-full bg-gradient-to-b from-[#252550] to-[#1A1A1A] text-white flex flex-col justify-center items-center p-6 overflow-hidden">
<section className="min-h-screen w-full bg-gradient-to-b from-purple-100 to-white dark:from-[#252550] dark:to-[#1A1A1A] text-gray-800 dark:text-white flex flex-col justify-center items-center p-6 overflow-hidden transition-colors duration-300">
<div className="p-10 about-main-div rounded-lg shadow-lg max-w-6xl mx-auto mt-12 w-full sm:w-11/12">
<motion.h1
className="text-4xl sm:text-6xl font-bold mb-6 animate-pulse text-center"
className="text-4xl sm:text-6xl font-bold mb-6 text-center bg-gradient-to-r from-purple-600 to-blue-600 dark:from-[#47B7FF] dark:to-[#CA35FF] bg-clip-text text-transparent"
initial={{ opacity: 0, y: -50 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
Expand All @@ -113,24 +113,22 @@ const AboutPage = () => {
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 1.2 }}
>
DecenTrade is a decentralized digital marketplace built
on the Ethereum blockchain, empowering users to engage
in secure and transparent transactions for digital
assets.
DecenTrade is a decentralized digital marketplace built on the Ethereum blockchain,
empowering users to engage in secure and transparent transactions for digital assets.
</motion.p>

<div className="grid grid-cols-1 md:grid-cols-2 gap-8 max-w-5xl mx-auto">
{features.map((feature) => (
<motion.div
key={feature.id} // Use unique ID as key
className="bg-gradient-to-r from-[#47B7FF] to-[#CA35FF] p-6 rounded-lg shadow-lg hover:shadow-xl transform transition duration-100 glassmorphism flex flex-col justify-between h-full"
key={feature.id}
className="bg-gradient-to-r from-purple-400 to-blue-400 dark:from-[#47B7FF] dark:to-[#CA35FF] p-6 rounded-lg shadow-lg hover:shadow-xl transform transition duration-100 backdrop-blur-sm bg-opacity-20 dark:bg-opacity-20 flex flex-col justify-between h-full"
whileHover={{ scale: 1.05 }}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.2 }}
>
<h3 className="text-2xl font-bold mb-2">
{feature.icon} {feature.title}
{feature.title}
</h3>
<p className="flex-grow">
{feature.description}
Expand All @@ -141,16 +139,17 @@ const AboutPage = () => {
</div>

<div className="max-w-4xl mx-auto text-center mt-12">
<h2 className="text-4xl font-bold mb-6">Our Vision</h2>
<h2 className="text-4xl font-bold mb-6 bg-gradient-to-r from-purple-600 to-blue-600 dark:from-[#47B7FF] dark:to-[#CA35FF] bg-clip-text text-transparent">
Our Vision
</h2>
<motion.p
className="text-lg mb-4 leading-relaxed"
initial={{ opacity: 0, y: 50 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 1.5 }}
>
At DecenTrade, we envision a world where digital assets
are easily accessible, allowing everyone to participate
in the digital economy.
At DecenTrade, we envision a world where digital assets are easily accessible,
allowing everyone to participate in the digital economy.
</motion.p>

<motion.p
Expand All @@ -159,21 +158,20 @@ const AboutPage = () => {
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 1.8 }}
>
Our mission is to create a secure, transparent, and
user-friendly platform for trading various digital
assets, empowering creators and collectors alike.
Our mission is to create a secure, transparent, and user-friendly platform for
trading various digital assets, empowering creators and collectors alike.
</motion.p>
</div>

<div className="max-w-5xl mx-auto mt-12">
<h2 className="text-4xl font-bold mb-6 text-center">
<h2 className="text-4xl font-bold mb-6 text-center bg-gradient-to-r from-purple-600 to-blue-600 dark:from-[#47B7FF] dark:to-[#CA35FF] bg-clip-text text-transparent">
Why Choose Us?
</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{additionalFeatures.map((item) => (
<motion.div
key={item.id} // Use unique ID as key
className="bg-gradient-to-r from-[#9F10B2] to-[#541C82] p-6 rounded-lg shadow-lg transform hover:scale-105 transition duration-100 glassmorphism"
key={item.id}
className="bg-gradient-to-r from-purple-300 to-blue-300 dark:from-[#9F10B2] dark:to-[#541C82] p-6 rounded-lg shadow-lg transform hover:scale-105 transition duration-100 backdrop-blur-sm bg-opacity-20 dark:bg-opacity-20"
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.2 }}
Expand All @@ -188,9 +186,8 @@ const AboutPage = () => {
</div>
</div>
</section>

</>
)
}
);
};

export default AboutPage
166 changes: 116 additions & 50 deletions frontend/src/pages/CreateNFTPage.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,84 @@
import React, { useState } from 'react'
import PropTypes from 'prop-types'
import { connectWallet, createNFT } from '../utils/ethereum'
import { ethers } from 'ethers'
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { motion, AnimatePresence } from 'framer-motion';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faSun, faMoon } from '@fortawesome/free-solid-svg-icons';
import { connectWallet, createNFT } from '../utils/ethereum';

const nftAddress = import.meta.env.VITE_NFT_ADDRESS
const marketplaceAddress = import.meta.env.VITE_MARKET_ADDRESS
const ThemeToggle = ({ className }) => {
const [darkMode, setDarkMode] = useState(false);

const toggleDarkMode = () => {
setDarkMode((prevMode) => !prevMode);
document.body.classList.toggle('dark', !darkMode);
};

useEffect(() => {
const savedMode = localStorage.getItem('darkMode') === 'true';
setDarkMode(savedMode);
document.body.classList.toggle('dark', savedMode);
}, []);

useEffect(() => {
localStorage.setItem('darkMode', darkMode);
}, [darkMode]);

return (
<motion.div
onClick={toggleDarkMode}
className={`relative w-24 h-12 rounded-full cursor-pointer flex items-center px-2 ${
darkMode ? 'bg-[#002855]' : 'bg-[#FFD966]'
} ${className}`}
layout
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5 }}
>
<AnimatePresence>
{darkMode ? (
<motion.div
key="moon"
initial={{ x: -40, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
exit={{ x: 40, opacity: 0 }}
transition={{ duration: 0.5 }}
className="absolute left-1 text-blue-400"
>
<FontAwesomeIcon icon={faMoon} size="lg" />
</motion.div>
) : (
<motion.div
key="sun"
initial={{ x: 40, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
exit={{ x: -40, opacity: 0 }}
transition={{ duration: 0.5 }}
className="absolute right-1 text-yellow-500"
>
<FontAwesomeIcon icon={faSun} size="lg" />
</motion.div>
)}
</AnimatePresence>

<motion.div
className="w-10 h-10 bg-white rounded-full shadow-md"
layout
transition={{ type: 'spring', stiffness: 700, damping: 30 }}
style={{
x: darkMode ? '100%' : '0%',
}}
></motion.div>
</motion.div>
);
};

const CreateNFT = ({ wallet }) => {
const [formData, setFormData] = useState({
name: '',
description: '',
price: '',
file: null,
})
});
const [dragging, setDragging] = useState(false);

const handleChange = (e) => {
Expand All @@ -21,91 +87,87 @@ const CreateNFT = ({ wallet }) => {
...prevState,
[name]: files ? files[0] : value,
}));
}
};

const handleDragOver = (e) => {
e.preventDefault();
if (!dragging) setDragging(true); // Prevent unnecessary reassignments
}
if (!dragging) setDragging(true);
};

const handleDragLeave = () => {
if (dragging) setDragging(false); // Prevent unnecessary reassignments
}
if (dragging) setDragging(false);
};

const handleDrop = (e) => {
e.preventDefault();
setDragging(false);
const droppedFiles = e.dataTransfer.files;

if (droppedFiles && droppedFiles[0]) {
setFormData((prevState) => ({
...prevState,
file: droppedFiles[0],
}));
}
}
};

const handleFileChange = (e) => {
const file = e.target.files[0];
setFormData((prevState) => ({
...prevState,
file: file,
}));
}
};

const handleCancelFile = () => {
setFormData((prevState) => ({
...prevState,
file: null,
}));
}
};

const handleSubmit = async (e) => {
e.preventDefault()

e.preventDefault();
try {
const { name, description, price, file } = formData

const { name, description, price, file } = formData;
if (!name || !description || !price || !file) {
throw new Error('All fields are required')
throw new Error('All fields are required');
}

const signer = await connectWallet()

const signer = await connectWallet();
try {
const tokenId = await createNFT(
signer,
name,
description,
price,
file,
nftAddress,
marketplaceAddress
)
console.log('NFT created and listed with token ID:', tokenId)
import.meta.env.VITE_NFT_ADDRESS,
import.meta.env.VITE_MARKET_ADDRESS
);
console.log('NFT created and listed with token ID:', tokenId);
} catch (error) {
console.error('Failed to create and list NFT:', error)
console.error('Failed to create and list NFT:', error);
}
} catch (error) {
console.error('Error creating NFT:', error)
console.error('Error creating NFT:', error);
}
}
};

return (
<div className="flex justify-center items-center min-h-screen bg-gradient-to-r from-gray-900 via-purple-900 to-black overflow-hidden">
<div
className="text-white shadow-2xl rounded-lg p-10 mt-10 mb-10 max-w-2xl w-full mx-4 transform transition-all duration-300 hover:scale-105 hover:shadow-3xl"
<div className="flex justify-center items-center min-h-screen bg-gradient-to-r from-purple-100 via-purple-200 to-white dark:from-gray-900 dark:via-purple-900 dark:to-black overflow-hidden transition-colors duration-300">
<motion.div
className="text-gray-900 dark:text-white shadow-2xl rounded-lg p-10 mt-10 mb-10 max-w-2xl w-full mx-4 relative transform transition-all duration-300 hover:scale-105 hover:shadow-3xl"
style={{
background: 'linear-gradient(to bottom right, #252550 20%, #ff00ff 100%)',
background: 'var(--form-bg)',
}}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onDrop={handleDrop}
role="button"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
<h1 className="text-4xl font-bold text-center text-white mb-6">

<h1 className="text-4xl font-bold text-center mb-6">
CREATE NFT
</h1>

<form onSubmit={handleSubmit} className="space-y-6">
<div>
<label
Expand All @@ -125,6 +187,7 @@ const CreateNFT = ({ wallet }) => {
className="w-full p-3 border-none rounded-lg shadow-sm bg-white text-black focus:outline-none focus:ring-2 focus:ring-purple-500 transition"
/>
</div>

<div>
<label
htmlFor="description"
Expand All @@ -141,8 +204,9 @@ const CreateNFT = ({ wallet }) => {
required
className="w-full p-3 border-none rounded-lg shadow-sm bg-white text-black focus:outline-none focus:ring-2 focus:ring-purple-500 transition resize-none"
rows="4"
></textarea>
/>
</div>

<div>
<label
htmlFor="price"
Expand All @@ -162,6 +226,7 @@ const CreateNFT = ({ wallet }) => {
className="w-full p-3 border-none rounded-lg shadow-sm bg-white text-black focus:outline-none focus:ring-2 focus:ring-purple-500 transition"
/>
</div>

<div>
<label
htmlFor="file"
Expand All @@ -176,7 +241,7 @@ const CreateNFT = ({ wallet }) => {
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onDrop={handleDrop}
role="button"
role="button"
>
{formData.file ? (
<div className="flex justify-between items-center">
Expand All @@ -190,34 +255,35 @@ const CreateNFT = ({ wallet }) => {
</button>
</div>
) : (
<div className="flex items-center">
<div className="flex items-center">
<p className="text-gray-500">Drag And Drop File Or</p>
<input
type="file"
id="file"
name="file"
onChange={handleFileChange}
required
className="cursor-pointer ml-1"
className="cursor-pointer ml-1"
/>
</div>
)}
</div>
</div>

<button
type="submit"
className="w-full bg-purple-800 hover:bg-purple-900 text-white font-bold py-3 rounded-lg transition"
className="w-full bg-purple-600 dark:bg-purple-800 hover:bg-purple-700 dark:hover:bg-purple-900 text-white font-bold py-3 rounded-lg transition"
>
Create NFT
</button>
</form>
</div>
</motion.div>
</div>
)
}
);
};

CreateNFT.propTypes = {
wallet: PropTypes.object.isRequired,
}
};

export default CreateNFT
export default CreateNFT;
Loading