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
6 changes: 6 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ NEXT_PUBLIC_BACKEND_URL=https://crowdlaunch-backend.fly.dev
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=ddfjqustf
NEXT_PUBLIC_CLOUDINARY_API_KEY=928737954645779
NEXT_PUBLIC_ALCHEMY_API_KEY=9xeTvkkpEiR-PXbo-NmV12O3BkNWixrk
NEXT_PUBLIC_ETHERSCAN_API_KEY=CAM2IJY36H53V5MQGP4U6NGNYYH3ZUGBU2
NEXT_PUBLIC_SEPOLIA_PRIVATE_KEY=7bba322ef8f78463c19f6db542c5831ce83d80e02766c0b1dd8504a7e65a8b83
NEXT_PUBLIC_INFURA_API_KEY=8c2f0978d3394f98b1e3160bba2844ab
NEXT_PUBLIC_CONTRACT_ADDRESS=0xD7A00a83eF39E68931701C03B2B12762874498BA
NEXT_PUBLIC_IPFS_API_KEY=2V90hTdp8C9BmLgSpq2LPWn2skX
NEXT_PUBLIC_IPFS_SECRET_KEY=65c68d12c92db6731cacbf80e522c8a0
5 changes: 0 additions & 5 deletions contracts/abi/crowdfundContractABI.json
Original file line number Diff line number Diff line change
Expand Up @@ -446,11 +446,6 @@
"name": "backersCount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "reportCount",
"type": "uint256"
},
{
"internalType": "address payable",
"name": "depositAddress",
Expand Down
22 changes: 22 additions & 0 deletions contracts/scripts/deploy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const { ethers } = require('hardhat');

const CAMPAIGN_FEE = ethers.utils.parseEther('0.00001');
const NFT_LISTING_FEE = ethers.utils.parseEther('0.00001');

async function main() {
const [deployer] = await ethers.getSigners();

console.log('Deploying contracts with the account:', deployer.address);

const ContractFactory = await ethers.getContractFactory('CampaignContract');
const contract = await ContractFactory.deploy(CAMPAIGN_FEE, NFT_LISTING_FEE);

console.log('contract address:', contract.address);
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
1 change: 0 additions & 1 deletion contracts/structs/globalStructs.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ struct Campaign {
address payable creatorAddress;
uint256 backersCount;
Backer[] backers;
uint256 reportCount;
address payable depositAddress;
uint256[] dividendAmount;
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/tests/crowdfundTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ describe('CrowdfundContract Test', function () {
});

const campaignData = await contract.campaigns(user1.address);
accountContractAddress = campaignData[8];
accountContractAddress = campaignData[7];

expect(accountContractAddress.toString()).to.have.lengthOf(42);
});
Expand Down
20 changes: 19 additions & 1 deletion hardhat.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
/** @type import('hardhat/config').HardhatUserConfig */
// /** @type import('hardhat/config').HardhatUserConfig */
require('@nomiclabs/hardhat-ethers');
require('@nomiclabs/hardhat-waffle');
require('dotenv').config();

const {
NEXT_PUBLIC_ETHERSCAN_API_KEY,
NEXT_PUBLIC_SEPOLIA_PRIVATE_KEY,
NEXT_PUBLIC_INFURA_API_KEY,
} = process.env;

module.exports = {
solidity: '0.8.2',
defaultNetwork: 'sepolia',
plugins: [require('@nomiclabs/hardhat-waffle')],
etherscan: {
apikey: `${NEXT_PUBLIC_ETHERSCAN_API_KEY}`,
},
networks: {
hardhat: {},
sepolia: {
url: `https://sepolia.infura.io/v3/${NEXT_PUBLIC_INFURA_API_KEY}`,
accounts: [`${NEXT_PUBLIC_SEPOLIA_PRIVATE_KEY}`],
},
},
};
5 changes: 5 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ const nextConfig = {
'api.minimalavatars.com',
'media.graphassets.com',
'res.cloudinary.com',
'crowdlaunch.infura-ipfs.io',
'https://crowdlaunch.infura-ipfs.io/ipfs/QmW6rSCkA8sFAhryq2cC46xF2fcNfYyZpfzh3DQMK3b4jw',
'bafybeidtkspvxntvrbah2gr6z3fw2i5glpdgrqgqnmmaq2qx3xidaqfaky.ipfs.dweb.link',
'ipfsexplorer.online',
'https://ipfsexplorer.online/view/QmW6rSCkA8sFAhryq2cC46xF2fcNfYyZpfzh3DQMK3b4jw',
],
},
};
Expand Down
10 changes: 9 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
"lint": "next lint",
"deploy": "npx hardhat run contracts/scripts/deploy.js --network sepolia"
},
"dependencies": {
"@cloudinary/react": "^1.11.2",
Expand All @@ -22,6 +23,7 @@
"@rainbow-me/rainbowkit": "^1.0.8",
"@rainbow-me/rainbowkit-siwe-next-auth": "^0.3.0",
"@reduxjs/toolkit": "^1.9.5",
"@thirdweb-dev/react": "^3.14.40",
"@types/chai": "^4.3.5",
"@types/draft-js": "^0.11.12",
"@types/mocha": "^10.0.1",
Expand All @@ -35,16 +37,20 @@
"axios": "^1.4.0",
"chai": "^4.3.7",
"cloudinary-react": "^1.8.1",
"dotenv": "^16.3.1",
"draft-js": "^0.11.7",
"eslint": "8.43.0",
"eslint-config-next": "13.4.7",
"ethereum-waffle": "^4.0.10",
"ethers": "^5",
"file-loader": "^6.2.0",
"framer-motion": "^10.12.18",
"graphql": "^16.7.1",
"graphql-request": "^6.1.0",
"html-react-parser": "^4.2.0",
"html-to-image": "^1.11.11",
"image-to-base64": "^2.2.0",
"ipfs-http-client": "^60.0.1",
"lodash": "^4.17.21",
"lodash.debounce": "^4.0.8",
"moment": "^2.29.4",
Expand All @@ -63,6 +69,7 @@
"react-hook-form": "^7.45.1",
"react-icons": "^4.10.1",
"react-image-crop": "^10.1.5",
"react-ipfs-image": "^0.7.1",
"react-lottie": "^1.2.3",
"react-parallax-tilt": "^1.7.161",
"react-query": "^3.39.3",
Expand All @@ -80,6 +87,7 @@
"ts-node": "^10.9.1",
"tss-react": "^4.9.0",
"typescript": "5.1.3",
"url-loader": "^4.1.1",
"use-clipboard-copy": "^0.2.0",
"viem": "^1.6.4",
"wagmi": "^1.3.10"
Expand Down
2 changes: 1 addition & 1 deletion src/components/explore/exploreSearch/exploreSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const ExploreSearch = ({ fullWidth }: HeaderSearchTypes) => {

const handleSearchSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
console.log('Search term:', searchTerm);

setSearchTerm('');
};

Expand Down
18 changes: 7 additions & 11 deletions src/components/explore/projectCard/portfolioCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import useGetProjectById from '@/hooks/RequestHooks/GET/useGetProjectById';
import ProjectCardSkeleton from './projectCardSkeleton';
import { CURRENCY_SYMBOL } from '@/data/appInfo';
import { formatPriceValue } from '@/helpers/formatters';

interface ProjectCardTypes {
projectId: string;
Expand Down Expand Up @@ -44,26 +45,21 @@ const PortfolioCard = ({ projectId }: ProjectCardTypes) => {
)}
<h4 aria-label="project name">{project?.project?.projectName}</h4>
</ProjectTitle>
{/* <ProjectProgress>
{project?.project?.targetAmount &&
project?.project?.amountRaised && (
<ProgressBar
max={project.project.targetAmount}
value={project.project.amountRaised}
/>
)}
</ProjectProgress> */}
<ProjectInfo>
<div>
<h5>Min Investment</h5>
{project?.project?.minInvestment && (
<p>{`> ${project.project.minInvestment} ${CURRENCY_SYMBOL}`}</p>
<p>{`> ${formatPriceValue(
project.project.minInvestment
)} ${CURRENCY_SYMBOL}`}</p>
)}
</div>
<div>
<h5>Amount Raised</h5>
{project?.project?.amountRaised ? (
<p>{`${project.project.amountRaised.toLocaleString()} ${CURRENCY_SYMBOL}`}</p>
<p>{`${formatPriceValue(
project.project.amountRaised
)} ${CURRENCY_SYMBOL}`}</p>
) : (
project?.project?.amountRaised === 0 && (
<p>{`0 ${CURRENCY_SYMBOL}`}</p>
Expand Down
7 changes: 5 additions & 2 deletions src/components/explore/projectCard/projectCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import { ProgressBar } from '@/components/global';
import useGetCategoryById from '@/hooks/RequestHooks/GET/useGetCategoyById';
import { CURRENCY_SYMBOL } from '@/data/appInfo';
import { formatPriceValue } from '@/helpers/formatters';

interface ProjectCardTypes {
projectName: string;
Expand Down Expand Up @@ -59,12 +60,14 @@ const ProjectCard = ({
<ProjectInfo>
<div>
<h5>Min Investment</h5>
{minInvestment && <p>{`> ${minInvestment} ${CURRENCY_SYMBOL}`}</p>}
{minInvestment && (
<p>{`> ${formatPriceValue(minInvestment)} ${CURRENCY_SYMBOL}`}</p>
)}
</div>
<div>
<h5>Amount Raised</h5>
{amountRaised ? (
<p>{`${amountRaised.toLocaleString()} ${CURRENCY_SYMBOL}`}</p>
<p>{`${formatPriceValue(amountRaised)} ${CURRENCY_SYMBOL}`}</p>
) : (
amountRaised === 0 && <p>{`0 ${CURRENCY_SYMBOL}`}</p>
)}
Expand Down
12 changes: 12 additions & 0 deletions src/components/global/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { useRouter } from 'next/router';
import styled from 'styled-components';
import { QUERIES } from '@/styles/mediaQueries';
import { TransactionLoader } from '@/components/global';

export const ButtonContainer = styled.button`
display: inline-flex;
Expand Down Expand Up @@ -30,6 +31,10 @@ export const ButtonContainer = styled.button`
outline: none;
}

span {
margin-left: 8px;
}

@media ${QUERIES.mobile} {
height: 40px;
padding: 11px 12.703px 12px 17px;
Expand All @@ -41,13 +46,15 @@ interface ButtonTypes {
buttonType: 'link' | 'action';
buttonLink?: string;
buttonFunction?: () => void;
showLoader?: boolean;
}

const Button = ({
buttonTitle,
buttonType,
buttonLink,
buttonFunction,
showLoader,
}: ButtonTypes) => {
const router = useRouter();

Expand All @@ -62,6 +69,11 @@ const Button = ({
return (
<ButtonContainer onClick={handleButtonClick} type="button" role="button">
{buttonTitle}
{showLoader && (
<span>
<TransactionLoader />
</span>
)}
</ButtonContainer>
);
};
Expand Down
71 changes: 71 additions & 0 deletions src/components/global/countdown/timer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React, { useState, useEffect } from 'react';

interface TimeRemaining {
total: number;
days: number;
hours: number;
minutes: number;
seconds: number;
}

interface CountdownTimerProps {
startDate: string;
targetSeconds: number;
}

const Timer = ({ startDate, targetSeconds }: CountdownTimerProps) => {
const [timeRemaining, setTimeRemaining] = useState<TimeRemaining>(
calculateTimeRemaining(startDate, targetSeconds)
);

useEffect(() => {
const interval = setInterval(() => {
const newTimeRemaining = calculateTimeRemaining(startDate, targetSeconds);
setTimeRemaining(newTimeRemaining);

if (newTimeRemaining.total <= 0) {
clearInterval(interval);
}
}, 1000);

return () => clearInterval(interval);
}, [startDate, targetSeconds]);

const formattedTime = `${timeRemaining.days.toLocaleString()}d : ${timeRemaining.hours.toLocaleString()}h : ${timeRemaining.minutes.toLocaleString()}m : ${timeRemaining.seconds.toLocaleString()}s`;

return <h3>{formattedTime}</h3>;
};

function calculateTimeRemaining(
startDate: string,
targetSeconds: number
): TimeRemaining {
const now = new Date().getTime();
const targetDate = new Date(startDate).getTime() + targetSeconds * 1000; // Convert targetSeconds to milliseconds
const timeDiff = targetDate - now;

if (timeDiff <= 0) {
return {
total: 0,
days: 0,
hours: 0,
minutes: 0,
seconds: 0,
};
}

const seconds = Math.floor((timeDiff / 1000) % 60);
const minutes = Math.floor((timeDiff / (1000 * 60)) % 60);
const hours = Math.floor((timeDiff / (1000 * 60 * 60)) % 24);
const days = Math.floor(timeDiff / (1000 * 60 * 60 * 24));

return {
total: timeDiff,
days,
hours,
minutes,
seconds,
};
}

export default Timer;
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ const HeaderSearchBar = ({ fullWidth }: HeaderSearchTypes) => {

const handleSearchSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
console.log('Search term:', searchTerm);
setSearchTerm('');
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { shortenWalletAddress } from '@/helpers/formatters';
import { profileMenu } from '@/data/menuData';
import { useRouter } from 'next/router';
import { FaPowerOff } from 'react-icons/fa';
import usePostAuth from '@/hooks/RequestHooks/POST/usePostAuth';
import { CroppedImage } from '@/components/global';

interface UserMenuTypes {
Expand Down
4 changes: 4 additions & 0 deletions src/components/global/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import CustomSkeleton from '@/components/global/customSkeleton/customSkeleton';
import LottieImage from '@/components/global/lottieImage/lottieImage';
import CroppedImage from '@/components/global/images/croppedImage';
import BarcodeGenerator from '@/components/global/barcode/barcode';
import TransactionLoader from '@/components/global/loader/transactionLoader';
import Timer from '@/components/global/countdown/timer';

export {
Header,
Expand All @@ -30,4 +32,6 @@ export {
LottieImage,
CroppedImage,
BarcodeGenerator,
TransactionLoader,
Timer,
};
Loading