├── .eslintignore ├── .eslintrc ├── .gitignore ├── .lintstagedrc ├── .prettierignore ├── .prettierrc ├── .vscode └── settings.json ├── README.md ├── index.html ├── netlify.toml ├── package.json ├── public ├── favicon.png └── social-card.png ├── src ├── App.tsx ├── assets │ ├── fonts │ │ ├── 3616Grammastile-Regular.woff2 │ │ ├── DecimaMonoPro-Bold.woff2 │ │ ├── DecimaMonoPro-BoldItalic.woff2 │ │ ├── DecimaMonoPro-Italic.woff2 │ │ ├── DecimaMonoPro.woff2 │ │ ├── DecimaMonoProLt-Italic.woff2 │ │ └── DecimaMonoProLt.woff2 │ └── images │ │ ├── allow-any-claimer-selected.png │ │ ├── allow-any-claimer.png │ │ ├── allow-any-collection-selected.png │ │ ├── allow-any-collection.png │ │ ├── allow-any-infuser-selected.png │ │ ├── allow-any-infuser.png │ │ ├── allow-specific-addresses-selected.png │ │ ├── allow-specific-addresses.png │ │ ├── allow-specific-collections-selected.png │ │ ├── allow-specific-collections.png │ │ ├── card-back.png │ │ ├── claim-header-flourish.svg │ │ ├── claim-tokens-border-pattern-horizontal.png │ │ ├── claim-tokens-border-pattern-vertical.png │ │ ├── claim-tokens.png │ │ ├── create-realm-border-pattern-horizontal.png │ │ ├── create-realm-border-pattern-vertical.png │ │ ├── create-realm.png │ │ ├── crosshair.svg │ │ ├── dust-bg.png │ │ ├── explore-realms-hr.svg │ │ ├── fallback.png │ │ ├── faq-tile.svg │ │ ├── flag.svg │ │ ├── headings │ │ ├── choose-your-path.svg │ │ ├── claim-tokens.svg │ │ ├── create-your-realm.svg │ │ ├── explore-realms.svg │ │ ├── infuse-token.svg │ │ ├── select-collection.svg │ │ ├── select-collections.svg │ │ ├── select-nft.svg │ │ ├── select-realm.svg │ │ ├── set-up-claiming.svg │ │ └── set-up-infusion.svg │ │ ├── icons │ │ ├── arrow-left.svg │ │ ├── arrow-right.svg │ │ ├── discord.svg │ │ ├── github.svg │ │ ├── plus.svg │ │ ├── step-1.svg │ │ ├── step-2.svg │ │ ├── step-3.svg │ │ ├── step-4.svg │ │ └── twitter.svg │ │ ├── infuse-nft-border-pattern-horizontal.png │ │ ├── infuse-nft-border-pattern-vertical.png │ │ ├── infuse-nft.png │ │ ├── infusion-header-flourish.svg │ │ ├── lab-bg.png │ │ ├── logo.svg │ │ ├── metamask.png │ │ ├── plus.svg │ │ ├── star.svg │ │ ├── submit-button-bg-lg.png │ │ ├── submit-button-bg.png │ │ └── swirl-bg.png ├── components │ ├── AddressInput.tsx │ ├── AppErrorMessage.tsx │ ├── BackButton.tsx │ ├── BannerPageHeading.tsx │ ├── Button.tsx │ ├── ButtonGroup.tsx │ ├── Card.tsx │ ├── CenteredContent.tsx │ ├── ClaimTokensContainer.tsx │ ├── CollectionCard.tsx │ ├── CollectionList.tsx │ ├── ConnectWallet.tsx │ ├── ConnectWalletInline.tsx │ ├── CreateRealmContainer.tsx │ ├── DecimalNumber.tsx │ ├── EmptyState.tsx │ ├── FormErrors.tsx │ ├── FormFieldErrorMessage.tsx │ ├── FormHeading.tsx │ ├── FormSteps.tsx │ ├── GlobalStyle.tsx │ ├── Header.tsx │ ├── InfuseNftContainer.tsx │ ├── InfusionTicker.tsx │ ├── Input.tsx │ ├── InputGroup.tsx │ ├── Label.tsx │ ├── Modal.tsx │ ├── MultiAddressInput.tsx │ ├── Nav.tsx │ ├── Nft.tsx │ ├── NftCard.tsx │ ├── NftGalleryCard.tsx │ ├── NumberInput.tsx │ ├── RadioButton.tsx │ ├── RadioButtonCard.tsx │ ├── RadioGroup.tsx │ ├── RealmCard.tsx │ ├── RealmList.tsx │ ├── ScrollToTop.tsx │ ├── SocialLinks.tsx │ ├── SubmitButton.tsx │ ├── Switch.tsx │ ├── SwitchGroup.tsx │ ├── TextInput.tsx │ └── WalletModal.tsx ├── constants │ ├── abis │ │ ├── ERC20.json │ │ ├── ERC721.json │ │ └── HyperVIBES.json │ ├── contracts.ts │ ├── formSteps.ts │ ├── rpc.ts │ └── wallets.ts ├── hooks │ ├── useAutoConnect.ts │ ├── useBrowseNftDetails.ts │ ├── useClaimTokens.ts │ ├── useCollectionInfusions.ts │ ├── useContract.ts │ ├── useCreateRealmWizard.ts │ ├── useCurrentMinedTokens.ts │ ├── useEns.ts │ ├── useErc20Allowance.ts │ ├── useErc20ApproveAllowance.ts │ ├── useErc20Contract.ts │ ├── useErc20Decimals.ts │ ├── useErc20TokenDetails.ts │ ├── useErc721Contract.ts │ ├── useErc721IsApproved.ts │ ├── useErc721OwnerOf.ts │ ├── useHyperVibesContract.ts │ ├── useHyperVibesSubgraph.ts │ ├── useInfuseNft.ts │ ├── useListRealmNfts.ts │ ├── useListRealms.ts │ ├── useMetadata.ts │ ├── useMyInfusedNfts.ts │ ├── useMyInfusibleRealms.ts │ ├── useMyOwnedNfts.ts │ ├── useMyRealmAdmins.ts │ ├── useNftDetails.ts │ ├── useRealmCollections.ts │ ├── useRealmDetails.ts │ └── useRealms.ts ├── hypervibes │ ├── abi │ │ └── HyperVIBES.json │ ├── constants.ts │ ├── contract.ts │ ├── dataloaders.ts │ ├── ipfs.ts │ ├── nft.ts │ └── subgraph.ts ├── index.tsx ├── pages │ ├── BrowseNftsPage.tsx │ ├── BrowseRealmsPage.tsx │ ├── ChooseYourPathPage.tsx │ ├── ClaimTokensEnterClaimAmountPage.tsx │ ├── ClaimTokensSelectRealmPage.tsx │ ├── ClaimTokensSelectTokenPage.tsx │ ├── ClaimTokensSuccessPage.tsx │ ├── CreateRealmBasicInfoPage.tsx │ ├── CreateRealmSelectCollectionsPage.tsx │ ├── CreateRealmSetUpClaimingPage.tsx │ ├── CreateRealmSetUpInfusionPage.tsx │ ├── CreateRealmSuccessPage.tsx │ ├── InfuseNftEnterInfusionAmountPage.tsx │ ├── InfuseNftInputTokenPage.tsx │ ├── InfuseNftSelectCollectionPage.tsx │ ├── InfuseNftSelectRealmPage.tsx │ ├── InfuseNftSelectTokenPage.tsx │ ├── InfuseNftSuccessPage.tsx │ ├── NftDetailPage.tsx │ ├── NftListPage.tsx │ ├── NotFoundPage.tsx │ └── PlaceholderPage.tsx ├── providers │ ├── NftProvider.tsx │ ├── QueryProvider.tsx │ └── WalletProvider.tsx ├── types │ └── index.ts ├── utils │ ├── address.ts │ ├── contract.ts │ ├── network.ts │ └── object.ts └── vite-env.d.ts ├── tsconfig.json ├── vite.config.ts └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /build 3 | /.husky 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": [ 4 | "eslint:recommended", 5 | "plugin:@typescript-eslint/recommended", 6 | "plugin:import/recommended", 7 | "plugin:import/typescript", 8 | "plugin:react/recommended", 9 | "plugin:react/jsx-runtime", 10 | "plugin:react-hooks/recommended", 11 | "plugin:prettier/recommended" 12 | ], 13 | "settings": { 14 | "import/resolver": { 15 | "typescript": {} 16 | }, 17 | "react": { 18 | "version": "detect" 19 | } 20 | }, 21 | "rules": { 22 | "react/display-name": 0 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # production 5 | /build 6 | 7 | # misc 8 | .DS_Store 9 | .env.local 10 | .env.development.local 11 | .env.test.local 12 | .env.production.local 13 | .eslintcache 14 | 15 | npm-debug.log* 16 | yarn-debug.log* 17 | yarn-error.log* 18 | -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.ts?(x)": "eslint --cache --fix" 3 | } 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /build 3 | /.husky 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "arrowParens": "avoid" 4 | } 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hypervibes-frontend 2 | 3 | Frontend app for the [**HyperVIBES**](https://hypervibes.xyz) project. 4 | 5 | ## Links 6 | 7 | - [Product Brief](https://docs.google.com/document/d/1NvztqdMAyLERTPuX5uHSnq8f5G0YVRaxNsq5UaXhQEw/edit?usp=sharing) 8 | - [MVP Coordination Doc](https://docs.google.com/document/d/1dpMlzGeO4XfD6gBQoaTTXO2NxCCfA0hDYlTinJjCsfQ/edit?usp=sharing) 9 | - [Contracts repo](https://github.com/R-Group-Devs/hypervibes-contracts) 10 | 11 | ## Requirements 12 | 13 | - [Node](https://nodejs.org/en/) >=14.0.0 14 | - [Yarn](https://yarnpkg.com/) ^1.22.0 15 | 16 | ## Setup 17 | 18 | Clone the repo: 19 | 20 | ```sh 21 | $ git clone git@github.com:R-Group-Devs/hypervibes-frontend.git 22 | ``` 23 | 24 | ## Development 25 | 26 | Install dependencies: 27 | 28 | ```sh 29 | $ yarn 30 | ``` 31 | 32 | You'll need RPC endpoints for all networks you plan to use during local development. You can generate private RPC endpoints with [Infura](https://infura.io/) or [Alchemy](https://www.alchemy.com/), or search for public RPC endpoints to use. 33 | 34 | Add the following environment variables to a `.env.local` file: 35 | 36 | ``` 37 | REACT_APP_ETHEREUM_RPC_URL=??? 38 | REACT_APP_POLYGON_RPC_URL=??? 39 | REACT_APP_FANTOM_RPC_URL=??? 40 | REACT_APP_ARBITRUM_RPC_URL=??? 41 | REACT_APP_ROPSTEN_RPC_URL=??? 42 | REACT_APP_RINKEBY_RPC_URL=??? 43 | REACT_APP_GOERLI_RPC_URL=??? 44 | REACT_APP_MUMBAI_RPC_URL=??? 45 | ``` 46 | 47 | Run the app in development mode: 48 | 49 | ```sh 50 | $ yarn start 51 | ``` 52 | 53 | Generate a browser-ready build artifact: 54 | 55 | ```sh 56 | $ yarn build 57 | ``` 58 | 59 | Preview an app build: 60 | 61 | ```sh 62 | $ yarn serve 63 | ``` 64 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | HyperVIBES 23 | 24 | 25 | 47 |
48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [[redirects]] 2 | from = "/*" 3 | to = "/index.html" 4 | status = 200 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hypervibes-frontend", 3 | "version": "0.1.0", 4 | "description": "Frontend app for the HyperVIBES project.", 5 | "license": "UNLICENSED", 6 | "scripts": { 7 | "build": "tsc && vite build", 8 | "prepare": "git config --unset core.hooksPath; pro-commit", 9 | "pro-commit:task": "lint-staged", 10 | "serve": "vite preview", 11 | "start": "vite" 12 | }, 13 | "dependencies": { 14 | "@ethersproject/address": "^5.5.0", 15 | "@ethersproject/bignumber": "^5.5.0", 16 | "@ethersproject/contracts": "^5.4.1", 17 | "@ethersproject/providers": "^5.4.5", 18 | "@hookform/devtools": "^4.0.1", 19 | "dataloader": "^2.0.0", 20 | "ethers": "^5.5.1", 21 | "ethers-multicall": "0.2.1", 22 | "get-ens": "^2.0.1", 23 | "graphql": "^15.7.0", 24 | "graphql-request": "^3.6.1", 25 | "lodash": "4.17.21", 26 | "p-queue": "7.1.0", 27 | "react": "^17.0.2", 28 | "react-copy-to-clipboard": "^5.0.4", 29 | "react-dom": "^17.0.2", 30 | "react-error-boundary": "^3.1.3", 31 | "react-helmet": "^6.1.0", 32 | "react-hook-form": "^7.17.5", 33 | "react-hooks-global-state": "^1.0.2", 34 | "react-is": "^17.0.2", 35 | "react-query": "^3.28.0", 36 | "react-router-dom": "^5.3.0", 37 | "react-spring": "^9.3.0", 38 | "react-useportal": "^1.0.14", 39 | "styled-components": "^5.3.1", 40 | "use-nft": "^0.10.1", 41 | "use-wallet": "^0.12.3" 42 | }, 43 | "devDependencies": { 44 | "@types/react": "^17.0.0", 45 | "@types/react-copy-to-clipboard": "^5.0.2", 46 | "@types/react-dom": "^17.0.0", 47 | "@types/react-helmet": "^6.1.4", 48 | "@types/react-router-dom": "^5.3.1", 49 | "@types/styled-components": "^5.1.15", 50 | "@typescript-eslint/eslint-plugin": "^5.3.0", 51 | "@typescript-eslint/parser": "^5.3.0", 52 | "@vitejs/plugin-react": "^1.0.7", 53 | "eslint": "^8.1.0", 54 | "eslint-config-prettier": "^8.3.0", 55 | "eslint-import-resolver-typescript": "^2.5.0", 56 | "eslint-plugin-import": "^2.25.2", 57 | "eslint-plugin-prettier": "^4.0.0", 58 | "eslint-plugin-react": "^7.26.1", 59 | "eslint-plugin-react-hooks": "^4.3.0", 60 | "lint-staged": "^11.2.6", 61 | "prettier": "^2.4.1", 62 | "pro-commit": "^1.2.2", 63 | "typescript": "^4.4.4", 64 | "vite": "^2.6.13" 65 | }, 66 | "engines": { 67 | "node": ">=14.0.0", 68 | "yarn": "^1.22.0" 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/public/favicon.png -------------------------------------------------------------------------------- /public/social-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/public/social-card.png -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | BrowserRouter as Router, 3 | Switch, 4 | Route, 5 | Redirect, 6 | } from 'react-router-dom'; 7 | import { ErrorBoundary } from 'react-error-boundary'; 8 | import styled from 'styled-components'; 9 | import WalletProvider from './providers/WalletProvider'; 10 | import QueryProvider from './providers/QueryProvider'; 11 | import NftProvider from './providers/NftProvider'; 12 | import ScrollToTop from './components/ScrollToTop'; 13 | import PlaceholderPage from './pages/PlaceholderPage'; 14 | import ChooseYourPathPage from './pages/ChooseYourPathPage'; 15 | import CreateRealmBasicInfoPage from './pages/CreateRealmBasicInfoPage'; 16 | import CreateRealmSelectCollectionsPage from './pages/CreateRealmSelectCollectionsPage'; 17 | import CreateRealmSetUpInfusionPage from './pages/CreateRealmSetUpInfusionPage'; 18 | import CreateRealmSetUpClaimingPage from './pages/CreateRealmSetUpClaimingPage'; 19 | import CreateRealmSuccessPage from './pages/CreateRealmSuccessPage'; 20 | import InfuseNftSelectRealmPage from './pages/InfuseNftSelectRealmPage'; 21 | import InfuseNftSelectCollectionPage from './pages/InfuseNftSelectCollectionPage'; 22 | import InfuseNftSelectTokenPage from './pages/InfuseNftSelectTokenPage'; 23 | import InfuseNftInputTokenPage from './pages/InfuseNftInputTokenPage'; 24 | import InfuseNftEnterInfusionAmountPage from './pages/InfuseNftEnterInfusionAmountPage'; 25 | import ClaimTokensSelectRealmPage from './pages/ClaimTokensSelectRealmPage'; 26 | import ClaimTokensSelectTokenPage from './pages/ClaimTokensSelectTokenPage'; 27 | import ClaimTokensEnterClaimAmountPage from './pages/ClaimTokensEnterClaimAmountPage'; 28 | import NftListPage from './pages/NftListPage'; 29 | import NotFoundPage from './pages/NotFoundPage'; 30 | import GlobalStyle from './components/GlobalStyle'; 31 | import Header from './components/Header'; 32 | import SocialLinks from './components/SocialLinks'; 33 | import AppErrorMessage from './components/AppErrorMessage'; 34 | import BrowseRealmsPage from './pages/BrowseRealmsPage'; 35 | import BrowseNftsPage from './pages/BrowseNftsPage'; 36 | import NftDetailPage from './pages/NftDetailPage'; 37 | 38 | const AppContainer = styled.div` 39 | display: flex; 40 | margin: 0 auto; 41 | padding: 10em 0; 42 | max-width: 1200px; 43 | height: 100%; 44 | flex-direction: column; 45 | align-items: center; 46 | `; 47 | 48 | export default () => ( 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | }> 57 | 58 |
59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | ); 157 | -------------------------------------------------------------------------------- /src/assets/fonts/3616Grammastile-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/fonts/3616Grammastile-Regular.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/DecimaMonoPro-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/fonts/DecimaMonoPro-Bold.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/DecimaMonoPro-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/fonts/DecimaMonoPro-BoldItalic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/DecimaMonoPro-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/fonts/DecimaMonoPro-Italic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/DecimaMonoPro.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/fonts/DecimaMonoPro.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/DecimaMonoProLt-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/fonts/DecimaMonoProLt-Italic.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/DecimaMonoProLt.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/fonts/DecimaMonoProLt.woff2 -------------------------------------------------------------------------------- /src/assets/images/allow-any-claimer-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/allow-any-claimer-selected.png -------------------------------------------------------------------------------- /src/assets/images/allow-any-claimer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/allow-any-claimer.png -------------------------------------------------------------------------------- /src/assets/images/allow-any-collection-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/allow-any-collection-selected.png -------------------------------------------------------------------------------- /src/assets/images/allow-any-collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/allow-any-collection.png -------------------------------------------------------------------------------- /src/assets/images/allow-any-infuser-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/allow-any-infuser-selected.png -------------------------------------------------------------------------------- /src/assets/images/allow-any-infuser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/allow-any-infuser.png -------------------------------------------------------------------------------- /src/assets/images/allow-specific-addresses-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/allow-specific-addresses-selected.png -------------------------------------------------------------------------------- /src/assets/images/allow-specific-addresses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/allow-specific-addresses.png -------------------------------------------------------------------------------- /src/assets/images/allow-specific-collections-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/allow-specific-collections-selected.png -------------------------------------------------------------------------------- /src/assets/images/allow-specific-collections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/allow-specific-collections.png -------------------------------------------------------------------------------- /src/assets/images/card-back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/card-back.png -------------------------------------------------------------------------------- /src/assets/images/claim-tokens-border-pattern-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/claim-tokens-border-pattern-horizontal.png -------------------------------------------------------------------------------- /src/assets/images/claim-tokens-border-pattern-vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/claim-tokens-border-pattern-vertical.png -------------------------------------------------------------------------------- /src/assets/images/claim-tokens.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/claim-tokens.png -------------------------------------------------------------------------------- /src/assets/images/create-realm-border-pattern-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/create-realm-border-pattern-horizontal.png -------------------------------------------------------------------------------- /src/assets/images/create-realm-border-pattern-vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/create-realm-border-pattern-vertical.png -------------------------------------------------------------------------------- /src/assets/images/create-realm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/create-realm.png -------------------------------------------------------------------------------- /src/assets/images/crosshair.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/assets/images/dust-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/dust-bg.png -------------------------------------------------------------------------------- /src/assets/images/explore-realms-hr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/images/fallback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/fallback.png -------------------------------------------------------------------------------- /src/assets/images/flag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/headings/select-nft.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/images/icons/arrow-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/icons/arrow-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/icons/discord.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/icons/github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/icons/plus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/icons/step-1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/icons/step-2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/icons/step-3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/icons/step-4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/icons/twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/infuse-nft-border-pattern-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/infuse-nft-border-pattern-horizontal.png -------------------------------------------------------------------------------- /src/assets/images/infuse-nft-border-pattern-vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/infuse-nft-border-pattern-vertical.png -------------------------------------------------------------------------------- /src/assets/images/infuse-nft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/infuse-nft.png -------------------------------------------------------------------------------- /src/assets/images/infusion-header-flourish.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/assets/images/lab-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/lab-bg.png -------------------------------------------------------------------------------- /src/assets/images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/assets/images/metamask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/metamask.png -------------------------------------------------------------------------------- /src/assets/images/plus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/star.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/submit-button-bg-lg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/submit-button-bg-lg.png -------------------------------------------------------------------------------- /src/assets/images/submit-button-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/submit-button-bg.png -------------------------------------------------------------------------------- /src/assets/images/swirl-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Group-Devs/hypervibes-frontend/03bb26092709b8e2243b17f0e4821a37b9481f4c/src/assets/images/swirl-bg.png -------------------------------------------------------------------------------- /src/components/AddressInput.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { useFormContext } from 'react-hook-form'; 3 | import { isAddress } from '@ethersproject/address'; 4 | import TextInput from './TextInput'; 5 | import useEns from '../hooks/useEns'; 6 | import useErc20TokenDetails from '../hooks/useErc20TokenDetails'; 7 | 8 | interface Props { 9 | name: string; 10 | label?: string; 11 | description?: string; 12 | required?: boolean; 13 | showTokenSymbol?: boolean; 14 | } 15 | 16 | const Container = styled.div` 17 | position: relative; 18 | display: flex; 19 | flex-direction: column; 20 | width: 100%; 21 | `; 22 | 23 | const ResolvedAddress = styled.div` 24 | position: absolute; 25 | bottom: 0.35em; 26 | font-size: 12px; 27 | `; 28 | 29 | const TokenSymbol = styled.div` 30 | position: absolute; 31 | right: 0; 32 | bottom: 2.4em; 33 | padding: 2em 0.5em 0 2em; 34 | background: #000; 35 | `; 36 | 37 | export default ({ 38 | name, 39 | label, 40 | description, 41 | required, 42 | showTokenSymbol, 43 | }: Props) => { 44 | const { watch } = useFormContext(); 45 | const value = watch(name); 46 | const { address } = useEns(value); 47 | const { symbol } = useErc20TokenDetails(value); 48 | 49 | return ( 50 | 51 | !value || isAddress(value), 58 | }} 59 | /> 60 | 61 | {showTokenSymbol && {symbol}} 62 | 63 | {address && ( 64 | 65 | Resolved address: {address} 66 | 67 | )} 68 | 69 | ); 70 | }; 71 | -------------------------------------------------------------------------------- /src/components/AppErrorMessage.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Link } from 'react-router-dom'; 3 | import CenteredContent from './CenteredContent'; 4 | 5 | const H1 = styled.h1` 6 | margin-top: 0; 7 | margin-bottom: 0.25em; 8 | font-size: 28px; 9 | letter-spacing: 5px; 10 | `; 11 | 12 | const H2 = styled.h2` 13 | margin-bottom: 0; 14 | font-size: 16px; 15 | letter-spacing: 8px; 16 | color: rgba(255, 255, 255, 0.6); 17 | `; 18 | 19 | export default () => ( 20 | 21 |

something went wrong :(

22 |

23 | go back home 24 |

25 |
26 | ); 27 | -------------------------------------------------------------------------------- /src/components/BackButton.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Link } from 'react-router-dom'; 3 | import Button from './Button'; 4 | import arrowLeft from '../assets/images/icons/arrow-left.svg'; 5 | 6 | interface Props { 7 | path: string; 8 | } 9 | 10 | const BackButton = styled(Button)` 11 | display: flex; 12 | margin-top: 2.2em; 13 | padding-left: 0; 14 | padding-right: 0; 15 | width: 182px; 16 | background: none; 17 | 18 | &:hover:not([disabled]) { 19 | background: none; 20 | } 21 | `; 22 | 23 | const StyledLink = styled(Link)` 24 | display: flex; 25 | align-items: center; 26 | justify-content: center; 27 | width: 100%; 28 | color: #fff; 29 | 30 | &:hover { 31 | text-decoration: none; 32 | } 33 | `; 34 | 35 | const ArrowLeftIcon = styled.img` 36 | margin-top: 0.2em; 37 | margin-right: 0.5em; 38 | `; 39 | 40 | export default ({ path, ...rest }: Props) => ( 41 | e.preventDefault()} {...rest}> 42 | 43 | 44 | Back 45 | 46 | 47 | ); 48 | -------------------------------------------------------------------------------- /src/components/BannerPageHeading.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import useMetadata from '../hooks/useMetadata'; 3 | 4 | interface Props { 5 | name: string; 6 | tokenUri: string; 7 | } 8 | 9 | const Banner = styled.div<{ src?: string }>` 10 | position: absolute; 11 | top: 0; 12 | left: 0; 13 | width: 100%; 14 | height: 400px; 15 | background: linear-gradient(rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0.75)), 16 | url(${({ src }) => src}) center center no-repeat; 17 | background-size: cover; 18 | z-index: -1; 19 | `; 20 | 21 | const Title = styled.h1` 22 | font-size: 32px; 23 | text-align: center; 24 | `; 25 | 26 | const Subtitle = styled.div` 27 | font-size: 14px; 28 | text-align: center; 29 | `; 30 | 31 | export default ({ name, tokenUri }: Props) => { 32 | const { metadata, isLoading, isIdle } = useMetadata(tokenUri); 33 | 34 | if (isLoading || isIdle) { 35 | return null; 36 | } 37 | 38 | return ( 39 | <> 40 | 41 | {name} 42 | NFTs in this realm 43 | 44 | ); 45 | }; 46 | -------------------------------------------------------------------------------- /src/components/Button.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export default styled.button<{ size?: 'sm' | 'md'; inline?: boolean }>` 4 | padding: ${({ size }) => (size === 'sm' ? '0.25em 1em' : '0.4em 2em')}; 5 | display: ${({ inline }) => (inline ? 'inline-block' : 'block')}; 6 | background: #000; 7 | font-size: ${({ size }) => (size === 'sm' ? '14px' : '12px')}; 8 | line-height: ${({ size }) => (size === 'sm' ? '18px' : '18px')}; 9 | font-family: ${({ size }) => 10 | size === 'sm' 11 | ? "'Decima Mono', 'Courier New', monospace" 12 | : "'3616 Grammastile', sans-serif"}; 13 | color: #fff; 14 | border: none; 15 | 16 | &:disabled { 17 | opacity: 0.5; 18 | } 19 | 20 | &:hover:not([disabled]) { 21 | background: #000; 22 | cursor: pointer; 23 | } 24 | `; 25 | -------------------------------------------------------------------------------- /src/components/ButtonGroup.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export default styled.div` 4 | display: flex; 5 | align-items: center; 6 | justify-content: center; 7 | text-align: center; 8 | margin-top: 3em; 9 | 10 | & button { 11 | display: inline-block; 12 | margin-right: 4em; 13 | 14 | &:last-child { 15 | margin-right: 0; 16 | } 17 | } 18 | `; 19 | -------------------------------------------------------------------------------- /src/components/Card.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Link } from 'react-router-dom'; 3 | import fallbackImage from '../assets/images/fallback.png'; 4 | 5 | interface Props { 6 | name: string; 7 | url: string; 8 | } 9 | 10 | const Container = styled.div` 11 | margin-right: 2em; 12 | margin-bottom: 2em; 13 | width: 136px; 14 | display: inline-block; 15 | 16 | &:hover img { 17 | outline: 4px solid #bcff67; 18 | box-shadow: 0 0 20px 0 #bcff67; 19 | } 20 | `; 21 | 22 | const Image = styled.img` 23 | width: 136px; 24 | height: 136px; 25 | border-radius: 12px; 26 | outline: 4px solid transparent; 27 | box-shadow: none; 28 | transition: all 0.2s; 29 | `; 30 | 31 | const StyledLink = styled(Link)` 32 | color: #fff; 33 | 34 | &:hover { 35 | color: #bcff67; 36 | text-decoration: none; 37 | } 38 | `; 39 | 40 | const Name = styled.div` 41 | margin-top: 12px; 42 | width: 100%; 43 | font-size: 12px; 44 | font-weight: 600; 45 | `; 46 | 47 | export default ({ name, url }: Props) => ( 48 | 49 | 50 | 51 | {name} 52 | 53 | 54 | ); 55 | -------------------------------------------------------------------------------- /src/components/CenteredContent.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export default styled.div` 4 | display: flex; 5 | position: relative; 6 | top: -10em; 7 | margin: 0 auto; 8 | max-width: 1200px; 9 | height: 100vh; 10 | flex-direction: column; 11 | align-items: center; 12 | justify-content: center; 13 | pointer-events: none; 14 | 15 | & * { 16 | pointer-events: auto; 17 | } 18 | `; 19 | -------------------------------------------------------------------------------- /src/components/ClaimTokensContainer.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import borderPatternVertical from '../assets/images/claim-tokens-border-pattern-vertical.png'; 3 | import borderPatternHorizontal from '../assets/images/claim-tokens-border-pattern-horizontal.png'; 4 | import headerFlourish from '../assets/images/claim-header-flourish.svg'; 5 | import crosshair from '../assets/images/crosshair.svg'; 6 | 7 | interface Props { 8 | name: string; 9 | children: React.ReactNode; 10 | } 11 | 12 | const BackgroundContainerVertical = styled.div` 13 | position: relative; 14 | padding-left: 3em; 15 | background: url(${borderPatternVertical}) left bottom no-repeat; 16 | background-size: 24px 388px; 17 | `; 18 | 19 | const BackgroundContainerHorizontal = styled.div` 20 | padding-bottom: 3em; 21 | margin-left: -3em; 22 | background: url(${borderPatternHorizontal}) left bottom no-repeat; 23 | background-size: 388px 24px; 24 | `; 25 | 26 | const BorderContainer = styled.div` 27 | position: relative; 28 | padding: 1px; 29 | box-shadow: 0 0 20px 10px rgba(0, 0, 0, 0.8); 30 | background: linear-gradient(#ff6b6b, #000); 31 | `; 32 | 33 | const Container = styled.div` 34 | min-height: 600px; 35 | background: #000; 36 | `; 37 | 38 | const Content = styled.div` 39 | display: flex; 40 | align-items: center; 41 | justify-content: center; 42 | flex-direction: column; 43 | padding: 5em 3.5em 4.5em; 44 | width: 80vw; 45 | max-width: 784px; 46 | `; 47 | 48 | const NameTab = styled.div` 49 | position: absolute; 50 | top: 0; 51 | right: -44px; 52 | padding: 20px 10px; 53 | width: 44px; 54 | display: inline-block; 55 | font-family: '3616 Grammastile', sans-serif; 56 | font-size: 14px; 57 | color: #000; 58 | background: #ff6b6b; 59 | writing-mode: vertical-rl; 60 | `; 61 | 62 | const ThreeLinePattern = styled.div` 63 | display: flex; 64 | flex-direction: column; 65 | padding-top: 2px; 66 | `; 67 | 68 | const LinePattern = styled.div` 69 | margin-top: 6px; 70 | width: 100%; 71 | border-top: 1px solid #ff6b6b; 72 | `; 73 | 74 | const HeaderFlourish = styled.img` 75 | position: absolute; 76 | top: -40px; 77 | left: calc(50% - 45px); 78 | `; 79 | 80 | const Crosshair = styled.img` 81 | position: absolute; 82 | top: 3em; 83 | right: 1.5em; 84 | `; 85 | 86 | export default ({ name, children }: Props) => ( 87 | 88 | 89 | {name} 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | {children} 101 | 102 | 103 | 104 | 105 | ); 106 | -------------------------------------------------------------------------------- /src/components/CollectionCard.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Link } from 'react-router-dom'; 3 | import useMetadata from '../hooks/useMetadata'; 4 | import fallbackImage from '../assets/images/fallback.png'; 5 | 6 | interface Props { 7 | name: string; 8 | url: string; 9 | tokenUri: string; 10 | } 11 | 12 | const Container = styled.div` 13 | margin-left: 1em; 14 | margin-right: 1em; 15 | margin-bottom: 2em; 16 | width: 136px; 17 | display: inline-block; 18 | 19 | &:hover img { 20 | outline: 4px solid #bcff67; 21 | box-shadow: 0 0 20px 0 #bcff67; 22 | } 23 | `; 24 | 25 | const Image = styled.img` 26 | width: 136px; 27 | height: 136px; 28 | border-radius: 12px; 29 | outline: 4px solid transparent; 30 | box-shadow: none; 31 | transition: all 0.2s; 32 | `; 33 | 34 | const StyledLink = styled(Link)` 35 | color: #fff; 36 | 37 | &:hover { 38 | color: #bcff67; 39 | text-decoration: none; 40 | } 41 | `; 42 | 43 | const Name = styled.div` 44 | margin-top: 12px; 45 | width: 100%; 46 | font-size: 12px; 47 | font-weight: 600; 48 | `; 49 | 50 | export default ({ name, url, tokenUri }: Props) => { 51 | const { metadata, isLoading } = useMetadata(tokenUri); 52 | 53 | return ( 54 | 55 | 56 | {!isLoading && ( 57 | <> 58 | 59 | {name} 60 | 61 | )} 62 | 63 | 64 | ); 65 | }; 66 | -------------------------------------------------------------------------------- /src/components/CollectionList.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import CollectionCard from './CollectionCard'; 3 | import { shortenAddress } from '../utils/address'; 4 | import { Collection } from '../types'; 5 | 6 | interface Props { 7 | collections: Collection[]; 8 | } 9 | 10 | const Container = styled.div` 11 | display: flex; 12 | width: 100%; 13 | flex-wrap: wrap; 14 | `; 15 | 16 | export default ({ collections }: Props) => ( 17 | 18 | {collections.map(collection => ( 19 | 25 | ))} 26 | 27 | ); 28 | -------------------------------------------------------------------------------- /src/components/ConnectWallet.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import styled from 'styled-components'; 3 | import { useWallet } from 'use-wallet'; 4 | import usePortal from 'react-useportal'; 5 | import Button from './Button'; 6 | import WalletModal from './WalletModal'; 7 | import useAutoConnect from '../hooks/useAutoConnect'; 8 | import { shortenAddress } from '../utils/address'; 9 | 10 | const Container = styled.div` 11 | position: absolute; 12 | top: 30px; 13 | right: 50px; 14 | display: flex; 15 | align-items: center; 16 | `; 17 | 18 | const ConnectWalletButton = styled(Button)<{ isConnected: boolean }>` 19 | padding: 1px; 20 | height: 42px; 21 | font-family: ${({ isConnected }) => 22 | isConnected 23 | ? "'Decima Mono', 'Courier New', monospace" 24 | : "'3616 Grammastile', sans-serif"}; 25 | font-size: ${({ isConnected }) => (isConnected ? '14px' : '8px')}; 26 | line-height: ${({ isConnected }) => (isConnected ? '14px' : '24px')}; 27 | background: linear-gradient(#bcff67, #17ffe3); 28 | 29 | &:hover:not([disabled]) { 30 | background: linear-gradient(#bcff67, #17ffe3); 31 | } 32 | `; 33 | 34 | const ButtonBackground = styled.div` 35 | padding: 1em 2.5em; 36 | height: 100%; 37 | background: #1c1c1c; 38 | transition: background 0.2s; 39 | `; 40 | 41 | const NetworkName = styled.span` 42 | margin-right: 1.5em; 43 | font-size: 14px; 44 | `; 45 | 46 | export default ({ ...rest }) => { 47 | const { openPortal, closePortal, isOpen, Portal } = usePortal(); 48 | const wallet = useWallet(); 49 | const triedAutoConnect = useAutoConnect(); 50 | 51 | useEffect(() => { 52 | if (wallet.status === 'connected') { 53 | closePortal(); 54 | } 55 | }, [wallet.status, closePortal]); 56 | 57 | return ( 58 | 59 | {wallet.account && } 60 | 61 | {triedAutoConnect && ( 62 | 66 | 67 | {wallet.account ? shortenAddress(wallet.account) : 'connect wallet'} 68 | 69 | 70 | )} 71 | 72 | 73 | 74 | 75 | 76 | ); 77 | }; 78 | -------------------------------------------------------------------------------- /src/components/ConnectWalletInline.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { useWallet } from 'use-wallet'; 3 | import ConnectWallet from '../components/ConnectWallet'; 4 | import useAutoConnect from '../hooks/useAutoConnect'; 5 | 6 | interface Props { 7 | message?: string; 8 | } 9 | 10 | const Message = styled.p` 11 | margin-top: 2em; 12 | `; 13 | 14 | const StyledConnectWallet = styled(ConnectWallet)` 15 | position: static; 16 | margin-top: 1em; 17 | `; 18 | 19 | export default ({ message }: Props) => { 20 | const wallet = useWallet(); 21 | const triedAutoConnect = useAutoConnect(); 22 | 23 | return ( 24 | <> 25 | {!wallet.account && triedAutoConnect && ( 26 | <> 27 | {message && {message}} 28 | 29 | 30 | )} 31 | 32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /src/components/CreateRealmContainer.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import FormSteps, { FormStep } from './FormSteps'; 3 | import borderPatternVertical from '../assets/images/create-realm-border-pattern-vertical.png'; 4 | import borderPatternHorizontal from '../assets/images/create-realm-border-pattern-horizontal.png'; 5 | import stepOneIcon from '../assets/images/icons/step-1.svg'; 6 | import stepTwoIcon from '../assets/images/icons/step-2.svg'; 7 | import stepThreeIcon from '../assets/images/icons/step-3.svg'; 8 | import stepFourIcon from '../assets/images/icons/step-4.svg'; 9 | import star from '../assets/images/star.svg'; 10 | 11 | interface Props { 12 | name: string; 13 | steps: FormStep[]; 14 | activeStep: number; 15 | children: React.ReactNode; 16 | } 17 | 18 | const BackgroundContainerVertical = styled.div` 19 | position: relative; 20 | padding-left: 3em; 21 | background: url(${borderPatternVertical}) left top repeat-y; 22 | background-size: 24px 388px; 23 | `; 24 | 25 | const BackgroundContainerHorizontal = styled.div` 26 | padding-bottom: 3em; 27 | margin-left: -3em; 28 | background: url(${borderPatternHorizontal}) left bottom repeat-x; 29 | background-size: 388px 24px; 30 | `; 31 | 32 | const BorderContainer = styled.div` 33 | position: relative; 34 | padding: 1px; 35 | box-shadow: 0 0 20px 10px rgba(0, 0, 0, 0.8); 36 | background: linear-gradient(#17ffe3, #000); 37 | `; 38 | 39 | const Container = styled.div` 40 | background: #000; 41 | `; 42 | 43 | const Content = styled.div` 44 | display: flex; 45 | align-items: center; 46 | justify-content: center; 47 | flex-direction: column; 48 | padding: 5em 4em 4.5em; 49 | width: 80vw; 50 | max-width: 784px; 51 | `; 52 | 53 | const NameTab = styled.div` 54 | position: absolute; 55 | top: 0; 56 | right: -44px; 57 | padding: 20px 10px; 58 | width: 44px; 59 | display: inline-block; 60 | font-family: '3616 Grammastile', sans-serif; 61 | font-size: 14px; 62 | color: #000; 63 | background: #bcff67; 64 | writing-mode: vertical-rl; 65 | `; 66 | 67 | const ThreeLinePattern = styled.div` 68 | display: flex; 69 | flex-direction: column; 70 | padding-top: 2px; 71 | `; 72 | 73 | const LinePattern = styled.div` 74 | margin-top: 6px; 75 | width: 90%; 76 | max-width: 704px; 77 | border-top: 1px solid #17ffe3; 78 | `; 79 | 80 | const StepIcon = styled.img` 81 | position: absolute; 82 | top: 1em; 83 | right: 1em; 84 | `; 85 | 86 | const Star = styled.img` 87 | position: absolute; 88 | bottom: 1.5em; 89 | left: 1.5em; 90 | `; 91 | 92 | export default ({ name, steps, activeStep, children }: Props) => ( 93 | <> 94 | 95 | 96 | 97 | 98 | {name} 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | {activeStep === 1 && } 110 | {activeStep === 2 && } 111 | {activeStep === 3 && } 112 | {activeStep === 4 && } 113 | {children} 114 | 115 | 116 | 117 | 118 | 119 | 120 | ); 121 | -------------------------------------------------------------------------------- /src/components/DecimalNumber.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { formatUnits } from '@ethersproject/units'; 3 | import { BigNumber } from 'ethers'; 4 | import { useEffect, useState } from 'react'; 5 | 6 | interface Props { 7 | value: BigNumber | null | undefined; 8 | decimals: number; 9 | precision?: number; 10 | interpolation?: { 11 | sampledAt: number; 12 | dailyRate: BigNumber; 13 | max: BigNumber; 14 | }; 15 | maximumFractionDigits?: number; 16 | minimumFractionDigits?: number; 17 | } 18 | 19 | const Container = styled.span``; 20 | 21 | /** 22 | * Render a BigNumber, optionally lerped in real time based on a sample time and 23 | * daily rate 24 | */ 25 | export default ({ 26 | value, 27 | decimals, 28 | interpolation, 29 | minimumFractionDigits, 30 | maximumFractionDigits, 31 | ...props 32 | }: Props) => { 33 | const [alpha, setAlpha] = useState(); 34 | 35 | useEffect(() => { 36 | const h = setInterval(update, 100); 37 | return () => clearInterval(h); 38 | }, [interpolation]); 39 | 40 | const update = () => { 41 | if (interpolation == null) { 42 | setAlpha(BigNumber.from(0)); 43 | return; 44 | } 45 | 46 | // compute time since sample and amount to add (alpha) 47 | const delta = Math.max(0, Date.now() - interpolation.sampledAt * 1000); 48 | const nextAlpha = interpolation.dailyRate 49 | .mul(delta) 50 | .div(1000 * 60 * 60 * 24); 51 | 52 | setAlpha(nextAlpha); 53 | }; 54 | 55 | if (value == null) { 56 | return <>-; 57 | } 58 | 59 | // un-inited state 60 | if (alpha == null) { 61 | return null; 62 | } 63 | 64 | // add alpha to value and clamp to max 65 | let num = value.add(alpha); 66 | if (interpolation != null) { 67 | num = num.gt(interpolation.max) ? interpolation.max : num; 68 | } 69 | 70 | const truncated = Number(formatUnits(num, decimals)).toLocaleString('en-US', { 71 | minimumFractionDigits, 72 | maximumFractionDigits, 73 | }); 74 | 75 | return {truncated}; 76 | }; 77 | -------------------------------------------------------------------------------- /src/components/EmptyState.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export default styled.div` 4 | margin-top: 2em; 5 | width: 100%; 6 | text-align: center; 7 | `; 8 | -------------------------------------------------------------------------------- /src/components/FormErrors.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | interface Props { 4 | errors: string[]; 5 | } 6 | 7 | const Container = styled.ul` 8 | margin-top: 2em; 9 | margin-bottom: 3em; 10 | padding: 1em 3em; 11 | border: 1px solid #ff6b6b; 12 | color: #ff6b6b; 13 | `; 14 | 15 | const FormError = styled.li``; 16 | 17 | export default ({ errors }: Props) => { 18 | if (errors.length === 0) { 19 | return null; 20 | } 21 | 22 | return ( 23 | 24 | {errors.map(error => ( 25 | {error} 26 | ))} 27 | 28 | ); 29 | }; 30 | -------------------------------------------------------------------------------- /src/components/FormFieldErrorMessage.tsx: -------------------------------------------------------------------------------- 1 | import { FieldError } from 'react-hook-form'; 2 | import styled from 'styled-components'; 3 | 4 | interface Props { 5 | error?: FieldError; 6 | minValue?: number; 7 | maxLength?: number; 8 | } 9 | 10 | const Container = styled.div` 11 | margin-top: 0.75em; 12 | height: 20px; 13 | font-size: 12px; 14 | `; 15 | 16 | const Message = styled.span<{ isVisible: boolean }>` 17 | opacity: ${({ isVisible }) => (isVisible ? 1 : 0)}; 18 | transition: opacity 0.2s; 19 | `; 20 | 21 | export default ({ error, minValue, maxLength }: Props) => ( 22 | 23 | 24 | {error?.type === 'required' && 'This field is required.'} 25 | {error?.type === 'isNumber' && 'Enter a valid number.'} 26 | {error?.type === 'maxLength' && 27 | `This field must be shorter ${maxLength} characters.`} 28 | {error?.type === 'minValue' && 29 | `Enter a value ${minValue === 0 ? 'zero' : minValue} or higher.`} 30 | {error?.type === 'address' && 'Enter a valid Ethereum address.'} 31 | {error?.type === 'custom' && error?.message} 32 | 33 | 34 | ); 35 | -------------------------------------------------------------------------------- /src/components/FormHeading.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export default styled.img` 4 | margin-bottom: 3em; 5 | height: 20px; 6 | `; 7 | -------------------------------------------------------------------------------- /src/components/FormSteps.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export interface FormStep { 4 | label: string; 5 | path: string; 6 | } 7 | 8 | interface Props { 9 | steps: FormStep[]; 10 | activeStep: number; 11 | } 12 | 13 | const Container = styled.div` 14 | position: absolute; 15 | margin-top: -3.5em; 16 | width: 80vw; 17 | max-width: 784px; 18 | `; 19 | 20 | const ProgressBar = styled.div<{ progress: number }>` 21 | margin-bottom: 15px; 22 | height: 6px; 23 | background: linear-gradient( 24 | to right, 25 | #bcff67 ${({ progress }) => progress / 2}%, 26 | transparent ${({ progress }) => progress}% 27 | ); 28 | border-radius: 20px; 29 | `; 30 | 31 | const Steps = styled.div` 32 | display: flex; 33 | justify-content: space-between; 34 | `; 35 | 36 | const Step = styled.span<{ $isActive: boolean }>` 37 | font-size: 14px; 38 | text-transform: uppercase; 39 | font-weight: ${({ $isActive }) => ($isActive ? 600 : 400)}; 40 | color: ${({ $isActive }) => ($isActive ? '#fff' : '#777')}; 41 | `; 42 | 43 | export default ({ steps, activeStep }: Props) => ( 44 | 45 | 46 | 47 | {steps.map((step, index) => ( 48 | 49 | {step.label} 50 | 51 | ))} 52 | 53 | 54 | ); 55 | -------------------------------------------------------------------------------- /src/components/GlobalStyle.tsx: -------------------------------------------------------------------------------- 1 | import { useLocation } from 'react-router-dom'; 2 | import { createGlobalStyle } from 'styled-components'; 3 | import DecimaMonoProLt from '../assets/fonts/DecimaMonoProLt.woff2'; 4 | import DecimaMonoProLtItalic from '../assets/fonts/DecimaMonoProLt-Italic.woff2'; 5 | import DecimaMonoPro from '../assets/fonts/DecimaMonoPro.woff2'; 6 | import DecimaMonoProBold from '../assets/fonts/DecimaMonoPro-Bold.woff2'; 7 | import DecimaMonoProItalic from '../assets/fonts/DecimaMonoPro-Italic.woff2'; 8 | import DecimaMonoProBoldItalic from '../assets/fonts/DecimaMonoPro-BoldItalic.woff2'; 9 | import ThreeSixOneSixGrammastileRegular from '../assets/fonts/3616Grammastile-Regular.woff2'; 10 | import swirlBg from '../assets/images/swirl-bg.png'; 11 | import labBg from '../assets/images/lab-bg.png'; 12 | import dustBg from '../assets/images/dust-bg.png'; 13 | 14 | const GlobalStyle = createGlobalStyle` 15 | @font-face { 16 | font-family: 'Decima Mono'; 17 | src: url(${DecimaMonoProLt}) format('woff2'); 18 | font-weight: 300; 19 | font-style: normal; 20 | font-display: block; 21 | } 22 | 23 | @font-face { 24 | font-family: 'Decima Mono'; 25 | src: url(${DecimaMonoProLtItalic}) format('woff2'); 26 | font-weight: 300; 27 | font-style: italic; 28 | font-display: block; 29 | } 30 | 31 | @font-face { 32 | font-family: 'Decima Mono'; 33 | src: url(${DecimaMonoPro}) format('woff2'); 34 | font-weight: 400; 35 | font-style: normal; 36 | font-display: block; 37 | } 38 | 39 | @font-face { 40 | font-family: 'Decima Mono'; 41 | src: url(${DecimaMonoProBold}) format('woff2'); 42 | font-weight: 600; 43 | font-style: normal; 44 | font-display: block; 45 | } 46 | 47 | @font-face { 48 | font-family: 'Decima Mono'; 49 | src: url(${DecimaMonoProItalic}) format('woff2'); 50 | font-weight: 400; 51 | font-style: italic; 52 | font-display: block; 53 | } 54 | 55 | @font-face { 56 | font-family: 'Decima Mono'; 57 | src: url(${DecimaMonoProBoldItalic}) format('woff2'); 58 | font-weight: 600; 59 | font-style: italic; 60 | font-display: block; 61 | } 62 | 63 | @font-face { 64 | font-family: '3616 Grammastile'; 65 | src: url(${ThreeSixOneSixGrammastileRegular}) format('woff2'); 66 | font-weight: 400; 67 | font-style: normal; 68 | font-display: block; 69 | } 70 | 71 | * { 72 | box-sizing: border-box; 73 | } 74 | 75 | ::selection { 76 | background: #17ffe3; 77 | color: #000; 78 | } 79 | 80 | ::-moz-selection { 81 | background: #17ffe3; 82 | color: #000; 83 | } 84 | 85 | html { 86 | background: linear-gradient(#1c1c1c 20%, #183934 100%); 87 | background-size: cover; 88 | background-attachment: fixed; 89 | } 90 | 91 | body, button, input { 92 | font-family: "Decima Mono", "Courier New", monospace; 93 | } 94 | 95 | #root { 96 | min-height: 100vh; 97 | } 98 | 99 | p { 100 | line-height: 24px; 101 | } 102 | 103 | h2 { 104 | margin-bottom: 2em; 105 | } 106 | 107 | form { 108 | width: 100%; 109 | } 110 | 111 | a { 112 | padding-bottom: 0.5em; 113 | color: rgba(255, 255, 255, 0.6); 114 | text-decoration: none; 115 | transition: all 0.2s; 116 | 117 | &:hover { 118 | color: #fff; 119 | text-decoration: underline; 120 | } 121 | } 122 | `; 123 | 124 | export default () => { 125 | const location = useLocation(); 126 | const section = location.pathname.split('/')[1]; 127 | const isBrowseRealmsPage = 128 | location.pathname.split('/')[2] === 'realms' && 129 | !location.pathname.split('/')[3]; 130 | const isHomePage = section === ''; 131 | 132 | const getBackground = () => { 133 | if (section === 'realm' || isHomePage) { 134 | return ` 135 | background: url(${swirlBg}) 0 0 no-repeat; 136 | background-size: cover; 137 | `; 138 | } 139 | 140 | if (section === 'infuse') { 141 | return ` 142 | background: url(${labBg}) 70% -30% no-repeat; 143 | background-size: 60%; 144 | `; 145 | } 146 | 147 | if (section === 'claim' || isBrowseRealmsPage) { 148 | return ` 149 | background: url(${dustBg}) 0 0 no-repeat; 150 | background-size: cover; 151 | `; 152 | } 153 | }; 154 | 155 | const background = getBackground(); 156 | 157 | const BodyStyle = createGlobalStyle` 158 | body { 159 | margin: 0; 160 | ${background} 161 | background-attachment: fixed; 162 | color: #fff; 163 | } 164 | `; 165 | 166 | return ( 167 | <> 168 | 169 | 170 | 171 | ); 172 | }; 173 | -------------------------------------------------------------------------------- /src/components/Header.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import Nav from './Nav'; 3 | import ConnectWallet from './ConnectWallet'; 4 | 5 | const Container = styled.div``; 6 | 7 | export default () => { 8 | return ( 9 | 10 |