├── .gitignore ├── assests └── FundRaiser.png ├── client ├── src │ ├── favicon.jpeg │ ├── assets │ │ ├── thirdweb.png │ │ ├── menu.svg │ │ ├── type.svg │ │ ├── profile.svg │ │ ├── index.js │ │ ├── logout.svg │ │ ├── search.svg │ │ ├── dashboard.svg │ │ ├── logo.svg │ │ ├── payment.svg │ │ ├── favicon.svg │ │ ├── withdraw.svg │ │ ├── money.svg │ │ ├── sun.svg │ │ ├── create-campaign.svg │ │ └── loader.svg │ ├── components │ │ ├── ExpiredNotice.jsx │ │ ├── index.js │ │ ├── CustomButton.jsx │ │ ├── CountBox.jsx │ │ ├── Loader.jsx │ │ ├── FormField.jsx │ │ ├── DisplayCampaigns.jsx │ │ ├── CountdownTimer.jsx │ │ ├── Sidebar.jsx │ │ ├── FundCard.jsx │ │ └── Navbar.jsx │ ├── utils │ │ ├── DateTimeDisplay.jsx │ │ ├── index.js │ │ └── useCountdown.js │ ├── pages │ │ ├── index.js │ │ ├── Logout.jsx │ │ ├── Home.jsx │ │ ├── Profile.jsx │ │ ├── CreateCampaign.jsx │ │ ├── UpdateCampaign.jsx │ │ └── CampaignDetails.jsx │ ├── index.css │ ├── constants │ │ └── index.js │ ├── App.jsx │ ├── main.jsx │ └── context │ │ └── index.jsx ├── postcss.config.js ├── vite.config.js ├── .gitignore ├── index.html ├── tailwind.config.js ├── package.json ├── public │ └── index.html └── LICENSE.md ├── web3.0 ├── .gitignore ├── contracts │ ├── CampaignTypes.sol │ └── CrowdFunding.sol ├── package.json ├── hardhat.config.js ├── scripts │ ├── utils.js │ └── deploy.js ├── README.md └── test │ └── CrowdFunding.test.js ├── Documentation.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Local Netlify folder 2 | .netlify 3 | -------------------------------------------------------------------------------- /assests/FundRaiser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vishalparmarr/FundRaiser/HEAD/assests/FundRaiser.png -------------------------------------------------------------------------------- /client/src/favicon.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vishalparmarr/FundRaiser/HEAD/client/src/favicon.jpeg -------------------------------------------------------------------------------- /client/src/assets/thirdweb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vishalparmarr/FundRaiser/HEAD/client/src/assets/thirdweb.png -------------------------------------------------------------------------------- /client/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /web3.0/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | coverage 4 | coverage.json 5 | typechain 6 | typechain-types 7 | 8 | # Hardhat files 9 | cache 10 | artifacts 11 | 12 | -------------------------------------------------------------------------------- /client/src/assets/menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /client/src/components/ExpiredNotice.jsx: -------------------------------------------------------------------------------- 1 | const ExpiredNotice = () => { 2 | return ( 3 |
4 | Expired!!! 5 |

Please select a future date and time.

6 |
7 | ); 8 | }; -------------------------------------------------------------------------------- /web3.0/contracts/CampaignTypes.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | // defining pre-defined campaign types(Todo) 5 | enum CampaignTypes { 6 | Education, 7 | Entertainment, 8 | Defi, 9 | Game 10 | } -------------------------------------------------------------------------------- /client/vite.config.js: -------------------------------------------------------------------------------- 1 | import react from "@vitejs/plugin-react"; 2 | import { defineConfig } from "vite"; 3 | import { nodePolyfills } from "vite-plugin-node-polyfills"; 4 | 5 | export default defineConfig({ 6 | plugins: [react(), nodePolyfills()], 7 | define: { 8 | "process.env": {}, 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /client/src/utils/DateTimeDisplay.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const DateTimeDisplay = ({ value, type, isDanger }) => { 4 | return ( 5 |
6 |

{value}:{type}

7 |
8 | ); 9 | }; 10 | 11 | export default DateTimeDisplay; -------------------------------------------------------------------------------- /client/src/assets/type.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /client/src/pages/index.js: -------------------------------------------------------------------------------- 1 | export { default as Home } from './Home'; 2 | export { default as Profile } from './Profile'; 3 | export { default as CreateCampaign } from './CreateCampaign'; 4 | export { default as CampaignDetails } from './CampaignDetails'; 5 | export { default as UpdateCampaign } from './UpdateCampaign'; 6 | export { default as Logout } from './Logout'; -------------------------------------------------------------------------------- /web3.0/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hardhat-project", 3 | "devDependencies": { 4 | "@nomicfoundation/hardhat-toolbox": "^3.0.0", 5 | "@nomiclabs/hardhat-etherscan": "^3.1.7", 6 | "hardhat": "^2.16.1" 7 | }, 8 | "dependencies": { 9 | "@openzeppelin/contracts": "^4.9.2", 10 | "dotenv": "^16.3.1", 11 | "path": "^0.12.7" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | .env 15 | 16 | # Editor directories and files 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | 27 | #Contract Address 28 | /src/abis -------------------------------------------------------------------------------- /client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | FundRaiser 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /client/src/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as Sidebar } from './Sidebar'; 2 | export { default as Navbar } from './Navbar'; 3 | export { default as CustomButton } from './CustomButton'; 4 | export { default as FormField } from './FormField'; 5 | export { default as DisplayCampaigns } from './DisplayCampaigns'; 6 | export { default as FundCard } from './FundCard'; 7 | export { default as CountBox } from './CountBox'; 8 | export { default as Loader } from './Loader'; -------------------------------------------------------------------------------- /client/src/index.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Epilogue:wght@400;500;600;700&display=swap"); 2 | 3 | @tailwind base; 4 | @tailwind components; 5 | @tailwind utilities; 6 | 7 | .linear-gradient { 8 | background: linear-gradient( 9 | 179.14deg, 10 | rgba(32, 18, 63, 0) -7.14%, 11 | #000000 87.01% 12 | ); 13 | } 14 | 15 | input[type="date"]::-webkit-calendar-picker-indicator { 16 | cursor: pointer; 17 | filter: invert(0.8); 18 | } -------------------------------------------------------------------------------- /client/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | darkMode: 'class', 4 | content: [ 5 | "./index.html", 6 | "./src/**/*.{js,ts,jsx,tsx}", 7 | ], 8 | theme: { 9 | extend: { 10 | fontFamily: { 11 | epilogue: ['Epilogue', 'sans-serif'], 12 | }, 13 | boxShadow: { 14 | secondary: '10px 10px 20px rgba(2, 2, 2, 0.25)', 15 | }, 16 | }, 17 | }, 18 | plugins: [], 19 | } 20 | -------------------------------------------------------------------------------- /client/src/pages/Logout.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { ConnectWallet } from "@thirdweb-dev/react"; 3 | const Logout = () => { 4 | return ( 5 |
6 |
7 | 10 |
11 |
12 | ); 13 | }; 14 | 15 | export default Logout; 16 | -------------------------------------------------------------------------------- /client/src/components/CustomButton.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const CustomButton = ({ btnType, title, handleClick, styles }) => { 4 | return ( 5 | 13 | ) 14 | } 15 | 16 | export default CustomButton -------------------------------------------------------------------------------- /Documentation.md: -------------------------------------------------------------------------------- 1 | # FrameWorks:- 2 | 3 | Third Web 4 | React.js 5 | Tailwind CSS 6 | Smart Contract on Ethereum Network 7 | 8 | ## Commands:- 9 | 10 | Thirdweb init - npx thirdweb@latest create --contract 11 | For Security - npm install dotenv 12 | Compile and deploy - npm run deploy 13 | 14 | Creating react app - npx thirdweb create --app 15 | Connect to Router - npm install react-router-dom 16 | 17 | Installing Tailwind CSS - npm install -D tailwindcss postcss autoprefixer 18 | Initiallization - npx tailwindcss init 19 | -------------------------------------------------------------------------------- /client/src/assets/profile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /client/src/components/CountBox.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const CountBox = ({ title, value }) => { 4 | return ( 5 |
6 |

{value}

7 |

{title}

8 |
9 | ) 10 | } 11 | 12 | export default CountBox -------------------------------------------------------------------------------- /client/src/components/Loader.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import { loader } from '../assets'; 4 | 5 | const Loader = () => { 6 | return ( 7 |
8 | loader 9 |

Transaction is in progress
Please wait...

10 |
11 | ) 12 | } 13 | 14 | export default Loader -------------------------------------------------------------------------------- /web3.0/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomicfoundation/hardhat-toolbox"); 2 | require("@nomicfoundation/hardhat-verify"); 3 | const path = require('path'); 4 | require('dotenv').config({path: path.resolve(__dirname, './.env')}); 5 | 6 | /** @type import('hardhat/config').HardhatUserConfig */ 7 | module.exports = { 8 | solidity: "0.8.19", 9 | networks: { 10 | sepolia : { 11 | url: "https://sepolia.rpc.thirdweb.com", 12 | accounts: [process.env.PRIVATE_KEY] 13 | }, 14 | hardhat: { 15 | } 16 | }, 17 | etherscan: { 18 | apiKey: process.env.EtherScan_API, 19 | }, 20 | 21 | }; 22 | -------------------------------------------------------------------------------- /client/src/utils/index.js: -------------------------------------------------------------------------------- 1 | export const daysLeft = (deadline) => { 2 | const difference = new Date(deadline).getTime() - Date.now(); 3 | const remainingDays = difference / (1000 * 3600 * 24); 4 | 5 | return remainingDays.toFixed(0); 6 | }; 7 | 8 | export const calculateBarPercentage = (goal, raisedAmount) => { 9 | const percentage = Math.round((raisedAmount * 100) / goal); 10 | 11 | return percentage; 12 | }; 13 | 14 | export const checkIfImage = (url, callback) => { 15 | const img = new Image(); 16 | img.src = url; 17 | 18 | if (img.complete) callback(true); 19 | 20 | img.onload = () => callback(true); 21 | img.onerror = () => callback(false); 22 | }; -------------------------------------------------------------------------------- /client/src/assets/index.js: -------------------------------------------------------------------------------- 1 | import createCampaign from './create-campaign.svg'; 2 | import dashboard from './dashboard.svg'; 3 | import logo from './logo.svg'; 4 | import logout from './logout.svg'; 5 | import payment from './payment.svg'; 6 | import profile from './profile.svg'; 7 | import sun from './sun.svg'; 8 | import withdraw from './withdraw.svg'; 9 | import tagType from './type.svg'; 10 | import search from './search.svg'; 11 | import menu from './menu.svg'; 12 | import money from './money.svg'; 13 | import loader from './loader.svg'; 14 | import thirdweb from './thirdweb.png'; 15 | 16 | export { 17 | tagType, 18 | createCampaign, 19 | dashboard, 20 | logo, 21 | logout, 22 | payment, 23 | profile, 24 | sun, 25 | withdraw, 26 | search, 27 | menu, 28 | money, 29 | loader, 30 | thirdweb, 31 | }; 32 | -------------------------------------------------------------------------------- /client/src/assets/logout.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /client/src/pages/Home.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react' 2 | 3 | import { DisplayCampaigns } from '../components'; 4 | import { useStateContext } from '../context' 5 | 6 | const Home = () => { 7 | const [isLoading, setIsLoading] = useState(false); 8 | const [campaigns, setCampaigns] = useState([]); 9 | 10 | const { address, contract, getCampaigns } = useStateContext(); 11 | 12 | const fetchCampaigns = async () => { 13 | setIsLoading(true); 14 | const data = await getCampaigns(); 15 | setCampaigns(data); 16 | setIsLoading(false); 17 | } 18 | 19 | useEffect(() => { 20 | if(contract) fetchCampaigns(); 21 | }, [address, contract]); 22 | 23 | return ( 24 | 29 | ) 30 | } 31 | 32 | export default Home -------------------------------------------------------------------------------- /client/src/pages/Profile.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react' 2 | 3 | import { DisplayCampaigns } from '../components'; 4 | import { useStateContext } from '../context' 5 | 6 | const Profile = () => { 7 | const [isLoading, setIsLoading] = useState(false); 8 | const [campaigns, setCampaigns] = useState([]); 9 | 10 | const { address, contract, getUserCampaigns } = useStateContext(); 11 | 12 | const fetchCampaigns = async () => { 13 | setIsLoading(true); 14 | const data = await getUserCampaigns(); 15 | setCampaigns(data); 16 | setIsLoading(false); 17 | } 18 | 19 | useEffect(() => { 20 | if(contract) fetchCampaigns(); 21 | }, [address, contract]); 22 | 23 | return ( 24 | 29 | ) 30 | } 31 | 32 | export default Profile -------------------------------------------------------------------------------- /client/src/constants/index.js: -------------------------------------------------------------------------------- 1 | import { createCampaign, dashboard, logout, payment, profile, withdraw } from '../assets'; 2 | 3 | export const navlinks = [ 4 | { 5 | name: 'Home', 6 | imgUrl: dashboard, 7 | link: '/', 8 | id: 0 9 | }, 10 | { 11 | name: 'Start campaign', 12 | imgUrl: createCampaign, 13 | link: '/create-campaign', 14 | id: 1 15 | }, 16 | { 17 | name: 'Edit campaign', 18 | imgUrl: payment, 19 | link: '/', 20 | // disabled: true, 21 | id: 2 22 | }, 23 | { 24 | name: 'Withdraw', 25 | imgUrl: withdraw, 26 | link: '/', 27 | // disabled: true, 28 | id: 3 29 | }, 30 | { 31 | name: 'Profile', 32 | imgUrl: profile, 33 | link: '/profile', 34 | id: 4 35 | }, 36 | { 37 | name: 'Logout', 38 | imgUrl: logout, 39 | link: '/logout', 40 | // disabled: true, 41 | id: 5 42 | }, 43 | ]; -------------------------------------------------------------------------------- /web3.0/scripts/utils.js: -------------------------------------------------------------------------------- 1 | const hre = require("hardhat"); 2 | 3 | async function waitForTargetBlock(confirmations) { 4 | const WAIT_BLOCK_CONFIRMATIONS = confirmations; 5 | const provider = hre.ethers.provider; 6 | let currentBlockNumber; 7 | 8 | await provider.getBlockNumber().then((blockNumber) => { 9 | currentBlockNumber = blockNumber; 10 | }); 11 | 12 | const targetBlockNumber = currentBlockNumber + WAIT_BLOCK_CONFIRMATIONS; 13 | 14 | return new Promise((resolve, reject) => { 15 | provider.on("block", (blockNumber) => { 16 | console.log(`Waiting to get target block(${WAIT_BLOCK_CONFIRMATIONS} blocks wait):`, blockNumber); 17 | if(blockNumber == targetBlockNumber) { 18 | console.log("Done:", blockNumber); 19 | provider.off("block"); 20 | resolve(blockNumber); 21 | } 22 | reject("Error in getting block number"); 23 | }) 24 | }) 25 | } 26 | 27 | module.exports = waitForTargetBlock; -------------------------------------------------------------------------------- /client/src/assets/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /client/src/utils/useCountdown.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | 3 | const useCountdown = (targetDate) => { 4 | const countDownDate = new Date(targetDate).getTime(); 5 | 6 | const [countDown, setCountDown] = useState( 7 | countDownDate - new Date().getTime() 8 | ); 9 | 10 | useEffect(() => { 11 | const interval = setInterval(() => { 12 | setCountDown(countDownDate - new Date().getTime()); 13 | }, 1000); 14 | 15 | return () => clearInterval(interval); 16 | }, [countDownDate]); 17 | 18 | return getReturnValues(countDown); 19 | }; 20 | 21 | const getReturnValues = (countDown) => { 22 | // calculate time left 23 | const days = Math.floor(countDown / (1000 * 60 * 60 * 24)); 24 | const hours = Math.floor( 25 | (countDown % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60) 26 | ); 27 | const minutes = Math.floor((countDown % (1000 * 60 * 60)) / (1000 * 60)); 28 | const seconds = Math.floor((countDown % (1000 * 60)) / 1000); 29 | 30 | return [days, hours, minutes, seconds]; 31 | }; 32 | 33 | export { useCountdown }; -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite --host --port 8888", 7 | "build": "vite build", 8 | "preview": "vite preview", 9 | "deploy": "yarn build && npx thirdweb@latest upload dist", 10 | "host": "--host" 11 | }, 12 | "dependencies": { 13 | "@clerk/clerk-react": "^4.30.5", 14 | "@clerk/themes": "^1.7.9", 15 | "@thirdweb-dev/auth": "^4.1.35", 16 | "@thirdweb-dev/react": "^3.16.5", 17 | "@thirdweb-dev/sdk": "^3.10.67", 18 | "axios": "^1.6.7", 19 | "dotenv": "^16.4.5", 20 | "ethers": "^5.7.2", 21 | "react": "^18.2.0", 22 | "react-dom": "^18.2.0", 23 | "react-router-dom": "^6.4.4", 24 | "react-toastify": "^10.0.4", 25 | "semantic-ui-react": "^2.1.5", 26 | "zod-error": "^1.5.0" 27 | }, 28 | "devDependencies": { 29 | "@vitejs/plugin-react": "^2.2.0", 30 | "autoprefixer": "^10.4.13", 31 | "postcss": "^8.4.19", 32 | "tailwindcss": "^3.2.4", 33 | "vite": "^3", 34 | "vite-plugin-node-polyfills": "^0.21.0" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /client/src/App.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Route, Routes } from 'react-router-dom'; 3 | 4 | import { Sidebar, Navbar } from './components'; 5 | import { CampaignDetails, CreateCampaign, UpdateCampaign, Home, Profile, Logout } from './pages'; 6 | 7 | const App = () => { 8 | return ( 9 |
10 |
11 | 12 |
13 | 14 |
15 | 16 | 17 | 18 | } /> 19 | } /> 20 | } /> 21 | } /> 22 | } /> 23 | } /> 24 | 25 |
26 |
27 | ) 28 | } 29 | 30 | export default App -------------------------------------------------------------------------------- /client/src/assets/dashboard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /client/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /client/src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import { BrowserRouter as Router } from "react-router-dom"; 4 | import { 5 | ThirdwebProvider, 6 | metamaskWallet, 7 | coinbaseWallet, 8 | walletConnect, 9 | localWallet, 10 | embeddedWallet, 11 | } from "@thirdweb-dev/react"; 12 | import { Sepolia } from "@thirdweb-dev/chains"; 13 | 14 | import { StateContextProvider } from "./context"; 15 | import App from "./App"; 16 | import "./index.css"; 17 | 18 | const root = ReactDOM.createRoot(document.getElementById("root")); 19 | 20 | root.render( 21 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | ); 43 | -------------------------------------------------------------------------------- /client/src/assets/payment.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /client/src/components/FormField.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const FormField = ({ labelName, placeholder, inputType, isTextArea, value, handleChange }) => { 4 | return ( 5 |