diff --git a/package.json b/package.json index fcfd493f..6c125438 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@taquito/tzip16": "13.0.1", "@types/mixpanel-browser": "^2.35.7", "@types/prismjs": "^1.26.0", + "@types/react-router-hash-link": "^2.4.5", "bignumber.js": "^9.0.1", "blockies-ts": "^1.0.0", "dayjs": "^1.10.4", @@ -53,6 +54,7 @@ "react-markdown": "^8.0.0", "react-query": "^3.13.0", "react-router-dom": "^5.2.0", + "react-router-hash-link": "^2.4.3", "react-scripts": "4.0.3", "react-simple-code-editor": "^0.11.2", "react-spring-bottom-sheet": "^3.4.0", diff --git a/src/modules/common/TitleBlock.tsx b/src/modules/common/TitleBlock.tsx index 2524667b..56ac2a46 100644 --- a/src/modules/common/TitleBlock.tsx +++ b/src/modules/common/TitleBlock.tsx @@ -2,6 +2,8 @@ import { Grid, Paper, styled, Tooltip, Typography } from "@material-ui/core" import React from "react" import { ReactElement } from "react-markdown/lib/react-markdown" import { InfoRounded } from "@material-ui/icons" +import { HashLink } from "react-router-hash-link" +import { CopyButton } from "./CopyButton" const StyledGrid = styled(Grid)({ height: "fit-content", @@ -40,7 +42,7 @@ const CustomTextContainer = styled(Paper)({ background: "inherit", boxShadow: "none", display: "flex", - alignItems: "flex-end" + alignItems: "center" }) interface Props { @@ -61,10 +63,12 @@ export const TitleBlock: React.FC = ({ title = "", description, tooltip = {tooltip ? ( - + - Configure Proposals and Voting + + {tooltipText} + ) : null} diff --git a/src/modules/creator/steps/Governance.tsx b/src/modules/creator/steps/Governance.tsx index 8da396f9..730c65a1 100644 --- a/src/modules/creator/steps/Governance.tsx +++ b/src/modules/creator/steps/Governance.tsx @@ -193,21 +193,21 @@ const validateForm = (values: VotingSettings) => { errors.proposalFlushBlocks = "Must be greater than 0" } - if ( - values.proposalFlushBlocks && - values.votingBlocks && - Number(values.votingBlocks) * 2 >= Number(values.proposalFlushBlocks) - ) { - errors.proposalFlushBlocks = "Must be greater than more than twice the voting cycle duration" - } - - if ( - values.proposalExpiryBlocks && - values.proposalFlushBlocks && - Number(values.proposalExpiryBlocks) <= Number(values.proposalFlushBlocks) - ) { - errors.proposalExpiryBlocks = "Must be greater than Proposal Execution Delay" - } + // if ( + // values.proposalFlushBlocks && + // values.votingBlocks && + // Number(values.votingBlocks) * 2 >= Number(values.proposalFlushBlocks) + // ) { + // errors.proposalFlushBlocks = "Must be greater than more than twice the voting cycle duration" + // } + + // if ( + // values.proposalExpiryBlocks && + // values.proposalFlushBlocks && + // Number(values.proposalExpiryBlocks) <= Number(values.proposalFlushBlocks) + // ) { + // errors.proposalExpiryBlocks = "Must be greater than Proposal Execution Delay" + // } if (!values.proposalExpiryBlocks || Number(values.proposalExpiryBlocks) <= 0) { errors.proposalExpiryBlocks = "Must be greater than 0" @@ -431,7 +431,7 @@ const GovernanceForm = ({ submitForm, values, setFieldValue, errors, touched, se blocks {errors.proposalFlushBlocks ? : } @@ -482,7 +482,7 @@ const GovernanceForm = ({ submitForm, values, setFieldValue, errors, touched, se blocks {errors.proposalExpiryBlocks ? : } @@ -670,6 +670,7 @@ export const Governance: React.FC = () => { diff --git a/src/modules/creator/steps/Quorum.tsx b/src/modules/creator/steps/Quorum.tsx index 36aef939..f82b9c20 100644 --- a/src/modules/creator/steps/Quorum.tsx +++ b/src/modules/creator/steps/Quorum.tsx @@ -398,6 +398,7 @@ export const Quorum: React.FC = () => { "\u0027" + "s total supply" } + tooltipText={"Quorum Settings"} tooltip={true} > diff --git a/src/modules/home/FAQ.tsx b/src/modules/home/FAQ.tsx index a9b42189..bc973867 100644 --- a/src/modules/home/FAQ.tsx +++ b/src/modules/home/FAQ.tsx @@ -74,7 +74,7 @@ export const FAQ: React.FC = () => { {faqList.map(({ question, answer }, i) => ( - + ))} diff --git a/src/modules/home/FAQItem.tsx b/src/modules/home/FAQItem.tsx index f39ff4fb..96053adc 100644 --- a/src/modules/home/FAQItem.tsx +++ b/src/modules/home/FAQItem.tsx @@ -1,10 +1,11 @@ -import React from "react" +import React, { useEffect, useState } from "react" import { AccordionDetails, AccordionSummary, Grid, Typography } from "@material-ui/core" import ExpandMoreIcon from "@material-ui/icons/ExpandMore" import { styled } from "@material-ui/core/styles" import { ContentContainer } from "../explorer/components/ContentContainer" import Accordion from "@material-ui/core/Accordion" import Markdown from "modules/common/Markdown" +import { useLocation } from "react-router-dom" const TableContainer = styled(ContentContainer)({ width: "100%" @@ -24,17 +25,78 @@ const AccordionContent = styled(AccordionDetails)(({ theme }) => ({ borderRadius: "0 0 8px 8px" })) -export const FAQItem = ({ question, answer }: { question: string; answer: string }) => { +const Hash = styled(Typography)({ + marginLeft: 8 +}) + +export const FAQItem = ({ question, answer, id }: { question: string; answer: string; id: string }) => { + const [open, setOpen] = useState(false) + const [style, setStyle] = useState({ display: "none" }) + + const location = useLocation() + + const formatQuestion = (question: string) => { + return question.replaceAll(" ", "-").toLowerCase() + } + const questionId = formatQuestion(question) + + useEffect(() => { + if (location.hash === "#" + questionId) { + setOpen(true) + setStyle({ display: "block" }) + return + } + setOpen(false) + setStyle({ display: "none" }) + }, [location, questionId]) + + useEffect(() => { + if (location.hash === "#" + questionId) { + setOpen(true) + const element = document.getElementById(`${questionId}`) + element?.scrollIntoView({ behavior: "smooth", block: "start" }) + setStyle({ display: "block" }) + return + } + setOpen(false) + setStyle({ display: "none" }) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + const updateLocationHash = () => { + window.location.hash = "#" + questionId + } + return ( - + - + } + expandIcon={ setOpen(!open)} style={{ fill: "rgb(65, 72, 77)" }} />} aria-controls="panel1a-content" id="panel1a-header" + onMouseEnter={e => { + setStyle({ display: "block" }) + }} + onMouseLeave={e => { + if (window.location.hash !== "#" + questionId) { + setStyle({ display: "none" }) + } + }} > - {question} + { + e.preventDefault() + updateLocationHash() + }} + > + {question} + + {" "} + #{" "} + + {answer} diff --git a/src/modules/home/utils/faq.md b/src/modules/home/utils/faq.md index 53cac04f..f5b0eb8d 100644 --- a/src/modules/home/utils/faq.md +++ b/src/modules/home/utils/faq.md @@ -1,4 +1,4 @@ -Why create a DAO ? +Why create a DAO? A DAO is a way to collectively manage resources in a community, in a way that is fair, transparent, and participatory. Instead of relying on top-down decision making, a DAO is led by a community. Founders put in funds and receive shares. As the DAO grows, new members are voted in, and members can receive shares for work, funds, or whatever else the community decides. Members can make proposals and vote. DAOs tend to be more creative, collaborative, agile, and fair.   @@ -53,7 +53,7 @@ From here you will Create DAO.   ![Homebase DAO - Creating a DAO on Tezos](~local/dao_create.png)   -Connect your wallet to proceed. +Connect your wallet to proceed.   There are two types of DAOs on Homebase. Treasury DAOs and Registry DAOs. Select which one is the type of DAO you are creating. The most common type of DAO is a Treasury DAO, to collectively manage shared resources, so this tutorial will walk you through that.   @@ -100,7 +100,7 @@ Please note, you cannot use an NFT token for voting on Homebase. If you enter an   Set your quorum to be low if it’s important that low participation doesn’t interfere with community governance. If your community is making highly consequential proposals, you might consider having a higher quorum.   -The next two numbers are the minimum and maximum amount the quorum threshold can get adjusted to after a period change. +The next two numbers are the minimum and maximum amount the quorum threshold can get adjusted to after a period change.   **Quorum Change** - A value that gets computed internally in the formula that calculates quorum adjustment.   @@ -120,7 +120,7 @@ The next two numbers are the minimum and maximum amount the quorum threshold can   ### **Review Information**   -If you click on next, you will be taken to the review information page, where you will be able to see everything you have configured so far; and if you see anything that you would like to change, you can just click on the edit button and you will be taken to that part of the creator and you will be able to change your settings. +If you click on next, you will be taken to the review information page, where you will be able to see everything you have configured so far; and if you see anything that you would like to change, you can just click on the edit button and you will be taken to that part of the creator and you will be able to change your settings.   If everything looks correct. And you can click on the launch button.   @@ -132,7 +132,7 @@ After your DAO has been properly indexed, you will see a button that says, "go t What is a registry? -A registry is a token-curated list of anything that DAO chooses. Examples might include marketplaces, a map of highly ranked places, or approved companies for placing ads on a blockchain-based media network. +A registry is a token-curated list of anything that DAO chooses. Examples might include marketplaces, a map of highly ranked places, or approved companies for placing ads on a blockchain-based media network.     ### **How does it work?** @@ -167,7 +167,7 @@ Assets can be directly transferred to the DAO's address. There is no special pro **Levels** - Are equivalent to blocks on the Tezos blockchain. The time between blocks is at least one minute, and varies somewhat. A cycle is 4,096 blocks.   -**FA2** - Is a token standard on Tezos, which supports standardization of permissions, and different token types including NFT’s. [Read more on the Tezos Developer Portal](https://tezos.b9lab.com/fa2). +**FA2** - Is a token standard on Tezos, which supports standardization of permissions, and different token types including NFT’s. [Read more on the Tezos Developer Portal](https://tezos.b9lab.com/fa2). diff --git a/src/services/beacon/context.tsx b/src/services/beacon/context.tsx index c259a03a..d03d388d 100644 --- a/src/services/beacon/context.tsx +++ b/src/services/beacon/context.tsx @@ -19,7 +19,7 @@ const getSavedState = async (): Promise => { try { const network = getTezosNetwork() const tezos = createTezos(network) - const wallet = createWallet() + const wallet = createWallet(network) const activeAccount = await wallet.client.getActiveAccount() if (!activeAccount?.address) { diff --git a/src/services/beacon/utils.ts b/src/services/beacon/utils.ts index 395d9a03..0c594fb9 100644 --- a/src/services/beacon/utils.ts +++ b/src/services/beacon/utils.ts @@ -29,10 +29,11 @@ export const getTezosNetwork = (): Network => { return envNetwork } -export const createWallet = () => +export const createWallet = (network: Network) => new BeaconWallet({ name: "Homebase", - iconUrl: "https://tezostaquito.io/img/favicon.png" + iconUrl: "https://tezostaquito.io/img/favicon.png", + preferredNetwork: network as NetworkType }) export const createTezos = (network: Network) => { @@ -62,7 +63,7 @@ export const connectWithBeacon = async ( wallet: BeaconWallet }> => { const networkType = getNetworkTypeByEnvNetwork(envNetwork) - const wallet = createWallet() + const wallet = createWallet(envNetwork) await wallet.requestPermissions({ network: { diff --git a/yarn.lock b/yarn.lock index 177f485e..b2b167e5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2251,6 +2251,11 @@ resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.9.tgz#1cfb6d60ef3822c589f18e70f8b12f9a28ce8724" integrity sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ== +"@types/history@^4.7.11": + version "4.7.11" + resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64" + integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== + "@types/html-minifier-terser@^5.0.0": version "5.1.2" resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.2.tgz#693b316ad323ea97eed6b38ed1a3cc02b1672b57" @@ -2399,6 +2404,15 @@ "@types/htmlparser2" "*" "@types/react" "*" +"@types/react-router-dom@*": + version "5.3.3" + resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83" + integrity sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw== + dependencies: + "@types/history" "^4.7.11" + "@types/react" "*" + "@types/react-router" "*" + "@types/react-router-dom@^5.1.6": version "5.3.2" resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.2.tgz#ebd8e145cf056db5c66eb1dac63c72f52e8542ee" @@ -2408,6 +2422,15 @@ "@types/react" "*" "@types/react-router" "*" +"@types/react-router-hash-link@^2.4.5": + version "2.4.5" + resolved "https://registry.yarnpkg.com/@types/react-router-hash-link/-/react-router-hash-link-2.4.5.tgz#41dcb55279351fedc9062115bb35db921d1d69f6" + integrity sha512-YsiD8xCWtRBebzPqG6kXjDQCI35LCN9MhV/MbgYF8y0trOp7VSUNmSj8HdIGyH99WCfSOLZB2pIwUMN/IwIDQg== + dependencies: + "@types/history" "^4.7.11" + "@types/react" "*" + "@types/react-router-dom" "*" + "@types/react-router@*": version "5.1.17" resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.17.tgz#087091006213b11042f39570e5cd414863693968" @@ -11282,6 +11305,13 @@ react-router-dom@^5.2.0: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" +react-router-hash-link@^2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/react-router-hash-link/-/react-router-hash-link-2.4.3.tgz#570824d53d6c35ce94d73a46c8e98673a127bf08" + integrity sha512-NU7GWc265m92xh/aYD79Vr1W+zAIXDWp3L2YZOYP4rCqPnJ6LI6vh3+rKgkidtYijozHclaEQTAHaAaMWPVI4A== + dependencies: + prop-types "^15.7.2" + react-router@5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.1.tgz#4d2e4e9d5ae9425091845b8dbc6d9d276239774d"