diff --git a/.env.example b/.env.example index d478406..673f932 100644 --- a/.env.example +++ b/.env.example @@ -5,12 +5,10 @@ DATABASE_URL= NEXT_PUBLIC_LH_API= NEXT_PUBLIC_WEB_TOKEN= - NEXT_PUBLIC_PARTICLE_NETWORK_PROJECT_ID= NEXT_PUBLIC_PARTICLE_NETWORK_CLIENT_KEY= NEXT_PUBLIC_PARTICLE_NETWORK_APP_ID= - NEXT_PUBLIC_PAYMENT_CONTRACT_ADDRESS= NEXT_PUBLIC_WALLET_CONTRACT_ADDRESS= diff --git a/.github/ISSUE_TEMPLATE/0-task.yml b/.github/ISSUE_TEMPLATE/0-task.yml index 1df4f1c..10c07e7 100644 --- a/.github/ISSUE_TEMPLATE/0-task.yml +++ b/.github/ISSUE_TEMPLATE/0-task.yml @@ -1,6 +1,6 @@ name: Task -title: "task: " -description: Create a task for the project +title: 'task: ' +description: Create a task for the project labels: ['task'] body: @@ -14,14 +14,14 @@ body: label: Task description description: A clear and concise description of the task value: | - - [ ] + - [ ] validations: required: true - type: input - attributes: + attributes: label: Related Issues placeholder: | Relates #21 validations: - required: false \ No newline at end of file + required: false diff --git a/.github/ISSUE_TEMPLATE/10-proposal.yml b/.github/ISSUE_TEMPLATE/10-proposal.yml index 430e38d..d338d7c 100644 --- a/.github/ISSUE_TEMPLATE/10-proposal.yml +++ b/.github/ISSUE_TEMPLATE/10-proposal.yml @@ -3,8 +3,7 @@ description: Submit a proposal for consideration title: 'proposal: ' labels: ['proposal'] - -body: +body: - type: markdown attributes: value: | @@ -39,9 +38,7 @@ body: id: additional-info attributes: label: Additional Information - description: Include any additional information or references that support the proposal. + description: + Include any additional information or references that support the proposal. validations: required: false - - - \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/2-feature-request.yml b/.github/ISSUE_TEMPLATE/2-feature-request.yml index aae4b62..c3796c9 100644 --- a/.github/ISSUE_TEMPLATE/2-feature-request.yml +++ b/.github/ISSUE_TEMPLATE/2-feature-request.yml @@ -1,18 +1,18 @@ name: Feature request description: Suggest an idea for this project title: 'feature-request:' -labels: ['enhancement','feature-request','feature'] +labels: ['enhancement', 'feature-request', 'feature'] assignees: ['Nasfame'] -body: +body: - type: markdown attributes: value: | ## Feature Request Thanks for helping us improve! 🙏 Please follow the sections in the template and provide as much information. - + - type: input - attributes: + attributes: label: Related Issues placeholder: | Relates #21 @@ -39,9 +39,7 @@ body: id: additional-info attributes: label: Additional Information - description: Include any additional information or references that support the proposal. + description: + Include any additional information or references that support the proposal. validations: required: false - - - \ No newline at end of file diff --git a/hardhat/README.md b/hardhat/README.md index e7bed2a..a4a5638 100644 --- a/hardhat/README.md +++ b/hardhat/README.md @@ -2,14 +2,18 @@ ## Overview -This repository serves as a template for web3 developers to kickstart their decentralized application (Dapp) development using Hardhat. Hardhat is a popular Ethereum development environment that makes it easy to compile, deploy, and test your smart contracts. +This repository serves as a template for web3 developers to kickstart their decentralized +application (Dapp) development using Hardhat. Hardhat is a popular Ethereum development +environment that makes it easy to compile, deploy, and test your smart contracts. ## Features - **Ready-to-Use**: Clone this repository, and you're ready to start building your Dapp. - **Smart Contract Development**: Write, compile, and deploy smart contracts effortlessly. -- **Testing**: Includes a testing environment with sample tests to ensure your contracts function as expected. -- **Deployment Scripts**: Simple scripts for deploying your smart contracts to various Ethereum networks. +- **Testing**: Includes a testing environment with sample tests to ensure your contracts + function as expected. +- **Deployment Scripts**: Simple scripts for deploying your smart contracts to various + Ethereum networks. ## Getting Started @@ -24,6 +28,8 @@ This repository serves as a template for web3 developers to kickstart their dece npm run build npm run test:local:dev ``` + ## Advanced Setup -1. Install [Release Drafter](https://github.com/apps/release-drafter/installations/select_target) \ No newline at end of file +1. Install + [Release Drafter](https://github.com/apps/release-drafter/installations/select_target) diff --git a/hardhat/docker-compose.yml b/hardhat/docker-compose.yml index 8971588..4be18ca 100644 --- a/hardhat/docker-compose.yml +++ b/hardhat/docker-compose.yml @@ -1,4 +1,4 @@ -version: "3.8" +version: '3.8' services: app: env_file: diff --git a/hardhat/hardhat.config.ts b/hardhat/hardhat.config.ts index 6bb3614..19d8d1a 100644 --- a/hardhat/hardhat.config.ts +++ b/hardhat/hardhat.config.ts @@ -1,28 +1,28 @@ -import { HardhatUserConfig } from "hardhat/config"; -import "@nomicfoundation/hardhat-toolbox"; +import { HardhatUserConfig } from 'hardhat/config' +import '@nomicfoundation/hardhat-toolbox' -import dotenv from "dotenv"; +import dotenv from 'dotenv' -dotenv.config(); +dotenv.config() const config: HardhatUserConfig = { - defaultNetwork: "local", + defaultNetwork: 'local', networks: { // Add your network configurations here sepolia: { url: `https://sepolia.infura.io/v3/${process.env.INFURA_PROJECT_ID}`, - accounts: [process.env.PRIVATE_KEY ?? ""], + accounts: [process.env.PRIVATE_KEY ?? ''], }, mumbai: { url: `https://polygon-mumbai.infura.io/v3/${process.env.INFURA_PROJECT_ID}`, - accounts: [process.env.PRIVATE_KEY ?? ""], + accounts: [process.env.PRIVATE_KEY ?? ''], }, local: { - url: "http://127.0.0.1:8545", + url: 'http://127.0.0.1:8545', }, }, solidity: { - version: "0.8.22", + version: '0.8.22', settings: { optimizer: { enabled: true, @@ -31,14 +31,14 @@ const config: HardhatUserConfig = { }, }, paths: { - sources: "./contracts", - tests: "./test", - cache: "./cache", - artifacts: "./artifacts", + sources: './contracts', + tests: './test', + cache: './cache', + artifacts: './artifacts', }, mocha: { timeout: 40000, }, -}; +} -export default config; +export default config diff --git a/hardhat/scripts/deploy.ts b/hardhat/scripts/deploy.ts index b8d1664..34e03ae 100644 --- a/hardhat/scripts/deploy.ts +++ b/hardhat/scripts/deploy.ts @@ -1,28 +1,28 @@ -import { ethers } from "hardhat"; -import { config } from "dotenv"; +import { ethers } from 'hardhat' +import { config } from 'dotenv' async function main() { - const currentTimestampInSeconds = Math.round(Date.now() / 1000); - const unlockTime = currentTimestampInSeconds + 60; + const currentTimestampInSeconds = Math.round(Date.now() / 1000) + const unlockTime = currentTimestampInSeconds + 60 - const lockedAmount = ethers.parseEther("0.001"); + const lockedAmount = ethers.parseEther('0.001') - const lock = await ethers.deployContract("Lock", [unlockTime], { + const lock = await ethers.deployContract('Lock', [unlockTime], { value: lockedAmount, - }); + }) - await lock.waitForDeployment(); + await lock.waitForDeployment() console.log( `Lock with ${ethers.formatEther( - lockedAmount - )}ETH and unlock timestamp ${unlockTime} deployed to ${lock.target}` - ); + lockedAmount, + )}ETH and unlock timestamp ${unlockTime} deployed to ${lock.target}`, + ) } // We recommend this pattern to be able to use async/await everywhere // and properly handle errors. main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); + console.error(error) + process.exitCode = 1 +}) diff --git a/hardhat/test/sample/Lock.ts b/hardhat/test/sample/Lock.ts index a6e866b..065745d 100644 --- a/hardhat/test/sample/Lock.ts +++ b/hardhat/test/sample/Lock.ts @@ -1,127 +1,116 @@ -import { - time, - loadFixture, -} from "@nomicfoundation/hardhat-toolbox/network-helpers"; -import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; -import { expect } from "chai"; -import { ethers } from "hardhat"; - -describe("Lock", function () { +import { time, loadFixture } from '@nomicfoundation/hardhat-toolbox/network-helpers' +import { anyValue } from '@nomicfoundation/hardhat-chai-matchers/withArgs' +import { expect } from 'chai' +import { ethers } from 'hardhat' + +describe('Lock', function () { // We define a fixture to reuse the same setup in every test. // We use loadFixture to run this setup once, snapshot that state, // and reset Hardhat Network to that snapshot in every test. async function deployOneYearLockFixture() { - const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; - const ONE_GWEI = 1_000_000_000; + const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60 + const ONE_GWEI = 1_000_000_000 - const lockedAmount = ONE_GWEI; - const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; + const lockedAmount = ONE_GWEI + const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS // Contracts are deployed using the first signer/account by default - const [owner, otherAccount] = await ethers.getSigners(); + const [owner, otherAccount] = await ethers.getSigners() - const Lock = await ethers.getContractFactory("Lock"); - const lock = await Lock.deploy(unlockTime, { value: lockedAmount }); + const Lock = await ethers.getContractFactory('Lock') + const lock = await Lock.deploy(unlockTime, { value: lockedAmount }) - return { lock, unlockTime, lockedAmount, owner, otherAccount }; + return { lock, unlockTime, lockedAmount, owner, otherAccount } } - describe("Deployment", function () { - it("Should set the right unlockTime", async function () { - const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture); + describe('Deployment', function () { + it('Should set the right unlockTime', async function () { + const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture) - expect(await lock.unlockTime()).to.equal(unlockTime); - }); + expect(await lock.unlockTime()).to.equal(unlockTime) + }) - it("Should set the right owner", async function () { - const { lock, owner } = await loadFixture(deployOneYearLockFixture); + it('Should set the right owner', async function () { + const { lock, owner } = await loadFixture(deployOneYearLockFixture) - expect(await lock.owner()).to.equal(owner.address); - }); + expect(await lock.owner()).to.equal(owner.address) + }) - it("Should receive and store the funds to lock", async function () { - const { lock, lockedAmount } = await loadFixture( - deployOneYearLockFixture - ); + it('Should receive and store the funds to lock', async function () { + const { lock, lockedAmount } = await loadFixture(deployOneYearLockFixture) - expect(await ethers.provider.getBalance(lock.target)).to.equal( - lockedAmount - ); - }); + expect(await ethers.provider.getBalance(lock.target)).to.equal(lockedAmount) + }) - it("Should fail if the unlockTime is not in the future", async function () { + it('Should fail if the unlockTime is not in the future', async function () { // We don't use the fixture here because we want a different deployment - const latestTime = await time.latest(); - const Lock = await ethers.getContractFactory("Lock"); + const latestTime = await time.latest() + const Lock = await ethers.getContractFactory('Lock') await expect(Lock.deploy(latestTime, { value: 1 })).to.be.revertedWith( - "Unlock time should be in the future" - ); - }); - }); - - describe("Withdrawals", function () { - describe("Validations", function () { - it("Should revert with the right error if called too soon", async function () { - const { lock } = await loadFixture(deployOneYearLockFixture); - - await expect(lock.withdraw()).to.be.revertedWith( - "You can't withdraw yet" - ); - }); - - it("Should revert with the right error if called from another account", async function () { + 'Unlock time should be in the future', + ) + }) + }) + + describe('Withdrawals', function () { + describe('Validations', function () { + it('Should revert with the right error if called too soon', async function () { + const { lock } = await loadFixture(deployOneYearLockFixture) + + await expect(lock.withdraw()).to.be.revertedWith("You can't withdraw yet") + }) + + it('Should revert with the right error if called from another account', async function () { const { lock, unlockTime, otherAccount } = await loadFixture( - deployOneYearLockFixture - ); + deployOneYearLockFixture, + ) // We can increase the time in Hardhat Network - await time.increaseTo(unlockTime); + await time.increaseTo(unlockTime) // We use lock.connect() to send a transaction from another account await expect(lock.connect(otherAccount).withdraw()).to.be.revertedWith( - "You aren't the owner" - ); - }); + "You aren't the owner", + ) + }) it("Shouldn't fail if the unlockTime has arrived and the owner calls it", async function () { - const { lock, unlockTime } = await loadFixture( - deployOneYearLockFixture - ); + const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture) // Transactions are sent using the first signer by default - await time.increaseTo(unlockTime); + await time.increaseTo(unlockTime) - await expect(lock.withdraw()).not.to.be.reverted; - }); - }); + await expect(lock.withdraw()).not.to.be.reverted + }) + }) - describe("Events", function () { - it("Should emit an event on withdrawals", async function () { + describe('Events', function () { + it('Should emit an event on withdrawals', async function () { const { lock, unlockTime, lockedAmount } = await loadFixture( - deployOneYearLockFixture - ); + deployOneYearLockFixture, + ) - await time.increaseTo(unlockTime); + await time.increaseTo(unlockTime) await expect(lock.withdraw()) - .to.emit(lock, "Withdrawal") - .withArgs(lockedAmount, anyValue); // We accept any value as `when` arg - }); - }); + .to.emit(lock, 'Withdrawal') + .withArgs(lockedAmount, anyValue) // We accept any value as `when` arg + }) + }) - describe("Transfers", function () { - it("Should transfer the funds to the owner", async function () { + describe('Transfers', function () { + it('Should transfer the funds to the owner', async function () { const { lock, unlockTime, lockedAmount, owner } = await loadFixture( - deployOneYearLockFixture - ); + deployOneYearLockFixture, + ) - await time.increaseTo(unlockTime); + await time.increaseTo(unlockTime) await expect(lock.withdraw()).to.changeEtherBalances( [owner, lock], - [lockedAmount, -lockedAmount] - ); - }); - }); - }); -}); + [lockedAmount, -lockedAmount], + ) + }) + }) + }) +}) diff --git a/package.json b/package.json index f21b9c6..a61997b 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "react-dom": "18.2.0", "react-icons": "^4.11.0", "react-intersection-observer": "^9.5.2", + "react-router-dom": "^6.18.0", "react-spinners": "^0.13.8", "save-as": "^0.1.8", "semver": "^7.5.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 25a3105..d05a34c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -119,6 +119,9 @@ dependencies: react-intersection-observer: specifier: ^9.5.2 version: 9.5.2(react@18.2.0) + react-router-dom: + specifier: ^6.18.0 + version: 6.18.0(react-dom@18.2.0)(react@18.2.0) react-spinners: specifier: ^0.13.8 version: 0.13.8(react-dom@18.2.0)(react@18.2.0) @@ -3757,6 +3760,11 @@ packages: react: 18.2.0 dev: false + /@remix-run/router@1.11.0: + resolution: {integrity: sha512-BHdhcWgeiudl91HvVa2wxqZjSHbheSgIiDvxrF1VjFzBzpTtuDPkOdOi3Iqvc08kXtFkLjhbS+ML9aM8mJS+wQ==} + engines: {node: '>=14.0.0'} + dev: false + /@rushstack/eslint-patch@1.4.0: resolution: {integrity: sha512-cEjvTPU32OM9lUFegJagO0mRnIn+rbqrG89vV8/xLnLFX0DoR0r1oy5IlTga71Q7uT3Qus7qm7wgeiMT/+Irlg==} dev: false @@ -10594,6 +10602,29 @@ packages: use-sidecar: 1.1.2(@types/react@18.2.21)(react@18.2.0) dev: false + /react-router-dom@6.18.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Ubrue4+Ercc/BoDkFQfc6og5zRQ4A8YxSO3Knsne+eRbZ+IepAsK249XBH/XaFuOYOYr3L3r13CXTLvYt5JDjw==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + dependencies: + '@remix-run/router': 1.11.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-router: 6.18.0(react@18.2.0) + dev: false + + /react-router@6.18.0(react@18.2.0): + resolution: {integrity: sha512-vk2y7Dsy8wI02eRRaRmOs9g2o+aE72YCx5q9VasT1N9v+lrdB79tIqrjMfByHiY5+6aYkH2rUa5X839nwWGPDg==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + dependencies: + '@remix-run/router': 1.11.0 + react: 18.2.0 + dev: false + /react-spinners@0.13.8(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-3e+k56lUkPj0vb5NDXPVFAOkPC//XyhKPJjvcGjyMNPWsBKpplfeyialP74G7H7+It7KzhtET+MvGqbKgAqpZA==} peerDependencies: diff --git a/src/app/dashboard/dashLayout.tsx b/src/app/dashboard/dashLayout.tsx index c76299a..5cabe21 100644 --- a/src/app/dashboard/dashLayout.tsx +++ b/src/app/dashboard/dashLayout.tsx @@ -1,27 +1,33 @@ 'use client' import Image from 'next/image' import React, { useState } from 'react' - +// import { useRouter } from ''; import { redirect, usePathname } from 'next/navigation' import imageDecenterLogoWhite from '@public/Logo White.png' import imageDecenterLogoSubtitle from '@public/Logo Texts.png' import { RxDashboard } from 'react-icons/rx' import { HiOutlineChip } from 'react-icons/hi' + import { BsDatabase } from 'react-icons/bs' import { GoBell, GoSearch } from 'react-icons/go' +import { AiFillSetting } from 'react-icons/ai' +import { CiLogout } from 'react-icons/ci' import Link from 'next/link' -//import { useUserContext } from '@state/userContext' + import notIcon from 'public/notification.png' import { ModalNotification } from './notifications/components/Notification' import useUserStore from '@/state/userStore' import { myImageLoader } from '@lib/imageHelper' +import particle from '@/lib/particle' +import { useRouter } from 'next/navigation' export const DashLayout = ({ children }: { children: React.ReactNode }) => { - //const { user } = useUserContext() const { user } = useUserStore() const pathname = usePathname() + const [isNotificationOpen, setNotificationOpen] = useState(false) const [showBackdrop, setShowBackdrop] = useState(false) + const [isProfileOpen, setProfileOpen] = useState(false) const openNotification = () => { setNotificationOpen(true) @@ -32,6 +38,22 @@ export const DashLayout = ({ children }: { children: React.ReactNode }) => { setShowBackdrop(false) } + const openProfile = () => { + setProfileOpen(!isProfileOpen) + } + const handleLogout = async () => { + await particle.auth.logout() + console.log('logout') + localStorage.clear() + userStore.clearUser() + redirect('/explore') + // push('/explore') + } + + const myImageLoader = ({ src }) => { + return src + } + const userStore = useUserStore() return (