├── .eslintignore
├── .eslintrc.json
├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.yml
│ └── feature_request.yml
├── .gitignore
├── .vscode
├── extensions.json
└── settings.json
├── LICENSE
├── README.md
├── SECURITY.md
├── app-env.d.ts
├── docs
├── COMMITS.md
├── CONTRIBUTING.md
├── ISSUES.md
├── JS.md
├── REACT.md
└── TRANSLATIONS.md
├── next-env.d.ts
├── next.config.js
├── package.json
├── public
├── assets
│ ├── illustrations
│ │ └── empty_content.svg
│ ├── images
│ │ ├── cawnet.png
│ │ ├── img_placeholder.svg
│ │ ├── intro.jpeg
│ │ └── overlay.svg
│ ├── screens
│ │ ├── screen_dark_1.png
│ │ ├── screen_dark_2.png
│ │ └── screen_dark_3.png
│ ├── tokens
│ │ ├── caw.png
│ │ ├── eth.png
│ │ └── mcaw.png
│ └── videos
│ │ ├── intro.mp4
│ │ └── intro_caw.mp4
├── browserconfig.xml
├── favicon.ico
├── favicon
│ ├── android-chrome-192x192.png
│ ├── apple-touch-icon.png
│ ├── favicon-16x16.png
│ ├── favicon-180x180.png
│ ├── favicon-192x192.png
│ ├── favicon-32x32.png
│ ├── favicon-apple-180x180.png
│ ├── favicon.ico
│ └── mstile-150x150.png
├── fonts
│ ├── CircularStd-Bold.otf
│ ├── CircularStd-Book.otf
│ ├── CircularStd-Medium.otf
│ ├── Roboto-Bold.ttf
│ ├── Roboto-Regular.ttf
│ └── index.css
├── icons
│ ├── bell.svg
│ ├── bookmark.svg
│ ├── chat.svg
│ ├── dextools.ico
│ ├── etherscan.ico
│ ├── hash.svg
│ ├── home-heart.svg
│ ├── ic_flag_de.svg
│ ├── ic_flag_en.svg
│ ├── ic_flag_es.svg
│ ├── ic_flag_pl.svg
│ ├── list.svg
│ ├── settings.svg
│ ├── uniswap.png
│ └── user.svg
├── logo.jpeg
├── logo
│ └── logo_single.png
├── robots.txt
├── safari-pinned-tab.svg
├── site.webmanifest
└── vercel.svg
├── src
├── assets
│ ├── illustration_404.tsx
│ ├── illustration_500.tsx
│ └── illustration_maintenance.tsx
├── blocks
│ ├── MintableCawForm.tsx
│ ├── home
│ │ ├── CardParallaxSection.tsx
│ │ ├── EconomySection.tsx
│ │ ├── FlippingText.tsx
│ │ ├── HeroSection.tsx
│ │ ├── PoweredCard.tsx
│ │ ├── PoweredSection.tsx
│ │ └── card-content.ts
│ ├── post
│ │ ├── Avatars.tsx
│ │ ├── NewPost.tsx
│ │ ├── PostActions.tsx
│ │ ├── PostAvatar.tsx
│ │ ├── PostMenu.tsx
│ │ └── index.tsx
│ └── wall
│ │ └── index.tsx
├── components
│ ├── AlertMessage.tsx
│ ├── Block.tsx
│ ├── CircularProgress.tsx
│ ├── ErrorBoundary.tsx
│ ├── Interface.Props.ts
│ ├── Logo.tsx
│ ├── MenuPopover.tsx
│ ├── NftUsernameCard.tsx
│ ├── PostContent.tsx
│ ├── Stat.tsx
│ ├── animate
│ │ ├── MotionContainer.tsx
│ │ ├── MotionLazyContainer.tsx
│ │ ├── MotionViewport.tsx
│ │ ├── ParallaxText.tsx
│ │ ├── WrapperFade.tsx
│ │ ├── features.js
│ │ ├── index.ts
│ │ ├── type.ts
│ │ └── variants
│ │ │ ├── actions.ts
│ │ │ ├── background.ts
│ │ │ ├── bounce.ts
│ │ │ ├── container.ts
│ │ │ ├── fade.ts
│ │ │ ├── flip.ts
│ │ │ ├── index.ts
│ │ │ ├── path.ts
│ │ │ ├── rotate.ts
│ │ │ ├── scale.ts
│ │ │ ├── slide.ts
│ │ │ ├── transition.ts
│ │ │ └── zoom.ts
│ ├── avatar
│ │ ├── Avatar.tsx
│ │ └── StoryStyledAvatar.tsx
│ ├── buttons
│ │ └── Button.tsx
│ ├── contract
│ │ ├── avatars
│ │ │ └── MyAvatar.tsx
│ │ ├── modals
│ │ │ ├── BuyCawModal.tsx
│ │ │ ├── ProtocolCost.tsx
│ │ │ ├── ProtocolCostModal.tsx
│ │ │ ├── QuickMintUserName.tsx
│ │ │ └── UsefulLinksModal.tsx
│ │ ├── stats
│ │ │ ├── CawPrice.tsx
│ │ │ ├── EthPrice.tsx
│ │ │ └── NftPrice.tsx
│ │ └── wallet
│ │ │ ├── BrowserMessageModal.tsx
│ │ │ ├── ConnectWalletButton.tsx
│ │ │ ├── NavbarAccount.tsx
│ │ │ ├── PopoverAccount.tsx
│ │ │ └── Wallet.tsx
│ ├── dialogs
│ │ ├── AlertDialog.tsx
│ │ ├── BlockChainOperationInProgressModal.tsx
│ │ └── OperationInProgress.tsx
│ ├── icons
│ │ ├── IconButtonAnimate.tsx
│ │ └── Iconify.tsx
│ ├── loaders
│ │ └── PageLoader.tsx
│ ├── settings
│ │ ├── LanguagePopover.tsx
│ │ └── ToogleMode.tsx
│ ├── sidebar
│ │ ├── MobileNav.tsx
│ │ ├── NavItem.tsx
│ │ ├── SidebarContent.tsx
│ │ ├── index.tsx
│ │ └── menu.ts
│ ├── tag-parser
│ │ ├── index.tsx
│ │ └── parser.ts
│ ├── topbar
│ │ ├── index.tsx
│ │ └── menu
│ │ │ ├── BuyCawItem.tsx
│ │ │ ├── CalculatorItem.tsx
│ │ │ ├── MenuItem.tsx
│ │ │ ├── MoreLinksItems.tsx
│ │ │ ├── QuickMintUserNameItem.tsx
│ │ │ └── index.tsx
│ └── wrappers
│ │ ├── Page.tsx
│ │ └── PopoverWrapper.tsx
├── config
│ ├── ABIs
│ │ ├── CAW.json
│ │ ├── CAW_NAME.json
│ │ ├── CAW_NAME_MINTER.json
│ │ └── MINTABLE_CAW.json
│ ├── index.ts
│ └── siteSettings.ts
├── context
│ ├── DAppConnectContext.tsx
│ └── Providers.tsx
├── hooks
│ ├── contracts
│ │ ├── helper.ts
│ │ ├── useAccountBalance.ts
│ │ ├── useCawNameMinterContract.ts
│ │ ├── useCawNamesContract.ts
│ │ ├── useETHBalance.ts
│ │ └── useMintableCAWContract.ts
│ ├── index.ts
│ ├── useAppConfigurations.ts
│ ├── useAsync.ts
│ ├── useDebounce.ts
│ ├── useDebounceEffect.tsx
│ ├── useIsMounted.tsx
│ ├── useLocalStorage.ts
│ ├── useLocale.ts
│ └── useOnClickOutside.tsx
├── interface
│ └── WalletBalanceInterface.ts
├── layouts
│ ├── DashboardLayout.tsx
│ ├── LandingLayout.tsx
│ ├── LogoOnlyLayout.tsx
│ └── index.tsx
├── locales
│ ├── de.json
│ ├── en.json
│ ├── es.json
│ ├── i18n.ts
│ └── pl.json
├── pages
│ ├── 404.tsx
│ ├── 500.tsx
│ ├── _app.tsx
│ ├── _document.tsx
│ ├── app.tsx
│ ├── app
│ │ ├── accounts
│ │ │ └── index.tsx
│ │ ├── bookmarks
│ │ │ └── index.tsx
│ │ ├── explore
│ │ │ └── index.tsx
│ │ ├── home
│ │ │ └── index.tsx
│ │ ├── lists
│ │ │ └── index.tsx
│ │ ├── messages
│ │ │ └── index.tsx
│ │ ├── notifications
│ │ │ └── index.tsx
│ │ ├── settings
│ │ │ ├── BoxMask.tsx
│ │ │ ├── Display.tsx
│ │ │ ├── Language.tsx
│ │ │ ├── SettingColorPresets.tsx
│ │ │ ├── SettingDirection.tsx
│ │ │ ├── SettingFullscreen.tsx
│ │ │ ├── SettingMode.tsx
│ │ │ └── index.tsx
│ │ └── swap
│ │ │ └── mcaw
│ │ │ └── index.tsx
│ ├── auth
│ │ ├── connect
│ │ │ └── index.tsx
│ │ ├── mint
│ │ │ ├── ConfirmAndMintCard.tsx
│ │ │ ├── FormStepper.tsx
│ │ │ ├── MintUserNameCard.tsx
│ │ │ ├── MintingCost.tsx
│ │ │ ├── NftPriceLegend.tsx
│ │ │ ├── Steps.tsx
│ │ │ ├── UserAcceptance.tsx
│ │ │ ├── WalletBalance.tsx
│ │ │ ├── WalletConnection.tsx
│ │ │ └── index.tsx
│ │ └── minted
│ │ │ └── [username]
│ │ │ ├── LoaderCard.tsx
│ │ │ ├── NftNameCard.tsx
│ │ │ └── [tx].tsx
│ ├── discover.tsx
│ ├── index.tsx
│ ├── maintenance.tsx
│ └── user
│ │ └── profile
│ │ └── [username].tsx
├── routes
│ └── paths.ts
├── styles
│ └── globals.css
├── theme
│ ├── cookie.tsx
│ ├── foundations
│ │ ├── blur.ts
│ │ ├── borders.ts
│ │ ├── breakpoints.ts
│ │ ├── colors.ts
│ │ ├── index.ts
│ │ ├── radius.ts
│ │ ├── shadows.ts
│ │ ├── sizes.ts
│ │ ├── spacing.ts
│ │ ├── transition.ts
│ │ ├── typography.ts
│ │ └── z-index.ts
│ └── index.ts
├── types
│ ├── community-feed.ts
│ ├── dtos.ts
│ └── global.d.ts
└── utils
│ ├── constants.ts
│ ├── createAvatar.ts
│ ├── formatNumber.ts
│ ├── formatTime.ts
│ ├── helper.ts
│ ├── manifestoHelper.ts
│ └── mock
│ ├── boolean.ts
│ ├── funcs.ts
│ ├── mock.ts
│ ├── name.ts
│ ├── number.ts
│ ├── text.ts
│ └── wallposts.ts
├── tsconfig.json
└── yarn.lock
/.eslintignore:
--------------------------------------------------------------------------------
1 | **/node_modules/*
2 | **/out/*
3 | **/.next/*
4 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "@typescript-eslint"
4 | ],
5 | "extends": [
6 | "next/core-web-vitals",
7 | "plugin:@typescript-eslint/recommended",
8 | "prettier"
9 | ],
10 | "rules": {
11 | "arrow-body-style": 1,
12 | "react/display-name": 0,
13 | "import/no-duplicates": 1,
14 | "react/no-children-prop": 0,
15 | "react/self-closing-comp": 2,
16 | "@next/next/no-img-element": 0,
17 | "react/no-unescaped-entities": 0,
18 | "import/no-useless-path-segments": 1,
19 | "@typescript-eslint/ban-ts-comment": 0,
20 | "@typescript-eslint/no-explicit-any": 0,
21 | "@typescript-eslint/no-empty-function": 0,
22 | "@typescript-eslint/no-non-null-assertion": 0,
23 | "@typescript-eslint/explicit-module-boundary-types": 0,
24 | "@typescript-eslint/no-unused-vars": [
25 | 1,
26 | {
27 | "vars": "all",
28 | "args": "none"
29 | }
30 | ]
31 | }
32 | }
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------
1 | name: "Feature Suggestions"
2 | description: "Suggest a new feature for CAW"
3 | labels: "needs review"
4 | body:
5 | - type: textarea
6 | attributes:
7 | label: Summary
8 | description: Describe the feature in 1 or 2 sentences
9 | placeholder: concisely describe the feature you want to see
10 | validations:
11 | required: true
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
3 | package-lock.json
4 | yarn.lock
5 |
6 | # dependencies
7 | /node_modules
8 | /.pnp
9 | .pnp.js
10 |
11 | # testing
12 | /coverage
13 |
14 | # next.js
15 | /.next/
16 | /out/
17 |
18 | # production
19 | /build
20 |
21 | # misc
22 | .DS_Store
23 | *.pem
24 |
25 | # debug
26 | .pnpm-debug.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 |
37 | # Logs
38 | logs
39 | *.log
40 | npm-debug.log*
41 | yarn-debug.log*
42 | yarn-error.log*
43 | lerna-debug.log*
44 |
45 | # Diagnostic reports (https://nodejs.org/api/report.html)
46 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
47 |
48 | # Runtime data
49 | pids
50 | *.pid
51 | *.seed
52 | *.pid.lock
53 |
54 | # Directory for instrumented libs generated by jscoverage/JSCover
55 | lib-cov
56 |
57 | # Coverage directory used by tools like istanbul
58 | coverage
59 | *.lcov
60 |
61 | # nyc test coverage
62 | .nyc_output
63 |
64 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
65 | .grunt
66 |
67 | # Bower dependency directory (https://bower.io/)
68 | bower_components
69 |
70 | # node-waf configuration
71 | .lock-wscript
72 |
73 | # Compiled binary addons (https://nodejs.org/api/addons.html)
74 | build/Release
75 |
76 | # Dependency directories
77 | node_modules/
78 | jspm_packages/
79 |
80 | # TypeScript v1 declaration files
81 | typings/
82 |
83 | # TypeScript cache
84 | *.tsbuildinfo
85 |
86 | # Optional npm cache directory
87 | .npm
88 |
89 | # Optional eslint cache
90 | .eslintcache
91 |
92 | # Microbundle cache
93 | .rpt2_cache/
94 | .rts2_cache_cjs/
95 | .rts2_cache_es/
96 | .rts2_cache_umd/
97 |
98 | # Optional REPL history
99 | .node_repl_history
100 |
101 | # Output of 'npm pack'
102 | *.tgz
103 |
104 | # Yarn Integrity file
105 | .yarn-integrity
106 |
107 | # dotenv environment variables file
108 | .env
109 | .env.test
110 |
111 | # parcel-bundler cache (https://parceljs.org/)
112 | .cache
113 |
114 | # Next.js build output
115 | .next
116 |
117 | # Nuxt.js build / generate output
118 | .nuxt
119 | dist
120 |
121 | # Gatsby files
122 | .cache/
123 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
124 | # https://nextjs.org/blog/next-9-1#public-directory-support
125 | # public
126 |
127 | # vuepress build output
128 | .vuepress/dist
129 |
130 | # Serverless directories
131 | .serverless/
132 |
133 | # FuseBox cache
134 | .fusebox/
135 |
136 | # DynamoDB Local files
137 | .dynamodb/
138 |
139 | # TernJS port file
140 | .tern-port
141 | >>>>>>> main-holder
142 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "dbaeumer.vscode-eslint",
4 | "aaron-bond.better-comments",
5 | "IronGeek.vscode-env",
6 | "PKief.material-icon-theme",
7 | "wix.vscode-import-cost"
8 | ]
9 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "compile-hero.disable-compile-files-on-did-save-code": false,
3 | "editor.tabSize": 2,
4 | "[typescriptreact]": {
5 | "editor.defaultFormatter": "vscode.typescript-language-features"
6 | },
7 | }
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 draos2q
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🌙 CAW Frontend
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | # About CAW - A Hunters Dream
11 |
12 |
13 | ## 📦 Environments
14 | | Name | Link |
15 | | --------------- | ----------------------------------- |
16 | | Mainnet | Not yet |
17 | | Alpha Test UI | https://teh-eyes.vercel.app/ |
18 |
19 | ## Getting Started
20 |
21 | Create an .env file (be aware that this file is not tracked by git) and add the following:
22 |
23 | ```bash
24 | ALCHEMY_API_KEY=SOME-STRING-OF-CHARS
25 | INFURA_API_KEY=SOME-STRING-OF-CHARS
26 | JSON_RPC_URL="https://rpc.builder0x69.io"
27 | NETWORK="goerli"
28 |
29 | ```
30 | > INFURA_API_KEY : Make sure to create a WEB3 API (Formely Ethereum) project on Infura and add the API key here.
31 |
32 | then run the following commands:
33 |
34 | ```sh
35 | yarn install
36 |
37 | # Development
38 | yarn dev
39 |
40 | # Production
41 | yarn build
42 | yarn start
43 | ```
44 | and visit http://localhost:8082
45 |
46 | ## Contributing
47 | Would you like to contribute to this project?
48 |
49 | This project is open source and welcomes contributions. We focus layer on the CAW Manifesto. We are in the early stages of a Social Clearing house; read more about it [here](https://caw.is/).
50 |
51 | We are looking for people who want to contribute to the project, not just the code. Join us on [Telegram](https://t.me/cawbuilders)
52 |
53 |
54 | Regarding the code, we invite you to read this project's [CONTRIBUTING](docs/CONTRIBUTING.md) guidelines.
55 |
56 | ## Recommended extensions
57 | - [BetterComments](https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments)
58 | - [GitLents](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens)
59 | - [ENV](https://marketplace.visualstudio.com/items?itemName=IronGeek.vscode-env)
60 |
61 | ## Built with
62 | - [TypeScript](https://www.typescriptlang.org/)
63 | - [Next.js](https://nextjs.org/)
64 | - [Chakra UI](https://chakra-ui.com/)
65 | - [Ethers.js](https://docs.ethers.io/v5/)
66 | - [Wagmi](https://wagmi.sh/)
67 | - [RainbowKit](https://www.rainbowkit.com/)
68 |
69 | ## Next Steps
70 | - [ ] Add more documentation
71 | - [ ] Add other guidelines
72 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Contact
2 |
3 | email: caw@caw.is
4 |
5 | # Reporting Security Issues
6 | If you believe you have discovered a security vulnerability, please contact us immediately at caw@caw.is
7 |
8 | We will promptly investigate and address any issues reported.
9 |
10 |
11 | # Security Measures | Please do the following:
12 | - Do not take advantage of the vulnerability or problem you have discovered, for example by downloading more data than necessary to demonstrate the vulnerability or deleting or modifying other people's data.
13 | - Do not reveal the problem to others until it has been resolved
14 | - Provide sufficient information to reproduce the problem so we will be able to resolve it as quickly as possible,
--------------------------------------------------------------------------------
/app-env.d.ts:
--------------------------------------------------------------------------------
1 | import { ExternalProvider } from "@ethersproject/providers";
2 |
3 | declare global {
4 | interface Window {
5 | ethereum?: ExternalProvider;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/docs/COMMITS.md:
--------------------------------------------------------------------------------
1 | # Semantic Commit Messages
2 |
3 | It is important to maintain an order and consistency in the commit messages.
4 |
5 | So, we have decided to use a commit message format based on [Semantic Commit Messages](https://sparkbox.com/foundry/semantic_commit_messages).
6 |
7 | Furthermore, refer to this [gist](https://gist.github.com/joshbuchea/6f47e86d2510bce28f8e7f42ae84c716)
8 | for more examples or discussion.
9 |
10 | ## Types
11 | * **feat**: new feature for the user, not a new feature for build script
12 |
13 | * **fix**: bug fix for the user, not a fix to a build script
14 | * **docs**: changes to the documentation
15 | * **style**: formatting, missing semi colons, etc; no production code change
16 | * **refactor**: refactoring production code, eg. renaming a variable
17 | * **test**: adding missing tests, refactoring tests; no production code change
18 | * **chore**: updating grunt tasks etc; no production code change
19 |
20 | ## Format
21 | ```hs
22 | is optional
23 | (issue #x | feature #x):
24 | summary : feat: short description of the commit
25 | description : Include a longer description of the commit if necessary.
26 |
27 | i.e.
28 | fix (issue #1): short title of the commit
29 | ```
30 |
--------------------------------------------------------------------------------
/docs/ISSUES.md:
--------------------------------------------------------------------------------
1 | # Submitting Bugs and Suggestions
2 |
3 |
4 | ## Before Submitting an Issue
5 | Please search for open issues to see if the issue or feature request has already been filed.
6 |
7 | If you find your issue already exists, make relevant comments and add your reaction.
8 |
9 | 👍 - upvote
10 | 👎 - downvote
11 |
12 | ## Writing Good Bug Reports and Feature Requests
13 | - File a single issue per problem and feature request.
14 | - Do not enumerate multiple bugs or feature requests in the same issue.
15 | - The more information you can provide, the more likely someone will successfully reproduce the issue and find a fix.
16 | - Please be as detailed as possible in your report.
17 | * What is your environment?
18 | * What steps will reproduce the issue?
19 | * What browser(s) and which Wallet are you connecting with?
20 |
21 |
22 | ## Contributing Fixes
23 | If you are interested in fixing issues and contributing directly to the code base, please see the document (How to Contribute)[CONTRIBUTING.md].
24 |
25 | Include the following information with each issue:
26 | Description :
27 | Page :
28 | Browser :
29 | Wallet :
30 | OS :
31 | Device :
32 | Steps to reproduce :
33 | Expected result :
34 | Actual result :
35 | Screenshot :
36 | Severity :
37 | Expected Behavior
38 |
39 |
40 |
--------------------------------------------------------------------------------
/docs/JS.md:
--------------------------------------------------------------------------------
1 | # Javascript/TypeScript Notes
2 |
3 | A collection of notes about Javascript and Typescript.
4 |
5 | Please code in typescript, and use the `.ts` extension for files, and `.tsx` for react components.
6 |
7 | ## General
8 | - We use the default vs-code formatter to keep the code style consistent.
9 | - Type your variables and functions, and use the `strict` compiler option.
10 | - Avoid using `any` as much as possible.
11 | - Use `const` for variables that are not going to be reassigned.
12 | - Try to avoid using `var` and `let` as much as possible.
13 | - Code should be self explanatory, avoid using comments unless it's really necessary.
14 | - Use `===` instead of `==` to avoid type coercion.
15 | - Use `null` instead of `undefined` to avoid type coercion.
16 | - Always format your code before committing it.
17 | - - **Use absolute imports** instead of relative imports : `import { formatNumber } from 'src/utils'` instead of `import { formatNumber } from '../../utils'`.
18 |
19 |
20 | ## Naming conventions
21 | - Use camelCase for variables, functions, and filenames.
22 | - Use PascalCase for classes and interfaces.
23 | - Use UPPERCASE for constants and enums.
24 | - Use camelCase for properties, and methods.
25 |
26 |
27 | ## Code style
28 | - Use spaces instead of tabs.
29 | - Mark indentation with 2 spaces
30 | - Use single quotes for strings in js code and double quotes for jsx.
31 |
32 | ## Functions
33 | - Use arrow functions instead of function declarations.
34 | - Use default parameters instead of checking if the parameter is undefined.
35 | - Use rest parameters instead of the `arguments` object.
36 | - Use the spread operators
37 | - Use destructuring to access properties of objects and arrays.
38 | - Use param object destructuring rather than positional arguments.
39 |
40 |
41 | ## Asynchronous methods
42 | - Use `async`/`await` instead of `.then`/`.catch` to avoid callback hell.
43 | - Use `try`/`catch` to handle errors instead of `.catch` to avoid callback hell.
44 | - Use `Promise.all` to run multiple promises in parallel.
45 |
46 | ## Comments
47 | - Use `//` for single line comments.
48 | - Short comments are usually better, so try to keep them in one line of 60–80 characters.
49 | - Install the [Better Comments](https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments) or a similar extension to make your comments more readable.
50 | - Avoid using comments to explain what the code does, use descriptive variable names and functions instead.
51 | - Use comments to explain why the code is doing something, not how.
52 |
--------------------------------------------------------------------------------
/docs/REACT.md:
--------------------------------------------------------------------------------
1 | # React Notes
2 |
3 |
4 | ## General
5 | - **Use Typescript** for react components.
6 | - **Use the `strict` compiler option** to avoid type coercion.
7 | - **Use `null` instead of `undefined`** to avoid type coercion.
8 | - Always format your code before committing it.
9 |
10 |
11 | ## Imports
12 | - Keep imports sorted and grouped by type.
13 | - Group imports by type, first external imports, then internal imports, and finally same folder imports.
14 | - External imports: `import React from 'react'`
15 | - Internal imports: `import { Button } from 'src/components/Button'`
16 | - Same folder imports: `import { Button } from './Button'`
17 | - **Use absolute imports** instead of relative imports : `import { Button } from 'src/components/Button'` instead of `import { Button } from '../../components/Button'`.
18 |
19 |
20 | ## Components
21 | - **Use functional components** instead of class components.
22 | - **Use hooks** instead of class components.
23 | - **Use React.memo** to avoid unnecessary re-renders.
24 | - **Use React.lazy** to lazy load components.
25 | - **Use React.Suspense** to lazy load components.
26 | - **Use React.Fragment** to avoid unnecessary divs.
27 | - **Use React.forwardRef** to forward refs to components.
28 | - **Don't use React.createContext** to create contexts, use the `useContext` hook instead.
29 | - **Deconstruct props** to avoid repeating `props` in the component.
30 | - **Don't use index for keys on lists** use a unique id instead.
31 | - **Don't create components inside other components** create them outside and import them.
32 |
33 |
34 | ## Naming conventions
35 | - **Components** Use PascalCase for components and filenames.
36 | - **Folders** Use camelCase for folders.
37 | - **Hooks** Use camelCase for hooks and their filenames.
38 | - **Files** Use camelCase for index.ts(x) and other files except for components
39 |
40 | ## Code style
41 | - **Spacing** Use spaces instead of tabs.
42 | - **Indentation** Use 2 spaces for indentation.
43 | - **Quotes** Use single quotes for strings in js code and double quotes for jsx.
44 |
45 | ## Principles
46 | - **Single responsibility principle** A component should only have one responsibility.
47 | - **Composition** Components should be composed instead of inheriting from other components.
48 | - **Separation of concerns** Components should be separated by concerns.
49 | - **Don't repeat yourself** Avoid repeating code.
50 | - **Keep it simple** Keep components simple and easy to understand, avoid complex components. If a component is too complex, break it down into smaller components.
51 | - **Keep it small** Keep components small, avoid having too many lines of code in a single component, think about atomic design.
52 |
53 |
54 |
--------------------------------------------------------------------------------
/docs/TRANSLATIONS.md:
--------------------------------------------------------------------------------
1 | # Translation notes
2 |
3 | Are you interested in translating the website to your language? Here are some notes that might help you.
4 |
5 | ## Path
6 | All the translations are located in the `src/locales` folder. Each language has its own file, for example, the English version is located in `src/locales/en.json`.
7 |
8 | ## Structure
9 | The structure of the file could be as follows:
10 |
11 | ```json
12 | {
13 | "key": "value",
14 | "key2": "value2",
15 | "key3": {
16 | "key4": "value4"
17 | },
18 | "labels" : {
19 | "under_dev": "Under development"
20 | }
21 | }
22 | ```
23 |
24 | ## Developer or non-developer
25 | Are you a developer, or do you understand how to use git?
26 | - You can fork the repository, add your translation and create a pull request.
27 | - You can edit the file and create a pull request.
28 |
29 | If you are not a developer, You can easily download the file and edit it with a text editor. Then you can send it to us on CawBuilders (Telegram)[https://t.me/cawbuilders] and we will add it to the website.
--------------------------------------------------------------------------------
/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | reactStrictMode: true,
4 | swcMinify: true,
5 | images: {
6 | domains: [ 'images.unsplash.com', 'https://pbs.twimg.com', 'https://picsum.photos', 'https://caw.is', 'https://nightly-eyes.vercel' , 'https://teh-eyes.vercel' ],
7 | },
8 | env: {
9 | NETWORK: process.env.NETWORK,
10 | INFURA_API_KEY: process.env.INFURA_API_KEY,
11 | ALCHEMY_API_KEY: process.env.ALCHEMY_API_KEY,
12 | CAW_CONTRACT: process.env.CAW_CONTRACT,
13 | CAW_NAME_CONTRACT: process.env.CAW_NAME_CONTRACT,
14 | CAW_NAME_MINTER_CONTRACT: process.env.CAW_NAME_MINTER_CONTRACT,
15 | MINTABLE_CAW_CONTRACT: process.env.MINTABLE_CAW_CONTRACT,
16 | },
17 | async redirects() {
18 | return [
19 | {
20 | source: '/app',
21 | destination: '/app/home',
22 | permanent: true,
23 | },
24 | ]
25 | },
26 | }
27 |
28 | // module.exports = nextConfig
29 |
30 | // eslint-disable-next-line @typescript-eslint/no-var-requires
31 | const withBundleAnalyzer = require('@next/bundle-analyzer')({
32 | enabled: process.env.ANALYZE === 'true',
33 | openAnalyzer: true,
34 | });
35 |
36 | module.exports = withBundleAnalyzer(nextConfig);
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "caw-frontend",
3 | "author": {
4 | "name": "Teh CAWMmunity",
5 | "url": "https://caw.is"
6 | },
7 | "description": "Cawnect teh world",
8 | "version": "0.1.1",
9 | "private": false,
10 | "license": "MIT",
11 | "scripts": {
12 | "dev": "npm run lint:es && next dev -p 8082",
13 | "build": "next build",
14 | "start": "next start -p 8082",
15 | "lint": "next lint",
16 | "lint:es": "eslint --ext .ts,.tsx ."
17 | },
18 | "resolutions": {
19 | "ethereumjs-abi": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz"
20 | },
21 | "pnpm": {
22 | "overrides": {
23 | "ethereumjs-abi": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz"
24 | }
25 | },
26 | "dependencies": {
27 | "@alch/alchemy-web3": "^1.4.6",
28 | "@chakra-ui/icons": "^2.0.14",
29 | "@chakra-ui/react": "^2.4.4",
30 | "@emotion/react": "^11.10.4",
31 | "@emotion/styled": "^11.10.4",
32 | "@iconify/react": "^4.0.0",
33 | "@metamask/detect-provider": "^2.0.0",
34 | "@next/bundle-analyzer": "^13.1.6",
35 | "@rainbow-me/rainbowkit": "^0.10.0",
36 | "date-fns": "^2.29.3",
37 | "eslint-config-next": "^13.1.1",
38 | "ethers": "^5.7.2",
39 | "framer-motion": "^7.6.1",
40 | "i18next": "^22.0.2",
41 | "i18next-browser-languagedetector": "^6.1.8",
42 | "lodash.debounce": "^4.0.8",
43 | "next": "^13.1.1",
44 | "react": "^18.2.0",
45 | "react-blockies": "^1.4.1",
46 | "react-dom": "^18.2.0",
47 | "react-hook-form": "^7.39.4",
48 | "react-i18next": "^11.18.6",
49 | "sharp": "^0.31.3",
50 | "use-debounce": "^8.0.4",
51 | "wagmi": "^0.10.0"
52 | },
53 | "devDependencies": {
54 | "@types/lodash.debounce": "^4.0.7",
55 | "@types/node": "18.8.4",
56 | "@types/react": "18.0.21",
57 | "@types/react-dom": "18.0.6",
58 | "@typescript-eslint/eslint-plugin": "^5.40.0",
59 | "@typescript-eslint/parser": "^5.40.0",
60 | "eslint": "^8.25.0",
61 | "eslint-config-prettier": "^8.5.0",
62 | "prettier": "^2.7.1",
63 | "typescript": "4.8.4"
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/public/assets/images/cawnet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/assets/images/cawnet.png
--------------------------------------------------------------------------------
/public/assets/images/img_placeholder.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/images/intro.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/assets/images/intro.jpeg
--------------------------------------------------------------------------------
/public/assets/images/overlay.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/assets/screens/screen_dark_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/assets/screens/screen_dark_1.png
--------------------------------------------------------------------------------
/public/assets/screens/screen_dark_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/assets/screens/screen_dark_2.png
--------------------------------------------------------------------------------
/public/assets/screens/screen_dark_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/assets/screens/screen_dark_3.png
--------------------------------------------------------------------------------
/public/assets/tokens/caw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/assets/tokens/caw.png
--------------------------------------------------------------------------------
/public/assets/tokens/eth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/assets/tokens/eth.png
--------------------------------------------------------------------------------
/public/assets/tokens/mcaw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/assets/tokens/mcaw.png
--------------------------------------------------------------------------------
/public/assets/videos/intro.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/assets/videos/intro.mp4
--------------------------------------------------------------------------------
/public/assets/videos/intro_caw.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/assets/videos/intro_caw.mp4
--------------------------------------------------------------------------------
/public/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #f7c034
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/favicon.ico
--------------------------------------------------------------------------------
/public/favicon/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/favicon/android-chrome-192x192.png
--------------------------------------------------------------------------------
/public/favicon/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/favicon/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/favicon/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/favicon/favicon-16x16.png
--------------------------------------------------------------------------------
/public/favicon/favicon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/favicon/favicon-180x180.png
--------------------------------------------------------------------------------
/public/favicon/favicon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/favicon/favicon-192x192.png
--------------------------------------------------------------------------------
/public/favicon/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/favicon/favicon-32x32.png
--------------------------------------------------------------------------------
/public/favicon/favicon-apple-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/favicon/favicon-apple-180x180.png
--------------------------------------------------------------------------------
/public/favicon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/favicon/favicon.ico
--------------------------------------------------------------------------------
/public/favicon/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/favicon/mstile-150x150.png
--------------------------------------------------------------------------------
/public/fonts/CircularStd-Bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/fonts/CircularStd-Bold.otf
--------------------------------------------------------------------------------
/public/fonts/CircularStd-Book.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/fonts/CircularStd-Book.otf
--------------------------------------------------------------------------------
/public/fonts/CircularStd-Medium.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/fonts/CircularStd-Medium.otf
--------------------------------------------------------------------------------
/public/fonts/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/fonts/Roboto-Bold.ttf
--------------------------------------------------------------------------------
/public/fonts/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/fonts/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/public/fonts/index.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'CircularStd';
3 | font-weight: 400;
4 | font-style: normal;
5 | src: local('CircularStd'), url('CircularStd-Book.otf') format('opentype');
6 | }
7 | @font-face {
8 | font-family: 'CircularStd';
9 | font-weight: 500;
10 | font-style: normal;
11 | src: local('CircularStd'), url('CircularStd-Medium.otf') format('opentype');
12 | }
13 | @font-face {
14 | font-family: 'CircularStd';
15 | font-weight: 700;
16 | font-style: normal;
17 | src: local('CircularStd'), url('CircularStd-Bold.otf') format('opentype');
18 | }
19 |
--------------------------------------------------------------------------------
/public/icons/bell.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icons/bookmark.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icons/chat.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icons/dextools.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/icons/dextools.ico
--------------------------------------------------------------------------------
/public/icons/etherscan.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/icons/etherscan.ico
--------------------------------------------------------------------------------
/public/icons/hash.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icons/home-heart.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icons/ic_flag_de.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icons/ic_flag_en.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icons/ic_flag_es.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icons/ic_flag_pl.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icons/list.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icons/settings.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icons/uniswap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/icons/uniswap.png
--------------------------------------------------------------------------------
/public/icons/user.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/logo.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/logo.jpeg
--------------------------------------------------------------------------------
/public/logo/logo_single.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawdevelopment/caw-front/dd85b358b1d0b64f9d0c8a34a9460fe3b2b3c4a5/public/logo/logo_single.png
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/public/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
20 |
--------------------------------------------------------------------------------
/public/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Decentralized Social Clearing House",
3 | "short_name": "caw",
4 | "display": "standalone",
5 | "start_url": "/",
6 | "theme_color": "#000000",
7 | "background_color": "#ffffff",
8 | "icons": [
9 | {
10 | "src": "favicon/favicon-32x32.png",
11 | "sizes": "32x32",
12 | "type": "image/png"
13 | },
14 | {
15 | "src": "favicon/favicon-180x180.png",
16 | "sizes": "180x180",
17 | "type": "image/png"
18 | },
19 | {
20 | "src": "favicon/favicon-192x192.png",
21 | "sizes": "192x192",
22 | "type": "image/png"
23 | },
24 | {
25 | "src": "favicon/android-chrome-192x192.png",
26 | "sizes": "192x192",
27 | "type": "image/png"
28 | }
29 | ]
30 | }
--------------------------------------------------------------------------------
/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/blocks/home/FlippingText.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 | import { Text, useToken, chakra } from "@chakra-ui/react";
3 | import { m } from "framer-motion";
4 |
5 | const items = [
6 | {
7 | id: 0,
8 | content: `BY`,
9 | pl: 3
10 | },
11 | {
12 | id: 1,
13 | content: "FOR",
14 | pl: 0
15 | },
16 | ];
17 |
18 | export function FlippingText({ textColor }: { textColor: string }) {
19 |
20 | const [ index, setIndex ] = useState(0);
21 | const color = useToken('colors', 'caw.dark');
22 |
23 | useEffect(() => {
24 |
25 | const id = setInterval(() => {
26 | setIndex((state) => {
27 | if (state >= items.length - 1)
28 | return 0;
29 | return state + 1;
30 | });
31 | }, 3000);
32 |
33 | return () => clearInterval(id);
34 | }, []);
35 |
36 | return (
37 |
42 |
48 | BUILT
49 |
57 |
58 | {`${items[ index ].content}`}
59 |
60 |
61 | {`TEH PPL`}
62 |
63 |
64 | );
65 | }
66 |
--------------------------------------------------------------------------------
/src/blocks/home/PoweredCard.tsx:
--------------------------------------------------------------------------------
1 | import { m } from 'framer-motion';
2 | import { Box, Center, useColorModeValue, Heading, Text, Stack, useToken, useMediaQuery } from '@chakra-ui/react';
3 | import Iconify from "src/components/icons/Iconify";
4 |
5 | type Props = {
6 | icon: string;
7 | title: string;
8 | description: string;
9 | index: number;
10 | };
11 |
12 | export default function PoweredCardInfo({ icon, title, description, index }: Props) {
13 |
14 | const mdSize = useToken('breakpoints', 'md');
15 | const [ isMd ] = useMediaQuery(`(min-width: ${mdSize})`)
16 | const iconColor = useColorModeValue('gray.900', 'gray.50');
17 | const pairCardColor = useColorModeValue('white', 'gray.800');
18 | const oddCardColor = useColorModeValue('gray.200', 'whiteAlpha.50');
19 | const titleColor = useColorModeValue('gray.700', 'gray.50');
20 | const subTitleColor = useColorModeValue('gray.600', 'gray.50');
21 | const bgCardColor = index % 2 === 0 ? oddCardColor : pairCardColor;
22 |
23 | return (
24 |
25 |
26 |
38 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | {title}
51 |
52 |
53 |
54 | {description}
55 |
56 |
57 |
58 |
59 |
60 | );
61 | }
--------------------------------------------------------------------------------
/src/blocks/post/Avatars.tsx:
--------------------------------------------------------------------------------
1 | import { Tooltip } from "@chakra-ui/react";
2 | import { motion } from 'framer-motion';
3 |
4 | import StoryStyledAvatar from "src/components/avatar/StoryStyledAvatar";
5 | import { useDappProvider } from "src/context/DAppConnectContext";
6 |
7 | const list = {
8 | visible: {
9 | opacity: 1,
10 | transition: {
11 | delayChildren: 1.5,
12 | staggerChildren: 0.1,
13 | },
14 | },
15 | hidden: {
16 | opacity: 0,
17 | },
18 | };
19 |
20 | const item = {
21 | visible: { opacity: 1, x: 0 },
22 | hidden: { opacity: 0, x: -10 },
23 | };
24 |
25 |
26 | const Avatars = () => {
27 |
28 | const { cawAccounts, changeCawAccount } = useDappProvider();
29 |
30 | return (
31 |
44 | {cawAccounts.map((acc) => (
45 |
59 |
64 | changeCawAccount(acc, true)}
68 | />
69 |
70 |
71 | ))}
72 |
73 | );
74 | };
75 |
76 | export default Avatars;
--------------------------------------------------------------------------------
/src/blocks/post/PostMenu.tsx:
--------------------------------------------------------------------------------
1 | import { Button, useColorModeValue, useToken } from '@chakra-ui/react';
2 | import { useTranslation } from "react-i18next";
3 |
4 | import Iconify from 'src/components/icons/Iconify';
5 | import MenuPopover from 'src/components/MenuPopover';
6 |
7 | export type Props = {
8 | postId: string;
9 | txId: string;
10 | onDelete?: VoidFunction;
11 | }
12 |
13 | export function PostMenu({ postId, txId, onDelete }: Props) {
14 |
15 | const { t } = useTranslation();
16 | const [ light, dark ] = useToken('colors', [ 'gray.600', 'gray.300' ]);
17 | const iconColor = useColorModeValue(light, dark);
18 |
19 | const handleReport = () => {
20 | console.log('report');
21 | }
22 |
23 | const handleDelete = () => {
24 | onDelete?.();
25 | }
26 |
27 | const handleBlockScan = () => {
28 | window.open(`https://etherscan.io/tx/${txId}`, '_blank');
29 | }
30 |
31 | return (
32 |
33 | }
37 | justifyContent="left"
38 | fontWeight="normal"
39 | fontSize="sm"
40 | onClick={handleDelete}
41 | >
42 | {t('buttons.btn_delete')}
43 |
44 | }
48 | justifyContent="left"
49 | fontWeight="normal"
50 | fontSize="sm"
51 | onClick={handleReport}
52 | >
53 | {t('buttons.btn_report')}
54 |
55 | }
59 | justifyContent="left"
60 | fontWeight="normal"
61 | fontSize="sm"
62 | onClick={handleBlockScan}
63 | >
64 | {t('buttons.btn_scan')}
65 |
66 |
67 | );
68 | }
69 |
--------------------------------------------------------------------------------
/src/blocks/post/index.tsx:
--------------------------------------------------------------------------------
1 | import { useCallback } from "react";
2 | import { Box, Divider, useColorModeValue, useToken } from "@chakra-ui/react";
3 |
4 | import PostContent from 'src/components/PostContent';
5 | import { TagType } from "src/components/tag-parser/parser";
6 | import { PostDto } from "src/types/community-feed";
7 | import PostAvatar from './PostAvatar';
8 | import PostActions from './PostActions';
9 |
10 | type Props = {
11 | post: PostDto
12 | };
13 |
14 | export default function Post({ post }: Props) {
15 |
16 | const [ htLight, htDark ] = useToken('colors', [ 'caw.800', 'caw.600' ]);
17 | const [ mtLight, mtDark ] = useToken('colors', [ 'red.600', 'red.500' ]);
18 | const [ urlLight, urlDark ] = useToken('colors', [ 'blue.600', 'blue.500' ]);
19 | const htColor = useColorModeValue(htLight, htDark);
20 | const mtColor = useColorModeValue(mtLight, mtDark);
21 | const urlColor = useColorModeValue(urlLight, urlDark);
22 |
23 | const { id, content, likes, votes, commentsCount, transactionHash, date, author } = post;
24 |
25 | const handleHashTagClicked = useCallback((ht: string, type: TagType, element: any) => {
26 | console.log(ht, type, element);
27 | }, []);
28 |
29 | const handleDeletePost = useCallback(() => {
30 | console.log('Delete post', id);
31 | }, [ id ]);
32 |
33 | return (
34 |
35 |
46 |
47 |
54 |
55 |
62 |
63 |
64 |
65 | );
66 | }
--------------------------------------------------------------------------------
/src/blocks/wall/index.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 | import { useTranslation } from "react-i18next";
3 | import { Box } from "@chakra-ui/react";
4 |
5 | import { posts } from 'src/utils/mock/wallposts'
6 | import NewPost from 'src/blocks/post/NewPost';
7 | import Post from 'src/blocks/post';
8 | import { PostDto } from 'src/types/community-feed';
9 |
10 | export default function WallPost() {
11 |
12 | //* Pagination rendering logic
13 | const { t } = useTranslation();
14 | const [ data, setData ] = useState([]);
15 | const [ loading, setLoading ] = useState(true);
16 |
17 | useEffect(() => {
18 |
19 | //* Load posts from API
20 | setTimeout(() => {
21 | setData(posts);
22 | setLoading(false);
23 | }, 50);
24 |
25 | }, []);
26 |
27 | return (
28 |
29 | {loading && {t('labels.loading')}
}
30 | {!loading && (
31 |
32 | )}
33 | {data.map((post) => (
34 |
37 | ))}
38 |
39 | );
40 | }
--------------------------------------------------------------------------------
/src/components/AlertMessage.tsx:
--------------------------------------------------------------------------------
1 | import { Alert, AlertDescription, AlertIcon, AlertTitle, Box, CloseButton, ResponsiveValue, Spacer, useDisclosure } from "@chakra-ui/react";
2 | import { WrapperFadeAnimation } from "./animate";
3 |
4 | type Props = {
5 | type: 'warning' | 'error' | 'success' | 'info' | 'loading';
6 | variant?: 'solid' | 'subtle' | 'left-accent' | 'top-accent';
7 | title?: string;
8 | message: string;
9 | showIcon?: boolean;
10 | showCloseButton?: boolean;
11 | maxWidth?: ResponsiveValue;
12 | }
13 |
14 | export default function AlertMessage({ type, title, message, variant, showIcon = true, maxWidth, showCloseButton = false }: Props) {
15 |
16 | const { isOpen: isVisible, onClose, } = useDisclosure({ defaultIsOpen: true });
17 |
18 | return (
19 |
23 |
28 | {showIcon && }
29 |
30 | {title && ({title})}
31 | {message}
32 |
33 |
34 | {showCloseButton && (
35 |
42 | )}
43 |
44 |
45 | );
46 | }
--------------------------------------------------------------------------------
/src/components/Block.tsx:
--------------------------------------------------------------------------------
1 | import { type ReactNode } from "react";
2 | import { Box, type SystemStyleObject, Text, useColorModeValue } from '@chakra-ui/react';
3 |
4 | export type BlockProps = {
5 | title?: string;
6 | subtitle?: string;
7 | children: ReactNode;
8 | sx?: SystemStyleObject
9 | sxContainer?: SystemStyleObject
10 | };
11 |
12 |
13 | export default function Block({ title, subtitle, sxContainer = { p: 8 }, sx = { p: 5 }, children }: BlockProps) {
14 |
15 | const bg = useColorModeValue('gray.200', 'whiteAlpha.50');
16 | const textColor = useColorModeValue('gray.600', 'gray.50');
17 | const borderColor = useColorModeValue('gray.100', 'gray.700');
18 |
19 | return (
20 |
21 |
31 | {title &&
37 | {title}
38 |
43 | {subtitle}
44 |
45 | }
46 | *': { mx: 1 },
53 | }}
54 | >
55 | {children}
56 |
57 |
58 | );
59 | }
60 |
--------------------------------------------------------------------------------
/src/components/CircularProgress.tsx:
--------------------------------------------------------------------------------
1 | import { CircularProgress, type CircularProgressProps, CircularProgressLabel } from "@chakra-ui/react";
2 |
3 | interface ProgressProps extends CircularProgressProps {
4 | text: string;
5 | value: number;
6 | color: string;
7 | }
8 |
9 | export default function CircularProgressWithLabel({ text, value, color, ...props }: ProgressProps) {
10 |
11 | return (
12 |
17 |
18 | {text}
19 |
20 |
21 | );
22 | }
--------------------------------------------------------------------------------
/src/components/ErrorBoundary.tsx:
--------------------------------------------------------------------------------
1 | import { ReactNode, Component } from 'react';
2 | import Page500 from 'src/pages/500';
3 |
4 | type Props = {
5 | children?: ReactNode;
6 | }
7 |
8 | interface State {
9 | hasError: boolean;
10 | }
11 |
12 | class ErrorBoundary extends Component {
13 |
14 | public state: State = {
15 | hasError: false
16 | };
17 |
18 | public static getDerivedStateFromError(): State {
19 | return { hasError: true };
20 | }
21 |
22 | public componentDidCatch(error: Error) {
23 | console.error('Uncaught error:', error);
24 | }
25 |
26 | public render() {
27 | if (this.state.hasError) {
28 | return ;
29 | }
30 |
31 | return this.props.children;
32 | }
33 | }
34 |
35 | export default ErrorBoundary;
36 |
--------------------------------------------------------------------------------
/src/components/Interface.Props.ts:
--------------------------------------------------------------------------------
1 | //! Created to avoid the use of chakra-ui types in the components since they are costly to import
2 |
3 | import { type BoxProps } from "@chakra-ui/react";
4 |
5 | export type Globals = "-moz-initial" | "inherit" | "initial" | "revert" | "revert-layer" | "unset";
6 | export type TextAlign = Globals | "center" | "end" | "justify" | "left" | "match-parent" | "right" | "start";
7 |
8 | export type iBoxProps = BoxProps;
--------------------------------------------------------------------------------
/src/components/Logo.tsx:
--------------------------------------------------------------------------------
1 | import { forwardRef } from 'react';
2 | import NextLink from 'next/link';
3 | import { BoxProps, Image } from "@chakra-ui/react";
4 |
5 | interface Props extends BoxProps {
6 | disabledLink?: boolean;
7 | }
8 |
9 | const Logo = forwardRef(({ disabledLink = false, sx }, ref) => {
10 |
11 | const logo = (
12 |
21 | );
22 |
23 | if (disabledLink) {
24 | return <>{logo}>;
25 | }
26 |
27 | return {logo};
28 | });
29 |
30 | Logo.displayName = 'Logo';
31 | export default Logo;
32 |
--------------------------------------------------------------------------------
/src/components/MenuPopover.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | Popover, PopoverTrigger, PopoverContent, PopoverBody, PopoverArrow, IconButton,
3 | Stack, Flex, useDisclosure, PlacementWithLogical
4 | } from '@chakra-ui/react';
5 | import Iconify from "src/components/icons/Iconify";
6 |
7 | type Props = {
8 | children: React.ReactNode;
9 | placement?: PlacementWithLogical;
10 | }
11 |
12 | export default function MenuPopover({ children, placement = "bottom" }: Props) {
13 |
14 | const { onOpen, onClose, isOpen } = useDisclosure()
15 |
16 | return (
17 |
18 |
26 |
27 | }
30 | variant="ghost"
31 | w="fit-content"
32 | />
33 |
34 |
35 |
36 |
37 |
38 | {children}
39 |
40 |
41 |
42 |
43 |
44 | );
45 | }
--------------------------------------------------------------------------------
/src/components/PostContent.tsx:
--------------------------------------------------------------------------------
1 | import { Text, useColorModeValue } from '@chakra-ui/react';
2 |
3 | import { TextAlign } from 'src/components/Interface.Props';
4 | import HashTagRender, { ActionTagEvent } from "./tag-parser";
5 |
6 | type Props = {
7 | align?: TextAlign;
8 | htStyle?: React.CSSProperties;
9 | mtStyle?: React.CSSProperties;
10 | urlStyle?: React.CSSProperties;
11 | onHashtagClick: ActionTagEvent;
12 | content: React.ReactNode[] | string;
13 | }
14 |
15 | export default function PostContent(props: Props) {
16 |
17 | const { align, htStyle, mtStyle, urlStyle, content, onHashtagClick } = props;
18 | const textColor = useColorModeValue('gray.900', 'gray.50');
19 |
20 | return (
21 |
27 |
33 | {content}
34 |
35 |
36 | );
37 |
38 | }
--------------------------------------------------------------------------------
/src/components/Stat.tsx:
--------------------------------------------------------------------------------
1 | import { Stat, StatArrow, StatHelpText, StatLabel, StatNumber } from "@chakra-ui/react";
2 |
3 | type Props = {
4 | label: string,
5 | value: string | React.ReactNode,
6 | showIndicator: boolean,
7 | indicatorType: 'increase' | 'decrease' | 'helper',
8 | indicatorValue: string,
9 | }
10 |
11 | function StatHelper({ type, value }: { type: 'increase' | 'decrease' | 'helper', value: string }) {
12 |
13 | if (type === 'helper')
14 | return (
15 |
16 | {value}
17 |
18 | );
19 |
20 | return (
21 |
22 |
23 | {value}
24 |
25 | );
26 | }
27 |
28 | export default function StatSummary(props: Props) {
29 |
30 | const { label, value, showIndicator, indicatorType, indicatorValue } = props;
31 |
32 | return (
33 |
34 | {label}
35 | {value}
36 | {showIndicator && }
37 |
38 | );
39 | }
--------------------------------------------------------------------------------
/src/components/animate/MotionContainer.tsx:
--------------------------------------------------------------------------------
1 | import { m, MotionProps } from 'framer-motion';
2 | import { Box, BoxProps } from '@chakra-ui/react';
3 | import { varContainer } from './variants';
4 |
5 | type IProps = BoxProps & MotionProps;
6 |
7 | export interface Props extends IProps {
8 | animate?: boolean;
9 | action?: boolean;
10 | }
11 |
12 | export default function MotionContainer({ animate, action = false, children, ...other }: Props) {
13 | if (action) {
14 | return (
15 |
22 | {children}
23 |
24 | );
25 | }
26 |
27 | return (
28 |
36 | {children}
37 |
38 | );
39 | }
40 |
--------------------------------------------------------------------------------
/src/components/animate/MotionLazyContainer.tsx:
--------------------------------------------------------------------------------
1 | import { ReactNode } from "react";
2 | import { LazyMotion } from 'framer-motion';
3 |
4 | // eslint-disable-next-line import/extensions
5 | const loadFeatures = () => import('./features.js').then((res) => res.default);
6 |
7 | type Props = {
8 | children: ReactNode;
9 | };
10 |
11 | export default function MotionLazyContainer({ children }: Props) {
12 | return (
13 |
14 | {children}
15 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/src/components/animate/MotionViewport.tsx:
--------------------------------------------------------------------------------
1 | import { type ReactNode } from 'react';
2 | import { m, type MotionProps } from 'framer-motion';
3 | import { Box, type BoxProps, useMediaQuery, useToken } from '@chakra-ui/react';
4 | import { varContainer } from '.';
5 |
6 |
7 | type IProps = BoxProps & MotionProps;
8 |
9 | interface Props extends IProps {
10 | children: ReactNode;
11 | disableAnimatedMobile?: boolean;
12 | }
13 |
14 | export default function MotionViewport({
15 | children,
16 | disableAnimatedMobile = true,
17 | ...other
18 | }: Props) {
19 |
20 | const mdSize = useToken('breakpoints', 'md');
21 | const [ isMd ] = useMediaQuery(`(min-width: ${mdSize})`)
22 |
23 | if (!isMd && disableAnimatedMobile) {
24 | return {children};
25 | }
26 |
27 | return (
28 |
36 | {children}
37 |
38 | );
39 | }
40 |
--------------------------------------------------------------------------------
/src/components/animate/ParallaxText.tsx:
--------------------------------------------------------------------------------
1 | import { useRef } from "react";
2 | import { wrap } from "@motionone/utils";
3 | import { m, useScroll, useSpring, useTransform, useMotionValue, useVelocity, useAnimationFrame } from "framer-motion";
4 | import { chakra } from "@chakra-ui/react";
5 |
6 |
7 | export interface ParallaxProps {
8 | children: React.ReactNode;
9 | baseVelocity: number;
10 | }
11 |
12 | export function ParallaxText({ children, baseVelocity = 100 }: ParallaxProps) {
13 |
14 | const baseX = useMotionValue(0);
15 | const { scrollY } = useScroll();
16 | const scrollVelocity = useVelocity(scrollY);
17 | const smoothVelocity = useSpring(scrollVelocity, { damping: 50, stiffness: 400 });
18 |
19 | const velocityFactor = useTransform(smoothVelocity, [ 0, 1000 ], [ 0, 5 ], { clamp: true });
20 |
21 | /**
22 | * This is a magic wrapping for the length of the card - you
23 | * have to replace for wrapping that works for you or dynamically
24 | * calculate
25 | */
26 | // const x = useTransform(baseX, (v) => `${wrap(-20, -45, v)}%`);
27 | const x = useTransform(baseX, (v) => `${wrap(-30, -0, v)}%`);
28 | const directionFactor = useRef(1);
29 | useAnimationFrame((t, delta) => {
30 |
31 | let moveBy = directionFactor.current * baseVelocity * (delta / 1000);
32 |
33 | /**
34 | * This is what changes the direction of the scroll once we
35 | * switch scrolling directions.
36 | */
37 | if (velocityFactor.get() < 0) {
38 | directionFactor.current = -1;
39 | } else if (velocityFactor.get() > 0) {
40 | directionFactor.current = 1;
41 | }
42 |
43 | moveBy += directionFactor.current * moveBy * velocityFactor.get();
44 |
45 | baseX.set(baseX.get() + moveBy);
46 | });
47 |
48 | /**
49 | * The number of times to repeat the child text should be dynamically calculated
50 | * based on the size of the text and viewport. Likewise, the x motion value is
51 | * currently wrapped between -20 and -45% - this 25% is derived from the fact
52 | * we have four children (100% / 4). This would also want deriving from the
53 | * dynamically generated number of children.
54 | */
55 | return (
56 |
57 |
58 | {children}
59 |
60 |
61 | );
62 | }
63 |
64 | export const ParallaxItemWrapper = ({ id, children }: { id: string, children: React.ReactNode }) => (
65 |
74 | {children}
75 |
76 | )
77 |
78 |
--------------------------------------------------------------------------------
/src/components/animate/WrapperFade.tsx:
--------------------------------------------------------------------------------
1 |
2 | import { motion, AnimatePresence, MotionStyle } from "framer-motion";
3 |
4 | type Props = {
5 | show: boolean;
6 | duration?: number;
7 | exitDuration?: number;
8 | children: React.ReactNode;
9 | sx?: MotionStyle
10 | }
11 |
12 | export default function WrapperFadeAnimation({ show, duration = 1.7, exitDuration, sx = { width: '100%' }, children }: Props) {
13 |
14 | return (
15 |
16 | {show ?
17 |
23 | {children}
24 |
25 | : null
26 | }
27 |
28 | );
29 | }
--------------------------------------------------------------------------------
/src/components/animate/features.js:
--------------------------------------------------------------------------------
1 | import { domMax } from 'framer-motion';
2 |
3 | export default domMax;
4 |
--------------------------------------------------------------------------------
/src/components/animate/index.ts:
--------------------------------------------------------------------------------
1 | export * from './variants';
2 | export { default as MotionContainer } from './MotionContainer';
3 | export { default as MotionLazyContainer } from './MotionLazyContainer';
4 | export { default as MotionViewport } from './MotionViewport';
5 | export { default as WrapperFadeAnimation } from './WrapperFade';
6 |
--------------------------------------------------------------------------------
/src/components/animate/type.ts:
--------------------------------------------------------------------------------
1 | type EaseType =
2 | | 'linear'
3 | | 'easeIn'
4 | | 'easeOut'
5 | | 'easeInOut'
6 | | 'circIn'
7 | | 'circOut'
8 | | 'circInOut'
9 | | 'backIn'
10 | | 'backOut'
11 | | 'backInOut'
12 | | 'anticipate'
13 | | number[];
14 |
15 | export type VariantsType = {
16 | distance?: number;
17 | durationIn?: number;
18 | durationOut?: number;
19 | easeIn?: EaseType;
20 | easeOut?: EaseType;
21 | };
22 |
23 | export type TranHoverType = {
24 | duration?: number;
25 | ease?: EaseType;
26 | };
27 |
28 | export type TranEnterType = {
29 | durationIn?: number;
30 | easeIn?: EaseType;
31 | };
32 |
33 | export type TranExitType = {
34 | durationOut?: number;
35 | easeOut?: EaseType;
36 | };
37 |
38 | export type BackgroundType = {
39 | colors?: string[];
40 | duration?: number;
41 | ease?: EaseType;
42 | };
43 |
--------------------------------------------------------------------------------
/src/components/animate/variants/actions.ts:
--------------------------------------------------------------------------------
1 |
2 | export const varHover = (scale?: number) => ({
3 | hover: {
4 | scale: scale || 1.1,
5 | },
6 | });
7 |
--------------------------------------------------------------------------------
/src/components/animate/variants/container.ts:
--------------------------------------------------------------------------------
1 |
2 | export type Props = {
3 | staggerIn?: number;
4 | delayIn?: number;
5 | staggerOut?: number;
6 | };
7 |
8 | export const varContainer = (props?: Props) => {
9 | const staggerIn = props?.staggerIn || 0.05;
10 | const delayIn = props?.staggerIn || 0.05;
11 | const staggerOut = props?.staggerIn || 0.05;
12 |
13 | return {
14 | animate: {
15 | transition: {
16 | staggerChildren: staggerIn,
17 | delayChildren: delayIn,
18 | },
19 | },
20 | exit: {
21 | transition: {
22 | staggerChildren: staggerOut,
23 | staggerDirection: -1,
24 | },
25 | },
26 | };
27 | };
28 |
--------------------------------------------------------------------------------
/src/components/animate/variants/flip.ts:
--------------------------------------------------------------------------------
1 | import { VariantsType } from '../type';
2 | import { varTranEnter, varTranExit } from './transition';
3 |
4 | export const varFlip = (props?: VariantsType) => {
5 | const durationIn = props?.durationIn;
6 | const durationOut = props?.durationOut;
7 | const easeIn = props?.easeIn;
8 | const easeOut = props?.easeOut;
9 |
10 | return {
11 | // IN
12 | inX: {
13 | initial: { rotateX: -180, opacity: 0 },
14 | animate: { rotateX: 0, opacity: 1, transition: varTranEnter({ durationIn, easeIn }) },
15 | exit: { rotateX: -180, opacity: 0, transition: varTranExit({ durationOut, easeOut }) },
16 | },
17 | inY: {
18 | initial: { rotateY: -180, opacity: 0 },
19 | animate: { rotateY: 0, opacity: 1, transition: varTranEnter({ durationIn, easeIn }) },
20 | exit: { rotateY: -180, opacity: 0, transition: varTranExit({ durationOut, easeOut }) },
21 | },
22 |
23 | // OUT
24 | outX: {
25 | initial: { rotateX: 0, opacity: 1 },
26 | animate: { rotateX: 70, opacity: 0, transition: varTranExit({ durationOut, easeOut }) },
27 | },
28 | outY: {
29 | initial: { rotateY: 0, opacity: 1 },
30 | animate: { rotateY: 70, opacity: 0, transition: varTranExit({ durationOut, easeOut }) },
31 | },
32 | };
33 | };
34 |
--------------------------------------------------------------------------------
/src/components/animate/variants/index.ts:
--------------------------------------------------------------------------------
1 | export * from './path';
2 | export * from './fade';
3 | export * from './zoom';
4 | export * from './flip';
5 | export * from './slide';
6 | export * from './scale';
7 | export * from './bounce';
8 | export * from './rotate';
9 | export * from './actions';
10 | export * from './container';
11 | export * from './transition';
12 | export * from './background';
13 |
--------------------------------------------------------------------------------
/src/components/animate/variants/path.ts:
--------------------------------------------------------------------------------
1 |
2 | export const TRANSITION = {
3 | duration: 2,
4 | ease: [ 0.43, 0.13, 0.23, 0.96 ],
5 | };
6 |
7 | export const varPath = {
8 | animate: {
9 | fillOpacity: [ 0, 0, 1 ],
10 | pathLength: [ 1, 0.4, 0 ],
11 | transition: TRANSITION,
12 | },
13 | };
14 |
--------------------------------------------------------------------------------
/src/components/animate/variants/rotate.ts:
--------------------------------------------------------------------------------
1 | import { VariantsType } from '../type';
2 | import { varTranEnter, varTranExit } from './transition';
3 |
4 | export const varRotate = (props?: VariantsType) => {
5 | const durationIn = props?.durationIn;
6 | const durationOut = props?.durationOut;
7 | const easeIn = props?.easeIn;
8 | const easeOut = props?.easeOut;
9 |
10 | return {
11 | // IN
12 | in: {
13 | initial: { opacity: 0, rotate: -360 },
14 | animate: { opacity: 1, rotate: 0, transition: varTranEnter({ durationIn, easeIn }) },
15 | exit: { opacity: 0, rotate: -360, transition: varTranExit({ durationOut, easeOut }) },
16 | },
17 |
18 | // OUT
19 | out: {
20 | initial: { opacity: 1, rotate: 0 },
21 | animate: { opacity: 0, rotate: -360, transition: varTranExit({ durationOut, easeOut }) },
22 | },
23 | };
24 | };
25 |
--------------------------------------------------------------------------------
/src/components/animate/variants/scale.ts:
--------------------------------------------------------------------------------
1 | import { VariantsType } from '../type';
2 | import { varTranEnter, varTranExit } from './transition';
3 |
4 | export const varScale = (props?: VariantsType) => {
5 | const durationIn = props?.durationIn;
6 | const durationOut = props?.durationOut;
7 | const easeIn = props?.easeIn;
8 | const easeOut = props?.easeOut;
9 |
10 | return {
11 | // IN
12 | inX: {
13 | initial: { scaleX: 0, opacity: 0 },
14 | animate: { scaleX: 1, opacity: 1, transition: varTranEnter({ durationIn, easeIn }) },
15 | exit: { scaleX: 0, opacity: 0, transition: varTranExit({ durationOut, easeOut }) },
16 | },
17 | inY: {
18 | initial: { scaleY: 0, opacity: 0 },
19 | animate: { scaleY: 1, opacity: 1, transition: varTranEnter({ durationIn, easeIn }) },
20 | exit: { scaleY: 0, opacity: 0, transition: varTranExit({ durationOut, easeOut }) },
21 | },
22 |
23 | // OUT
24 | outX: {
25 | initial: { scaleX: 1, opacity: 1 },
26 | animate: { scaleX: 0, opacity: 0, transition: varTranEnter({ durationIn, easeIn }) },
27 | },
28 | outY: {
29 | initial: { scaleY: 1, opacity: 1 },
30 | animate: { scaleY: 0, opacity: 0, transition: varTranEnter({ durationIn, easeIn }) },
31 | },
32 | };
33 | };
34 |
--------------------------------------------------------------------------------
/src/components/animate/variants/slide.ts:
--------------------------------------------------------------------------------
1 | import { VariantsType } from '../type';
2 | import { varTranEnter, varTranExit } from './transition';
3 |
4 | export const varSlide = (props?: VariantsType) => {
5 | const distance = props?.distance || 160;
6 | const durationIn = props?.durationIn;
7 | const durationOut = props?.durationOut;
8 | const easeIn = props?.easeIn;
9 | const easeOut = props?.easeOut;
10 |
11 | return {
12 | // IN
13 | inUp: {
14 | initial: { y: distance },
15 | animate: { y: 0, transition: varTranEnter({ durationIn, easeIn }) },
16 | exit: { y: distance, transition: varTranExit({ durationOut, easeOut }) },
17 | },
18 | inDown: {
19 | initial: { y: -distance },
20 | animate: { y: 0, transition: varTranEnter({ durationIn, easeIn }) },
21 | exit: { y: -distance, transition: varTranExit({ durationOut, easeOut }) },
22 | },
23 | inLeft: {
24 | initial: { x: -distance },
25 | animate: { x: 0, transition: varTranEnter({ durationIn, easeIn }) },
26 | exit: { x: -distance, transition: varTranExit({ durationOut, easeOut }) },
27 | },
28 | inRight: {
29 | initial: { x: distance },
30 | animate: { x: 0, transition: varTranEnter({ durationIn, easeIn }) },
31 | exit: { x: distance, transition: varTranExit({ durationOut, easeOut }) },
32 | },
33 |
34 | // OUT
35 | outUp: {
36 | initial: { y: 0 },
37 | animate: { y: -distance, transition: varTranEnter({ durationIn, easeIn }) },
38 | exit: { y: 0, transition: varTranExit({ durationOut, easeOut }) },
39 | },
40 | outDown: {
41 | initial: { y: 0 },
42 | animate: { y: distance, transition: varTranEnter({ durationIn, easeIn }) },
43 | exit: { y: 0, transition: varTranExit({ durationOut, easeOut }) },
44 | },
45 | outLeft: {
46 | initial: { x: 0 },
47 | animate: { x: -distance, transition: varTranEnter({ durationIn, easeIn }) },
48 | exit: { x: 0, transition: varTranExit({ durationOut, easeOut }) },
49 | },
50 | outRight: {
51 | initial: { x: 0 },
52 | animate: { x: distance, transition: varTranEnter({ durationIn, easeIn }) },
53 | exit: { x: 0, transition: varTranExit({ durationOut, easeOut }) },
54 | },
55 | };
56 | };
57 |
--------------------------------------------------------------------------------
/src/components/animate/variants/transition.ts:
--------------------------------------------------------------------------------
1 | import { TranHoverType, TranEnterType, TranExitType } from '../type';
2 |
3 | export const varTranHover = (props?: TranHoverType) => {
4 | const duration = props?.duration || 0.32;
5 | const ease = props?.ease || [ 0.43, 0.13, 0.23, 0.96 ];
6 |
7 | return { duration, ease };
8 | };
9 |
10 | export const varTranEnter = (props?: TranEnterType) => {
11 | const duration = props?.durationIn || 0.64;
12 | const ease = props?.easeIn || [ 0.43, 0.13, 0.23, 0.96 ];
13 |
14 | return { duration, ease };
15 | };
16 |
17 | export const varTranExit = (props?: TranExitType) => {
18 | const duration = props?.durationOut || 0.48;
19 | const ease = props?.easeOut || [ 0.43, 0.13, 0.23, 0.96 ];
20 |
21 | return { duration, ease };
22 | };
23 |
--------------------------------------------------------------------------------
/src/components/avatar/Avatar.tsx:
--------------------------------------------------------------------------------
1 | import { Avatar, SystemStyleObject } from '@chakra-ui/react'
2 | import { MediaType } from 'src/types/community-feed'
3 |
4 | export type Props = {
5 | size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full' | '2xs'
6 | src?: string
7 | name?: string
8 | color?: string
9 | sx?: SystemStyleObject,
10 | type?: MediaType
11 | }
12 |
13 | export default function UserAvatar(props: Props) {
14 |
15 | const { size = "md", src, name = "", color, sx } = props;
16 | return (
17 |
18 | );
19 | }
--------------------------------------------------------------------------------
/src/components/avatar/StoryStyledAvatar.tsx:
--------------------------------------------------------------------------------
1 | import { motion } from 'framer-motion';
2 | import { useColorModeValue, useToken } from "@chakra-ui/react";
3 |
4 | type Props = {
5 | src: string,
6 | alt: string,
7 | height?: string,
8 | width?: string,
9 | onClick?: () => void,
10 | }
11 |
12 | const item = {
13 | visible: { opacity: 1, x: 0 },
14 | hidden: { opacity: 0, x: -10 },
15 | };
16 |
17 |
18 | export default function StoryStyledAvatar({ src, alt, height = '3.125rem', width = '3.125rem', onClick }: Props) {
19 |
20 | const [ PRIMARY_MAIN, PRIMARY_DARKER, BORDER_LOGO ] = useToken('colors', [ 'caw.main', 'caw.darker', 'caw.border' ]);
21 | const bg = useColorModeValue('cawAlpha.400', 'cawAlpha.50');
22 | const hoverBg = useColorModeValue(BORDER_LOGO, PRIMARY_MAIN);
23 |
24 | return (
25 |
33 |
47 |

59 |
60 |
61 | );
62 | }
--------------------------------------------------------------------------------
/src/components/buttons/Button.tsx:
--------------------------------------------------------------------------------
1 | import { Button, ButtonProps } from '@chakra-ui/react';
2 |
3 | export default function StyledButton(props: ButtonProps) {
4 | return (
5 |
14 | );
15 | }
--------------------------------------------------------------------------------
/src/components/contract/avatars/MyAvatar.tsx:
--------------------------------------------------------------------------------
1 |
2 | import { SystemStyleObject } from "@chakra-ui/react";
3 | import Blockies from 'react-blockies';
4 |
5 | import StoryStyledAvatar from "src/components/avatar/StoryStyledAvatar";
6 | import { useDappProvider } from "src/context/DAppConnectContext";
7 |
8 | type Props = {
9 | sx?: SystemStyleObject;
10 | }
11 |
12 | export default function MyAvatar({ sx }: Props) {
13 |
14 | const { connected, cawAccount, address } = useDappProvider();
15 |
16 | if (!connected) {
17 | return (
18 | );
23 | }
24 |
25 | return (
26 |
30 | );
31 | }
--------------------------------------------------------------------------------
/src/components/contract/modals/ProtocolCostModal.tsx:
--------------------------------------------------------------------------------
1 | import { useTranslation } from "react-i18next";
2 | import { Modal, ModalContent, ModalOverlay, ModalHeader, ModalCloseButton, ModalBody, ModalFooter } from "@chakra-ui/react";
3 |
4 | import ProtocolCost from "./ProtocolCost";
5 |
6 | export type ProtocolCostModalProps = {
7 | isOpen: boolean;
8 | onClose: () => void;
9 | }
10 |
11 | export default function ProtocolCostModal({ isOpen, onClose }: ProtocolCostModalProps) {
12 |
13 | const { t } = useTranslation();
14 | return (
15 |
22 |
23 |
24 |
25 |
26 | {t('calc.title')}
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | );
36 | }
37 |
--------------------------------------------------------------------------------
/src/components/contract/stats/CawPrice.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 |
3 | import StatSummary from 'src/components/Stat';
4 | import { useAsync } from 'src/hooks';
5 | import { getCawPriceInUsd } from 'src/hooks/contracts/helper';
6 | import { tokenPriceSS } from "src/utils/formatNumber";
7 |
8 | type Props = {
9 | watch: boolean;
10 | }
11 |
12 | export default function CawCurrentPrice({ watch }: Props) {
13 |
14 | const { execute, value: cawPrice } = useAsync(getCawPriceInUsd, false);
15 |
16 | useEffect(() => {
17 | execute();
18 | }, [ execute ]);
19 |
20 | //* Update price every 1 minute
21 | useEffect(() => {
22 |
23 | if (!watch)
24 | return;
25 |
26 | const interval = setInterval(() => {
27 | execute();
28 | }, 60000);
29 |
30 | return () => clearInterval(interval);
31 | }, [ cawPrice, watch, execute ]);
32 |
33 | const priceFormated = `$${tokenPriceSS(Number(cawPrice || 0), 12)}`;
34 |
35 | return (
36 |
43 | );
44 | }
--------------------------------------------------------------------------------
/src/components/contract/stats/EthPrice.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 |
3 | import StatSummary from 'src/components/Stat';
4 | import { useAsync } from 'src/hooks';
5 | import { fCurrency } from 'src/utils/formatNumber';
6 | import { getEthPriceInUsd } from 'src/hooks/contracts/helper';
7 |
8 | type Props = {
9 | watch: boolean;
10 | }
11 |
12 | export default function CawCurrentPrice({ watch }: Props) {
13 |
14 | const { execute, value: ethPrice } = useAsync(getEthPriceInUsd, false);
15 |
16 | useEffect(() => {
17 | execute();
18 | }, [ execute ]);
19 |
20 | //* Update price every 1 minute
21 | useEffect(() => {
22 |
23 | if (!watch)
24 | return;
25 |
26 | const interval = setInterval(() => {
27 | execute();
28 | }, 60000);
29 |
30 | return () => clearInterval(interval);
31 | }, [ ethPrice, watch, execute ]);
32 |
33 |
34 | return (
35 |
42 | );
43 | }
--------------------------------------------------------------------------------
/src/components/contract/stats/NftPrice.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 |
3 | import { useAsync } from "src/hooks";
4 | import StatSummary from 'src/components/Stat';
5 | import { getCawPriceInUsd } from "src/hooks/contracts/helper";
6 | import { fCurrency, superScript } from 'src/utils/formatNumber';
7 | import { NftCostInUsdByLength } from "src/utils/manifestoHelper";
8 | import { Tooltip } from "@chakra-ui/react";
9 |
10 | const characterNums = 8;
11 | const characters = superScript(characterNums);
12 |
13 | type Props = {
14 | watch: boolean;
15 | }
16 |
17 | export default function NftPrice({ watch }: Props) {
18 |
19 | const { execute, status, value: price } = useAsync(getCawPriceInUsd, false);
20 |
21 | useEffect(() => {
22 | execute();
23 | }, [ execute ]);
24 |
25 |
26 | //* Update price every 1 minute
27 | useEffect(() => {
28 |
29 | if (!watch)
30 | return;
31 |
32 | const interval = setInterval(() => {
33 | execute();
34 | }, 60000);
35 |
36 | return () => clearInterval(interval);
37 | }, [ price, watch, execute ]);
38 |
39 | const cawCost = status === 'success' ? NftCostInUsdByLength(characterNums, price || 0) : -1;
40 |
41 | return (
42 |
45 |
46 | 0 ? fCurrency(cawCost) : "..."}
49 | showIndicator={false}
50 | indicatorType={"decrease"}
51 | indicatorValue={""}
52 | />
53 |
54 |
55 | );
56 | }
--------------------------------------------------------------------------------
/src/components/contract/wallet/BrowserMessageModal.tsx:
--------------------------------------------------------------------------------
1 | import { useTranslation } from "react-i18next";
2 | import dynamic from "next/dynamic";
3 |
4 | import { sentenceCase } from "src/utils/helper";
5 |
6 | export const AlertDialogConfirm = dynamic(() => import("src/components/dialogs/AlertDialog"), { ssr: false });
7 |
8 |
9 | export function BrowserMessageModal({ isOpen, onClose, openConnectModal }: { isOpen: boolean; onClose: () => void; openConnectModal: () => void; }) {
10 |
11 | const { t } = useTranslation();
12 | return (
13 | {t('errors.mobileBrowserNotSupported')}} />
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/src/components/dialogs/AlertDialog.tsx:
--------------------------------------------------------------------------------
1 | import { useRef } from "react";
2 | import {
3 | Button, AlertDialog, AlertDialogBody, AlertDialogFooter, AlertDialogHeader, AlertDialogContent,
4 | AlertDialogOverlay, AlertDialogCloseButton
5 | } from '@chakra-ui/react';
6 |
7 | type Props = {
8 | isOpen: boolean;
9 | title: string;
10 | body: string | React.ReactNode;
11 | cancelText?: string;
12 | cancelColorScheme?: string;
13 | confirmText?: string;
14 | confirmColorScheme?: string;
15 | onClose: () => void;
16 | onConfirm: () => void;
17 | }
18 |
19 | export default function AlertDialogConfirm(props: Props) {
20 |
21 | const { isOpen, title, body = `Are you sure? You can't undo this action afterwards.`, cancelText = 'Cancel', cancelColorScheme, confirmText = 'Confirm', confirmColorScheme = 'red', onClose } = props;
22 | const cancelRef = useRef();
23 |
24 | const handleConfirm = () => {
25 | onClose();
26 | props.onConfirm();
27 | }
28 |
29 | return (
30 | <>
31 |
38 |
39 |
40 |
41 | {title}
42 |
43 |
44 |
45 |
46 | {body}
47 |
48 |
49 |
50 |
53 |
56 |
57 |
58 |
59 | >
60 | );
61 | }
--------------------------------------------------------------------------------
/src/components/dialogs/BlockChainOperationInProgressModal.tsx:
--------------------------------------------------------------------------------
1 | import { CircularProgressProps, Text, Code } from "@chakra-ui/react";
2 | import { useTranslation } from "react-i18next";
3 |
4 | import OperationInProgressModal from "./OperationInProgress";
5 |
6 | export type BCOProps = {
7 | message: string;
8 | processing: boolean;
9 | txSent: boolean;
10 | circularProps?: CircularProgressProps;
11 | onClose: () => void;
12 | }
13 |
14 | export default function BlockChainOperationInProgressModal({ processing, txSent, onClose, message, circularProps }: BCOProps) {
15 | const { t } = useTranslation();
16 | return (
17 | {t('wallet.waitConfirmedTx')} : {t('wallet.confirmTxInWallet')}
}
22 | circularProps={circularProps}
23 | onClose={onClose} />
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/src/components/dialogs/OperationInProgress.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | Modal, ModalOverlay, ModalContent, ModalBody, ModalCloseButton, ModalFooter,
3 | Heading, Text, CircularProgress, CircularProgressProps, VStack
4 | } from "@chakra-ui/react";
5 |
6 | type Props = {
7 | title: string;
8 | message: string;
9 | footer: string | React.ReactNode;
10 | isOpen: boolean;
11 | circularProps?: CircularProgressProps;
12 | onClose: () => void;
13 | }
14 |
15 | export default function OperationInProgressModal(props: Props) {
16 |
17 | const { title, message, footer, isOpen, onClose,
18 | circularProps = {
19 | isIndeterminate: true,
20 | size: '80px',
21 | thickness: '4px',
22 | color: 'blue.500',
23 | } } = props;
24 |
25 | return (
26 |
34 |
35 |
36 |
37 |
38 |
41 |
42 | {title}
43 | {message}
44 |
45 |
46 |
49 | {footer}
50 |
51 |
52 |
53 | );
54 | }
55 |
--------------------------------------------------------------------------------
/src/components/icons/IconButtonAnimate.tsx:
--------------------------------------------------------------------------------
1 | import { m } from 'framer-motion';
2 | import { forwardRef, ReactNode } from 'react';
3 | import { Box, IconButton, IconButtonProps, ResponsiveValue } from '@chakra-ui/react';
4 |
5 | type AnimateWrapProp = {
6 | children: ReactNode;
7 | size: ResponsiveValue
8 | };
9 |
10 | const varSmall = {
11 | hover: { scale: 1.1 },
12 | tap: { scale: 0.95 },
13 | };
14 |
15 | const varMedium = {
16 | hover: { scale: 1.09 },
17 | tap: { scale: 0.97 },
18 | };
19 |
20 | const varLarge = {
21 | hover: { scale: 1.08 },
22 | tap: { scale: 0.99 },
23 | };
24 |
25 | function AnimateWrap({ size, children }: AnimateWrapProp) {
26 | const isSmall = size === 'small';
27 | const isLarge = size === 'large';
28 |
29 | return (
30 |
39 | {children}
40 |
41 | );
42 | }
43 |
44 | const IconButtonAnimate = forwardRef(
45 | ({ children, size = 'medium', ...other }, ref) => (
46 |
47 |
48 | {children}
49 |
50 |
51 | )
52 | );
53 |
54 | export default IconButtonAnimate;
55 |
--------------------------------------------------------------------------------
/src/components/icons/Iconify.tsx:
--------------------------------------------------------------------------------
1 | import { Icon } from '@iconify/react';
2 | import { Box, BoxProps, useColorMode, useToken } from '@chakra-ui/react'
3 |
4 | interface Props extends BoxProps {
5 | icon: string;
6 | rotate?: number;
7 | width?: number;
8 | height?: number;
9 | color?: string;
10 | }
11 |
12 |
13 | export default function Iconify({ icon, sx, rotate = 180, width = 24, height = 24, color, ...others }: Props) {
14 |
15 | const { colorMode } = useColorMode();
16 | const [ light, dark ] = useToken('colors', [ 'gray.600', 'gray.500' ]);
17 |
18 | return (
19 |
22 |
29 |
30 | );
31 | }
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/components/loaders/PageLoader.tsx:
--------------------------------------------------------------------------------
1 | import type { FC } from 'react';
2 | import NextImage from 'next/image';
3 |
4 | import PageWrapper from 'src/components/wrappers/Page';
5 |
6 | const Loading: FC = () => (
7 |
15 |
26 |
27 | )
28 |
29 | export default Loading;
30 |
--------------------------------------------------------------------------------
/src/components/settings/LanguagePopover.tsx:
--------------------------------------------------------------------------------
1 | import { Text, HStack, Button, Menu, MenuButton, MenuItem, MenuList, Image, useColorModeValue } from "@chakra-ui/react";
2 | import useLocales from "src/hooks/useLocale";
3 |
4 | type LanguagePopoverProps = {
5 | bgIPopover?: string;
6 | }
7 |
8 | export default function LanguagePopover({ bgIPopover }: LanguagePopoverProps) {
9 |
10 | const { allLang, currentLang, onChangeLang } = useLocales();
11 | const bgMenuItemHover = useColorModeValue('gray.200', 'gray.600');
12 | const bgMenuItem = useColorModeValue('cawAlpha.300', 'cawAlpha.300');
13 | const bgMenuList = useColorModeValue('gray.100', 'gray.800');
14 |
15 | return (
16 |
62 | );
63 | }
--------------------------------------------------------------------------------
/src/components/settings/ToogleMode.tsx:
--------------------------------------------------------------------------------
1 | import { Button, ButtonProps, useColorMode } from '@chakra-ui/react';
2 | import Iconify from "src/components/icons/Iconify";
3 |
4 | export default function ColorModeToggle(props: ButtonProps) {
5 |
6 | const { colorMode, toggleColorMode } = useColorMode();
7 |
8 | return (
9 |
19 | );
20 | }
--------------------------------------------------------------------------------
/src/components/sidebar/MobileNav.tsx:
--------------------------------------------------------------------------------
1 | import { IconButton, Flex, useColorModeValue, FlexProps, useToken } from '@chakra-ui/react';
2 | import { HamburgerIcon } from '@chakra-ui/icons';
3 |
4 | import Logo from "src/components/Logo";
5 | import TopBarMenuButton from "src/components/topbar/menu";
6 |
7 |
8 | export interface MobileProps extends FlexProps {
9 | onOpen: () => void;
10 | }
11 |
12 | export default function MobileNav({ onOpen, ...rest }: MobileProps): JSX.Element {
13 |
14 | const bg = useColorModeValue('white', 'gray.900');
15 | const borderColor = useColorModeValue('gray.200', 'gray.700');
16 | const textColor = useColorModeValue('gray.50', 'gray.50');
17 | const [ icLight, icDark ] = useToken('colors', [ 'gray.500', 'gray.500' ]);
18 | const menuItemIconColor = useColorModeValue(icLight, icDark);
19 |
20 | return (
21 |
32 | }
37 | />
38 |
39 |
44 |
45 | );
46 | }
47 |
--------------------------------------------------------------------------------
/src/components/sidebar/NavItem.tsx:
--------------------------------------------------------------------------------
1 | import { usePathname } from "next/navigation";
2 | import NextLink from 'next/link'
3 | import { Flex, FlexProps, Text, useColorModeValue, useToken } from '@chakra-ui/react';
4 |
5 | import Iconify from 'src/components/icons/Iconify';
6 |
7 | export interface NavItemProps extends FlexProps {
8 | icon: string;
9 | name: string;
10 | link: string;
11 |
12 | }
13 |
14 | export default function NavItem({ icon, link, name, ...rest }: NavItemProps) {
15 |
16 | const pathname = usePathname();
17 | const selected = pathname === link;
18 | const [ iconColor ] = useToken('colors', [ 'caw.600' ]);
19 | const bg = useColorModeValue('cawAlpha.400', 'cawAlpha.300');
20 | const hoverBg = useColorModeValue('blackAlpha.50', 'whiteAlpha.50');
21 | const bgSel = useColorModeValue('caw.400', 'caw.900');
22 | const textColor = useColorModeValue('gray.700', 'gray.50');
23 | const textColorSelected = useColorModeValue('gray.600', 'caw.800');
24 |
25 | return (
26 |
31 |
46 |
47 |
51 | {name}
52 |
53 |
54 |
55 | );
56 | }
57 |
--------------------------------------------------------------------------------
/src/components/sidebar/SidebarContent.tsx:
--------------------------------------------------------------------------------
1 | import { useTranslation } from "react-i18next";
2 | import { chakra, Box, CloseButton, Flex, useColorModeValue, BoxProps, Spacer, Stack } from '@chakra-ui/react';
3 |
4 | import Logo from 'src/components/Logo';
5 | import ColorModeToggle from "src/components/settings/ToogleMode";
6 | import { LinkItems } from "./menu";
7 | import NavItem from "./NavItem";
8 | import NavbarAccount from '../contract/wallet/NavbarAccount';
9 |
10 | export interface SidebarProps extends BoxProps {
11 | onClose: () => void;
12 | }
13 |
14 | export default function SidebarContent({ onClose, ...rest }: SidebarProps) {
15 |
16 | const { t } = useTranslation();
17 | const bg = useColorModeValue('white', 'gray.900');
18 | const borderColor = useColorModeValue('gray.200', 'gray.700');
19 |
20 | return (
21 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
43 | {LinkItems.map((link) => (
44 |
50 | ))}
51 |
52 |
67 |
68 |
69 | );
70 | }
71 |
--------------------------------------------------------------------------------
/src/components/sidebar/menu.ts:
--------------------------------------------------------------------------------
1 | import { PATH_DASHBOARD } from 'src/routes/paths';
2 |
3 | export interface LinkItemProps {
4 | name: string;
5 | icon: string;
6 | link: string;
7 | }
8 |
9 | //* Get icons from https://icon-sets.iconify.design/
10 | export const LinkItems: Array = [
11 | {
12 | name: 'sidebar_menu.home',
13 | icon: 'ci:home-heart-1',
14 | link: PATH_DASHBOARD.app.home
15 | },
16 | {
17 | name: 'sidebar_menu.explore',
18 | icon: 'clarity:hashtag-solid',
19 | link: PATH_DASHBOARD.app.explore
20 | },
21 | {
22 | name: 'sidebar_menu.notifications',
23 | icon: 'clarity:bell-solid',
24 | link: PATH_DASHBOARD.app.notifications
25 | },
26 | {
27 | name: 'sidebar_menu.messages',
28 | icon: 'bi:chat-square-heart-fill',
29 | link: PATH_DASHBOARD.app.messages
30 | },
31 | {
32 | name: 'sidebar_menu.bookmarks',
33 | icon: 'bxs:bookmark-heart',
34 | link: PATH_DASHBOARD.app.bookmarks
35 | },
36 | {
37 | name: 'sidebar_menu.lists',
38 | icon: 'fa:th-list',
39 | link: PATH_DASHBOARD.app.lists
40 | },
41 | {
42 | name: 'sidebar_menu.profile',
43 | icon: 'carbon:user-filled',
44 | link: PATH_DASHBOARD.app.accounts
45 | },
46 | {
47 | name: 'sidebar_menu.more',
48 | icon: 'fluent:more-circle-32-filled',
49 | link: PATH_DASHBOARD.app.settings
50 | },
51 | ];
--------------------------------------------------------------------------------
/src/components/tag-parser/parser.ts:
--------------------------------------------------------------------------------
1 | export type TagType = '@' | '#' | '$' | 'url';
2 | export type ActionTagEvent = (ht: string, type: TagType, element: any) => void;
3 |
4 | const rule = /([#@$\bwww\bhttp|#@$\bwww\bhttp][^\s]+)/g;
5 |
6 | type parserProps = {
7 | value: any,
8 | htRenderer: any,
9 | linkRenderer: any,
10 | atRenderer: any,
11 | stockRenderer: any,
12 | action: ActionTagEvent,
13 | }
14 |
15 | export const parse = ({ value, htRenderer, linkRenderer, atRenderer, stockRenderer, action }: parserProps) => {
16 |
17 | if (!value?.split)
18 | return value;
19 |
20 | const hts = value.split(rule).map((chunk: string) => {
21 |
22 | if (chunk.match(rule)) {
23 | if (chunk.includes('@'))
24 | return atRenderer(chunk, action);
25 |
26 | if (chunk.includes('#'))
27 | return htRenderer(chunk, action);
28 |
29 | if (chunk.includes('$'))
30 | return stockRenderer(chunk, action);
31 |
32 | if (chunk.includes('http') || chunk.includes('www'))
33 | return linkRenderer(chunk, action);
34 |
35 | return chunk;
36 | }
37 | return chunk;
38 | });
39 |
40 | return hts;
41 | };
--------------------------------------------------------------------------------
/src/components/topbar/menu/BuyCawItem.tsx:
--------------------------------------------------------------------------------
1 | import { useTranslation } from "react-i18next";
2 | import { useDisclosure } from '@chakra-ui/react';
3 | import dynamic from "next/dynamic";
4 |
5 | import MenuItem from "./MenuItem";
6 |
7 | const BuyCawModal = dynamic(() => import("src/components/contract/modals/BuyCawModal"), { ssr: false });
8 |
9 | type Props = {
10 | iconColor: string;
11 | useIcon: boolean;
12 | }
13 |
14 | export default function BuyCawItem({ iconColor, useIcon }: Props) {
15 |
16 | const { t } = useTranslation();
17 | const { isOpen, onOpen, onClose } = useDisclosure();
18 |
19 | return (
20 | <>
21 |
28 |
29 | >
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/src/components/topbar/menu/CalculatorItem.tsx:
--------------------------------------------------------------------------------
1 | import { useDisclosure } from '@chakra-ui/react';
2 | import dynamic from "next/dynamic";
3 |
4 | import MenuItem from "./MenuItem";
5 |
6 | const ProtocolCostModal = dynamic(() => import("src/components/contract/modals/ProtocolCostModal"), { ssr: false });
7 |
8 | type Props = {
9 | iconColor: string;
10 | useIcon: boolean;
11 | }
12 |
13 | export default function CalculatorItem({ iconColor, useIcon }: Props) {
14 |
15 | const { isOpen, onOpen, onClose } = useDisclosure();
16 | return (
17 | <>
18 |
25 |
26 | >
27 | );
28 | }
29 |
--------------------------------------------------------------------------------
/src/components/topbar/menu/MenuItem.tsx:
--------------------------------------------------------------------------------
1 | import { useColorModeValue, Text, Link, ListItem, HStack, Spacer } from '@chakra-ui/react';
2 | import NextLink from 'next/link'
3 |
4 | import Iconify from "src/components/icons/Iconify";
5 |
6 | export type MenuItemProps = {
7 | useIcon: boolean,
8 | icon: string,
9 | iconColor: string,
10 | label: string,
11 | useLink: boolean,
12 | href?: string,
13 | isExternal?: boolean,
14 | onClick?: () => void,
15 | }
16 |
17 | export default function MenuItem({ useLink, href, useIcon = true, icon, iconColor, label, isExternal, onClick }: MenuItemProps) {
18 |
19 | const hoverColor = useColorModeValue('blackAlpha.50', 'whiteAlpha.100');
20 |
21 | return (
22 |
23 |
31 |
37 | {useIcon && icon && iconColor && }
38 |
39 |
40 | {label}
41 |
42 |
43 |
44 |
45 | );
46 | }
47 |
--------------------------------------------------------------------------------
/src/components/topbar/menu/MoreLinksItems.tsx:
--------------------------------------------------------------------------------
1 | import { useTranslation } from "react-i18next";
2 | import { useDisclosure } from '@chakra-ui/react';
3 | import dynamic from "next/dynamic";
4 |
5 | import MenuItem from "./MenuItem";
6 |
7 | const UsefulLinksModal = dynamic(() => import("src/components/contract/modals/UsefulLinksModal"), { ssr: false });
8 |
9 | type Props = {
10 | iconColor: string;
11 | useIcon: boolean;
12 | }
13 |
14 | export default function MoreLinksItems({ iconColor, useIcon }: Props) {
15 |
16 | const { t } = useTranslation();
17 | const { isOpen, onOpen, onClose } = useDisclosure();
18 |
19 | return (
20 | <>
21 |
29 |
30 | >
31 | );
32 | }
33 |
--------------------------------------------------------------------------------
/src/components/topbar/menu/QuickMintUserNameItem.tsx:
--------------------------------------------------------------------------------
1 | import { useTranslation } from "react-i18next";
2 | import { useDisclosure } from '@chakra-ui/react';
3 |
4 | import { QuickMintingUserName } from "src/components/contract/modals/QuickMintUserName";
5 | import MenuItem from "./MenuItem";
6 |
7 | type Props = {
8 | iconColor: string;
9 | useIcon: boolean;
10 | }
11 |
12 | export default function QuickMintUserNameItem({ iconColor, useIcon }: Props) {
13 |
14 | const { t } = useTranslation();
15 | const { isOpen, onOpen, onClose } = useDisclosure();
16 |
17 | return (
18 | <>
19 |
27 |
28 | >
29 | );
30 | }
31 |
--------------------------------------------------------------------------------
/src/components/wrappers/PopoverWrapper.tsx:
--------------------------------------------------------------------------------
1 | import { Hide, Show, Modal, ModalBody, ModalCloseButton, ModalContent, ModalOverlay, ModalHeader, ModalFooter } from "@chakra-ui/react";
2 |
3 | type Props = {
4 | children: React.ReactNode,
5 | footer?: React.ReactNode,
6 | isOpen: boolean,
7 | onClose: () => void
8 | isCentered?: boolean,
9 | wrapAbove: 'xs' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl' | '8xl' | '9xl' | 'full';
10 | scrollBehavior?: 'inside' | 'outside';
11 | }
12 |
13 | export default function PopoverWrapperInModal(props: Props) {
14 |
15 | const { children, footer, isCentered, scrollBehavior = 'inside', isOpen, onClose, wrapAbove } = props;
16 |
17 | return (
18 | <>
19 |
20 |
27 |
28 |
29 |
30 |
31 |
32 | {children}
33 |
34 |
35 | {footer}
36 |
37 |
38 |
39 |
40 |
41 | {children}
42 |
43 | >
44 | );
45 | }
--------------------------------------------------------------------------------
/src/config/ABIs/CAW_NAME_MINTER.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [
4 | {
5 | "internalType": "address",
6 | "name": "_caw",
7 | "type": "address"
8 | },
9 | {
10 | "internalType": "address",
11 | "name": "_cawNames",
12 | "type": "address"
13 | }
14 | ],
15 | "stateMutability": "nonpayable",
16 | "type": "constructor"
17 | },
18 | {
19 | "inputs": [
20 | {
21 | "internalType": "string",
22 | "name": "username",
23 | "type": "string"
24 | }
25 | ],
26 | "name": "costOfName",
27 | "outputs": [
28 | {
29 | "internalType": "uint256",
30 | "name": "",
31 | "type": "uint256"
32 | }
33 | ],
34 | "stateMutability": "pure",
35 | "type": "function"
36 | },
37 | {
38 | "inputs": [
39 | {
40 | "internalType": "string",
41 | "name": "",
42 | "type": "string"
43 | }
44 | ],
45 | "name": "idByUsername",
46 | "outputs": [
47 | {
48 | "internalType": "uint64",
49 | "name": "",
50 | "type": "uint64"
51 | }
52 | ],
53 | "stateMutability": "view",
54 | "type": "function"
55 | },
56 | {
57 | "inputs": [
58 | {
59 | "internalType": "string",
60 | "name": "_input",
61 | "type": "string"
62 | }
63 | ],
64 | "name": "isValidUsername",
65 | "outputs": [
66 | {
67 | "internalType": "bool",
68 | "name": "",
69 | "type": "bool"
70 | }
71 | ],
72 | "stateMutability": "pure",
73 | "type": "function"
74 | },
75 | {
76 | "inputs": [
77 | {
78 | "internalType": "string",
79 | "name": "username",
80 | "type": "string"
81 | }
82 | ],
83 | "name": "mint",
84 | "outputs": [],
85 | "stateMutability": "nonpayable",
86 | "type": "function"
87 | }
88 | ]
--------------------------------------------------------------------------------
/src/config/index.ts:
--------------------------------------------------------------------------------
1 | import CAW_ABI from './ABIs/CAW.json';
2 | import CAW_NAMES_ABI from './ABIs/CAW_NAME.json';
3 | import MINTABLE_CAW_ABI from './ABIs/MINTABLE_CAW.json';
4 | import CAW_NAME_MINTER_ABI from './ABIs/CAW_NAME_MINTER.json';
5 |
6 | export {
7 | CAW_ABI,
8 | CAW_NAMES_ABI,
9 | MINTABLE_CAW_ABI,
10 | CAW_NAME_MINTER_ABI,
11 | }
--------------------------------------------------------------------------------
/src/config/siteSettings.ts:
--------------------------------------------------------------------------------
1 | import {
2 | MintableCAW_CONTRACT, CawName_CONTRACT, CawActions_CONTRACT,
3 | CawNameURI_CONTRACT, CawNameMinter_CONTRACT, AHuntersDream_CONTRACT, DEFAULT_JSON_RPC_URL
4 | } from 'src/utils/constants'
5 | import { CAW_ABI, CAW_NAMES_ABI, MINTABLE_CAW_ABI, CAW_NAME_MINTER_ABI } from 'src/config';
6 |
7 |
8 | export function AppEnvSettings() {
9 |
10 | const NETWORK = String(process.env.NETWORK || '').toLowerCase();
11 | const INFURA_API_KEY = String(process.env.INFURA_API_KEY);
12 | const ALCHEMY_API_KEY = String(process.env.ALCHEMY_API_KEY);
13 |
14 | const ENVIRONMENT = String(process.env.ENVIRONMENT || '').toLowerCase();
15 | const JSON_RPC_URL = String(process.env.JSON_RPC_URL || DEFAULT_JSON_RPC_URL);
16 |
17 | return {
18 | keys: {
19 | INFURA_API_KEY,
20 | ALCHEMY_API_KEY,
21 | },
22 | network: NETWORK,
23 | environment: ENVIRONMENT,
24 | jsonRpcUrl: JSON_RPC_URL,
25 | contracts: {
26 | CAW: {
27 | address: AHuntersDream_CONTRACT,
28 | abi: CAW_ABI,
29 | },
30 | CAW_NAME: {
31 | address: CawName_CONTRACT,
32 | abi: CAW_NAMES_ABI,
33 | },
34 | CAW_ACTIONS: {
35 | address: CawActions_CONTRACT,
36 | },
37 | CAW_NAME_URI: {
38 | address: CawNameURI_CONTRACT,
39 | },
40 | CAW_NAME_MINTER: {
41 | address: CawNameMinter_CONTRACT,
42 | abi: CAW_NAME_MINTER_ABI,
43 | },
44 | MINTABLE_CAW: {
45 | address: MintableCAW_CONTRACT,
46 | abi: MINTABLE_CAW_ABI,
47 | }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/hooks/contracts/useAccountBalance.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState, useCallback } from "react";
2 |
3 | import { WalletBalanceModel } from "src/types/dtos";
4 | import { WalletBalanceInterface } from "src/interface/WalletBalanceInterface";
5 | import useAppConfigurations from "../useAppConfigurations";
6 |
7 | type Props = {
8 | connected: boolean;
9 | address: string;
10 | chainId: number;
11 | chainName: string;
12 | // onBalanceChange?: (balance: WalletBalanceModel[]) => void;
13 | }
14 |
15 | export default function useAccountBalance({ address, connected, chainId, chainName }: Props) {
16 |
17 | const [ assets, setAssets ] = useState(WalletBalanceInterface.getInitialtBalance());
18 | const [ processing, setProcessing ] = useState(false);
19 | const { provider } = useAppConfigurations();
20 |
21 | useEffect(() => {
22 |
23 | if (!connected || !address)
24 | setAssets(() => WalletBalanceInterface.getInitialtBalance());
25 |
26 | }, [ connected, address ]);
27 |
28 | // useEffect(() => {
29 | // onBalanceChange?.(assets);
30 | // }, [ assets, onBalanceChange ]);
31 |
32 | const fetchBalance = useCallback(async () => {
33 | try {
34 |
35 | if (!address || !chainId || !chainName) {
36 | setAssets(() => WalletBalanceInterface.getInitialtBalance());
37 | return;
38 | }
39 |
40 | setProcessing(true);
41 | const accountBalance = new WalletBalanceInterface(address, chainId, chainName, provider);
42 |
43 | const eth_prom = accountBalance.getEthBalance();
44 | const caw_prom = accountBalance.getCawBalance();
45 | const mcaw_prom = accountBalance.getMintableCawBalance();
46 |
47 | const [ eth, caw, mcaw ] = await Promise.all([ eth_prom, caw_prom, mcaw_prom ]);
48 |
49 | setAssets((prev) => prev.map(asset => {
50 |
51 | if (asset.symbol === 'ETH') {
52 | return { ...asset, amount: eth }
53 | }
54 |
55 | if (asset.symbol === 'CAW') {
56 | return { ...asset, amount: caw }
57 | }
58 |
59 | if (asset.symbol === 'mCAW') {
60 | return { ...asset, amount: mcaw }
61 | }
62 |
63 | return { ...asset };
64 | }));
65 |
66 | setProcessing(false);
67 | }
68 | catch (error) {
69 | console.log('Error: ', error);
70 | setAssets(() => WalletBalanceInterface.getInitialtBalance());
71 | setProcessing(false);
72 | }
73 | }, [ address, chainId, chainName, provider ]);
74 |
75 |
76 | useEffect(() => {
77 | fetchBalance();
78 | }, [ fetchBalance ]);
79 |
80 | return {
81 | assets,
82 | processing,
83 | }
84 | }
--------------------------------------------------------------------------------
/src/hooks/contracts/useETHBalance.ts:
--------------------------------------------------------------------------------
1 | import { useCallback, useEffect, useState } from "react";
2 | import { WalletBalanceInterface } from "src/interface/WalletBalanceInterface";
3 | import useAppConfigurations from "../useAppConfigurations";
4 |
5 | type Props = {
6 | account: string;
7 | chainId: number;
8 | chainName: string;
9 | onSuccess?: (balance: number, data: any) => void;
10 | onError?: (error: any) => void;
11 | }
12 |
13 | export default function useETHBalance({ account, chainId, chainName, onSuccess, onError }: Props) {
14 |
15 | const [ balance, setBalance ] = useState(0);
16 | const [ fetchingETH, setFetchingETH ] = useState(false);
17 | const { provider } = useAppConfigurations();
18 |
19 | const getEthBalance = useCallback(async () => {
20 |
21 | if (!account) {
22 | setBalance(0);
23 | onError && onError('Account not connected');
24 | return;
25 | }
26 |
27 | if (!chainId || !chainName) {
28 | setBalance(0);
29 | onError && onError('Chain not valid');
30 | return;
31 | }
32 |
33 | try {
34 | setFetchingETH(true);
35 | const accountBalance = new WalletBalanceInterface(account, chainId, chainName, provider);
36 | const bal = await accountBalance.getEthBalance();
37 | setBalance(() => bal);
38 | onSuccess && onSuccess(bal, null);
39 | }
40 | catch (error) {
41 | console.error(`ETH->Balance.error`, error);
42 | setBalance(0);
43 | onError && onError(error);
44 | }
45 | finally {
46 | setFetchingETH(false);
47 | }
48 | }, [ account, chainId, chainName, provider, onError, onSuccess ]);
49 |
50 |
51 | useEffect(() => {
52 | getEthBalance();
53 | }, [ getEthBalance ]);
54 |
55 |
56 | return {
57 | fetchETH: getEthBalance,
58 | balance,
59 | fetchingETH,
60 | };
61 | }
62 |
--------------------------------------------------------------------------------
/src/hooks/index.ts:
--------------------------------------------------------------------------------
1 | import { useTranslation } from "react-i18next/";
2 | import { useToast } from "@chakra-ui/react";
3 |
4 | // * Generics
5 | import useLocale from './useLocale'
6 | import { useLocalStorage } from "./useLocalStorage";
7 | import useAsync from './useAsync';
8 | import useDebounce from './useDebounce';
9 | import { useDebounceEffect } from './useDebounceEffect';
10 | import useIsMounted from './useIsMounted';
11 | import useOnClickOutside from './useOnClickOutside';
12 |
13 | //* App Configurations
14 | import useAppConfigurations from './useAppConfigurations'
15 |
16 | //* Contracts / Blockchain
17 | import useCawNameMinterContract from './contracts/useCawNameMinterContract';
18 | import useCawNamesContract from './contracts/useCawNamesContract';
19 | import useMintableCAWContract from './contracts/useMintableCAWContract';
20 | import useETHBalance from './contracts/useETHBalance';
21 | import useAccountBalance from './contracts/useAccountBalance';
22 |
23 |
24 | export {
25 | useLocalStorage,
26 | useLocale,
27 | useAsync,
28 | useDebounce,
29 | useDebounceEffect,
30 | useIsMounted,
31 | useOnClickOutside,
32 | useAppConfigurations,
33 | useCawNameMinterContract,
34 | useCawNamesContract,
35 | useMintableCAWContract,
36 | useETHBalance,
37 | useAccountBalance,
38 | useTranslation,
39 | useToast
40 | }
--------------------------------------------------------------------------------
/src/hooks/useAppConfigurations.ts:
--------------------------------------------------------------------------------
1 |
2 | import { useNetwork ,useProvider} from "wagmi";
3 | import { AppEnvSettings } from "src/config/siteSettings";
4 |
5 | export default function useAppConfigurations() {
6 |
7 | const { chain } = useNetwork();
8 | const provider = useProvider();
9 |
10 | const _v = AppEnvSettings()
11 | const _env = _v.environment;
12 | return {
13 | ..._v,
14 | provider : provider,
15 | allowMainnet: ((chain?.id || 0) === 1) ? (_env === 'production' || _env === 'live') && (_v.network === 'mainnet') : true,
16 | };
17 | }
--------------------------------------------------------------------------------
/src/hooks/useAsync.ts:
--------------------------------------------------------------------------------
1 | import { useCallback, useEffect, useState } from "react";
2 |
3 | type status = "idle" | "pending" | "success" | "error";
4 |
5 | //* Shoutout to https://usehooks.com/
6 | export default function useAsync(asyncFunction: any, immediate: boolean) {
7 |
8 | const [ status, setStatus ] = useState("idle");
9 | const [ value, setValue ] = useState(null);
10 | const [ error, setError ] = useState(null);
11 |
12 | // The execute function wraps asyncFunction and
13 | // handles setting state for pending, value, and error.
14 | // useCallback ensures the below useEffect is not called
15 | // on every render, but only if asyncFunction changes.
16 | const execute = useCallback(() => {
17 | setStatus("pending");
18 | setValue(null);
19 | setError(null);
20 |
21 | return asyncFunction()
22 | .then((response: any) => {
23 | setValue(response);
24 | setStatus("success");
25 | })
26 | .catch((error: any) => {
27 | setError(error);
28 | setStatus("error");
29 | });
30 | }, [ asyncFunction ]);
31 |
32 | // Call execute if we want to fire it right away.
33 | // Otherwise execute can be called later, such as
34 | // in an onClick handler.
35 | useEffect(() => {
36 | if (immediate) {
37 | execute();
38 | }
39 | }, [ execute, immediate ]);
40 |
41 | return { execute, status, value, error };
42 | };
--------------------------------------------------------------------------------
/src/hooks/useDebounce.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 |
3 | //* Shoutout to https://usehooks.com/
4 | export default function useDebounce(value: any, delay: number) {
5 |
6 | const [ debouncedValue, setDebouncedValue ] = useState(value);
7 |
8 | useEffect(
9 | () => {
10 |
11 | // Update debounced value after delay
12 | const handler = setTimeout(() => {
13 | setDebouncedValue(value);
14 | }, delay);
15 |
16 | // Cancel the timeout if value changes (also on delay change or unmount)
17 | // This is how we prevent debounced value from updating if value is changed ...
18 | // .. within the delay period. Timeout gets cleared and restarted.
19 | return () => {
20 | clearTimeout(handler);
21 | };
22 | },
23 | [ value, delay ] // Only re-call effect if value or delay changes
24 | );
25 |
26 | return debouncedValue;
27 | }
--------------------------------------------------------------------------------
/src/hooks/useDebounceEffect.tsx:
--------------------------------------------------------------------------------
1 | import type { DependencyList, EffectCallback } from 'react';
2 | import { useEffect } from 'react';
3 |
4 | export const useDebounceEffect = (effect: EffectCallback, delay: number, deps?: DependencyList): void => {
5 | useEffect(() => {
6 | const handler = setTimeout(() => effect(), delay);
7 |
8 | return () => clearTimeout(handler);
9 | // using || operator because
10 | // if its optional then it can be undefined.
11 | // eslint-disable-next-line react-hooks/exhaustive-deps
12 | }, [ ...(deps || []), delay ]);
13 | };
14 |
--------------------------------------------------------------------------------
/src/hooks/useIsMounted.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react';
2 |
3 | const useIsMounted = () => {
4 | const [ mounted, setMounted ] = useState(false);
5 |
6 | useEffect(() => {
7 | setMounted(true);
8 | }, []);
9 |
10 | return { mounted };
11 | };
12 |
13 | export default useIsMounted;
14 |
--------------------------------------------------------------------------------
/src/hooks/useLocalStorage.ts:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 |
3 | export function useLocalStorage(key: string, initialValue: T) {
4 |
5 | // State to store our value
6 | // Pass initial state function to useState so logic is only executed once
7 | const [ storedValue, setStoredValue ] = useState(() => {
8 | if (typeof window === "undefined") {
9 | return initialValue;
10 | }
11 |
12 | try {
13 | // Get from local storage by key
14 | const item = window.localStorage.getItem(key);
15 | // Parse stored json or if none return initialValue
16 | return item ? JSON.parse(item) : initialValue;
17 | } catch (error) {
18 | // If error also return initialValue
19 | console.log(error);
20 | return initialValue;
21 | }
22 | });
23 |
24 | // Return a wrapped version of useState's setter function that ...
25 | // ... persists the new value to localStorage.
26 | const setValue = (value: T | ((val: T) => T)) => {
27 | try {
28 | // Allow value to be a function so we have same API as useState
29 | const valueToStore =
30 | value instanceof Function ? value(storedValue) : value;
31 | // Save state
32 | setStoredValue(valueToStore);
33 | // Save to local storage
34 | if (typeof window !== "undefined") {
35 | window.localStorage.setItem(key, JSON.stringify(valueToStore));
36 | }
37 | } catch (error) {
38 | // A more advanced implementation would handle the error case
39 | console.log(error);
40 | }
41 | };
42 | return [ storedValue, setValue ] as const;
43 | }
--------------------------------------------------------------------------------
/src/hooks/useLocale.ts:
--------------------------------------------------------------------------------
1 | import { useTranslation } from 'react-i18next';
2 |
3 | const LANGS = [
4 | {
5 | label: 'English',
6 | value: 'en',
7 | icon: '/icons/ic_flag_en.svg',
8 | },
9 | {
10 | label: 'Español',
11 | value: 'es',
12 | icon: '/icons/ic_flag_es.svg',
13 | },
14 | {
15 | label: 'Polski',
16 | value: 'pl',
17 | icon: '/icons/ic_flag_pl.svg',
18 | },
19 | // {
20 | // label: 'Deutsch',
21 | // value: 'de',
22 | // icon: '/icons/ic_flag_de.svg',
23 | // },
24 | ];
25 |
26 | export default function useLocales() {
27 |
28 | const { i18n, t } = useTranslation();
29 | const langStorage = (typeof window !== 'undefined') ? localStorage.getItem('i18nextLng') : 'en';
30 | const currentLang = LANGS.find((_lang) => _lang.value === langStorage) || LANGS[ 0 ];
31 |
32 | const handleChangeLanguage = (newlang: string) => {
33 | i18n.changeLanguage(newlang);
34 | };
35 |
36 | return {
37 | onChangeLang: handleChangeLanguage,
38 | t,
39 | currentLang,
40 | allLang: LANGS,
41 | };
42 | }
43 |
--------------------------------------------------------------------------------
/src/hooks/useOnClickOutside.tsx:
--------------------------------------------------------------------------------
1 | import type { RefObject } from 'react';
2 | import { useEffect } from 'react';
3 |
4 | type AnyEvent = MouseEvent | TouchEvent;
5 |
6 | const useOnClickOutside = (
7 | ref: RefObject,
8 | handler: (event: AnyEvent) => void
9 | ): void => {
10 | useEffect(() => {
11 | const listener = (event: AnyEvent) => {
12 | const el = ref?.current;
13 |
14 | // Do nothing if clicking ref's element or descendent elements
15 | if (!el || el.contains(event.target as Node)) {
16 | return;
17 | }
18 |
19 | handler(event);
20 | };
21 |
22 | document.addEventListener(`mousedown`, listener);
23 | document.addEventListener(`touchstart`, listener);
24 |
25 | return () => {
26 | document.removeEventListener(`mousedown`, listener);
27 | document.removeEventListener(`touchstart`, listener);
28 | };
29 |
30 | // Reload only if ref or handler changes
31 | }, [ ref, handler ]);
32 | };
33 |
34 | export default useOnClickOutside;
35 |
--------------------------------------------------------------------------------
/src/layouts/DashboardLayout.tsx:
--------------------------------------------------------------------------------
1 |
2 | import SideBar from 'src/components/sidebar';
3 |
4 | type Props = {
5 | children: React.ReactNode;
6 | }
7 |
8 | export default function DashboardLayout({ children }: Props) {
9 |
10 | return (
11 |
12 | {children}
13 |
14 | );
15 | }
--------------------------------------------------------------------------------
/src/layouts/LogoOnlyLayout.tsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 | import { Box, Center, Flex, Spacer, useColorModeValue } from '@chakra-ui/react';
3 |
4 | import LanguagePopover from "src/components/settings/LanguagePopover";
5 | import ColorModeToggle from "src/components/settings/ToogleMode";
6 | import Logo from 'src/components/Logo';
7 | import WalletOptions from 'src/components/contract/wallet/Wallet';
8 |
9 | type Props = {
10 | children?: React.ReactNode;
11 | };
12 |
13 | export default function LogoOnlyLayout({ children }: Props) {
14 |
15 | const bg = useColorModeValue('gray.50', 'gray.900');
16 | const [ scroll, setScroll ] = useState(false);
17 |
18 | const changeScroll = () =>
19 | document.body.scrollTop > 80 || document.documentElement.scrollTop > 80
20 | ? setScroll(true)
21 | : setScroll(false);
22 |
23 | useEffect(() => {
24 |
25 | if (window)
26 | window.addEventListener?.('scroll', changeScroll);
27 |
28 | return () => {
29 |
30 | if (window)
31 | window.removeEventListener?.('scroll', changeScroll);
32 | };
33 |
34 | }, [ scroll ]);
35 |
36 |
37 | return (
38 |
39 |
46 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | {children}
63 |
64 | );
65 | }
66 |
--------------------------------------------------------------------------------
/src/layouts/index.tsx:
--------------------------------------------------------------------------------
1 | import { useTranslation } from "react-i18next";
2 | import { Box, CloseButton, Slide } from "@chakra-ui/react";
3 | import type { FC, ReactNode } from 'react';
4 |
5 | import { useLocalStorage } from "src/hooks";
6 | import DashboardLayout from './DashboardLayout';
7 | import LogoOnlyLayout from './LogoOnlyLayout';
8 | import LandinLayout from './LandingLayout';
9 |
10 | type Props = {
11 | children: ReactNode;
12 | variant: 'dashboard' | 'logoOnly' | 'landing';
13 | };
14 |
15 | function WarningSlide() {
16 |
17 | const { t } = useTranslation();
18 | const [ noticedClose, setNotice ] = useLocalStorage("developmentNotice", false);
19 |
20 | const handleClose = () => setNotice(true);
21 |
22 | return (
23 |
24 |
32 |
33 | {t('layout_page.text_1')}
34 |
35 | {t('layout_page.text_2')}
36 |
37 |
38 | );
39 | }
40 |
41 | // export default function Layout({ variant = 'dashboard', children }: Props) {
42 | const Layout: FC = ({ variant = 'dashboard', children }) => {
43 | if (variant === 'dashboard') {
44 | return (
45 |
46 | {children}
47 |
48 |
49 | );
50 | }
51 |
52 | if (variant === 'landing') {
53 | return (
54 |
55 | {children}
56 |
57 | );
58 | }
59 |
60 | return (
61 |
62 | {children}
63 |
64 |
65 | );
66 | }
67 |
68 | export default Layout;
69 |
--------------------------------------------------------------------------------
/src/locales/de.json:
--------------------------------------------------------------------------------
1 | {
2 | "demo": {
3 | "title": "German",
4 | "introduction": "Lorem Ipsum ist einfach Dummy-Text der Druck- und Satzindustrie. Lorem Ipsum ist seit dem 16. Jahrhundert der Standard-Dummy-Text der Branche, als ein unbekannter Drucker eine Galeere vom Typ nahm und sie zu einem Musterbuch verschlüsselte. Es hat nicht nur fünf Jahrhunderte überlebt, sondern auch den Sprung in den elektronischen Satz, der im Wesentlichen unverändert geblieben ist. Es wurde in den 1960er Jahren mit der Veröffentlichung von Letraset-Blättern mit Lorem Ipsum-Passagen und in jüngerer Zeit mit Desktop-Publishing-Software wie Aldus PageMaker einschließlich Versionen von Lorem Ipsum populär gemacht."
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/locales/i18n.ts:
--------------------------------------------------------------------------------
1 | import i18n from 'i18next';
2 | import LanguageDetector from 'i18next-browser-languagedetector';
3 | import { initReactI18next } from 'react-i18next';
4 |
5 | //* The translations
6 | import enLocales from './en.json';
7 | import deLocales from './de.json';
8 | import esLocales from './es.json';
9 | import plLocales from './pl.json';
10 |
11 | let lng = 'en';
12 |
13 | if (typeof localStorage !== 'undefined') {
14 | lng = localStorage.getItem('i18nextLng') || 'en';
15 | }
16 |
17 | i18n
18 | .use(LanguageDetector)
19 | .use(initReactI18next)
20 | .init({
21 | resources: {
22 | en: { translations: enLocales },
23 | es: { translations: esLocales },
24 | de: { translations: deLocales },
25 | pl: { translations: plLocales }
26 | },
27 | lng,
28 | fallbackLng: 'en',
29 | debug: false,
30 | ns: [ 'translations' ],
31 | defaultNS: 'translations',
32 | interpolation: {
33 | escapeValue: false
34 | }
35 | });
36 |
37 | export default i18n;
38 |
--------------------------------------------------------------------------------
/src/pages/404.tsx:
--------------------------------------------------------------------------------
1 | import { m } from 'framer-motion';
2 | import NextLink from 'next/link';
3 | import { Box, Button, Heading, Text, Container, useColorModeValue } from '@chakra-ui/react';
4 |
5 | import { useTranslation } from 'src/hooks';
6 | import PageWrapper, { Layout } from 'src/components/wrappers/Page';
7 | import { varBounce } from 'src/components/animate';
8 | import PageNotFoundIllustration from 'src/assets/illustration_404';
9 |
10 | Page404.getLayout = function getLayout(page: React.ReactElement) {
11 | return {page};
12 | };
13 |
14 | export default function Page404() {
15 |
16 | const { t } = useTranslation();
17 | const bg = useColorModeValue('gray.50', 'gray.900');
18 |
19 | return (
20 |
21 |
22 |
23 |
24 |
25 | {t('404_page.title')}
26 |
27 |
28 |
29 | {t('404_page.description')}
30 |
31 |
32 |
33 |
34 |
35 |
43 |
44 |
45 |
46 |
47 | );
48 | }
--------------------------------------------------------------------------------
/src/pages/500.tsx:
--------------------------------------------------------------------------------
1 | import { m } from 'framer-motion';
2 | import NextLink from 'next/link';
3 | import { Box, Button, Text, Heading, Container, useColorModeValue } from '@chakra-ui/react';
4 |
5 | import { useTranslation } from 'src/hooks';
6 | import PageWrapper, { Layout } from 'src/components/wrappers/Page';
7 | import { MotionLazyContainer, varBounce } from 'src/components/animate';
8 | import SeverErrorIllustration from 'src/assets/illustration_500';
9 |
10 | Page500.getLayout = function getLayout(page: React.ReactElement) {
11 | return {page};
12 | };
13 |
14 | export default function Page500() {
15 |
16 | const { t } = useTranslation();
17 | const bg = useColorModeValue('gray.50', 'gray.900');
18 |
19 | return (
20 |
21 |
22 |
23 |
24 |
25 |
26 | {t('500_page.title')}
27 |
28 |
29 |
30 | {t('500_page.description')}
31 |
32 |
33 |
34 |
35 |
36 |
44 |
45 |
46 |
47 |
48 |
49 | );
50 | }
51 |
--------------------------------------------------------------------------------
/src/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import { type ReactElement, type ReactNode, lazy, Suspense } from "react";
2 | import { type AppProps } from "next/app";
3 | import { NextPage } from "next/types/index";
4 |
5 | import "src/styles/globals.css";
6 | import "@rainbow-me/rainbowkit/styles.css";
7 | import "../locales/i18n";
8 |
9 | import Loading from "src/components/loaders/PageLoader";
10 |
11 |
12 | type NextPageWithLayout = NextPage & {
13 | getLayout?: (page: ReactElement) => ReactNode;
14 | };
15 |
16 | interface MyAppProps extends AppProps {
17 | Component: NextPageWithLayout;
18 | }
19 |
20 | const Providers = lazy(() => import('src/context/Providers'));
21 |
22 | const App = (props: MyAppProps) => {
23 |
24 | const { Component, pageProps } = props;
25 | const getLayout = Component.getLayout ?? ((page) => page);
26 |
27 | return (
28 | }>
29 |
30 | {/* This allows us to use diferent layouts for each type of pages (i.e dashboard, landing page, etc) */}
31 | {getLayout()}
32 |
33 |
34 | );
35 | };
36 |
37 | export default App;
38 |
--------------------------------------------------------------------------------
/src/pages/_document.tsx:
--------------------------------------------------------------------------------
1 | import Document, { Html, Head, Main, NextScript } from 'next/document';
2 | import { ColorModeScript } from '@chakra-ui/react'
3 |
4 | import { MetaTags } from "src/components/wrappers/Page";
5 | import { APP_DESCRIPTION, APP_NAME } from 'src/utils/constants'
6 | import theme from '../theme';
7 |
8 | export default class MyDocument extends Document {
9 |
10 | // static async getInitialProps(ctx: any) {
11 | // return await Document.getInitialProps(ctx)
12 | // }
13 |
14 | render() {
15 | return (
16 |
17 |
18 |
19 |
20 |
21 |
22 | {/* */}
23 |
24 |
25 |
29 |
33 |
34 |
35 |
36 |
37 | {/* 👇 Here's the script */}
38 |
39 |
40 |
41 |
42 |
43 | )
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/pages/app.tsx:
--------------------------------------------------------------------------------
1 | export default function Dashboard() {
2 |
3 | //redirect to app/index
4 |
5 | }
--------------------------------------------------------------------------------
/src/pages/app/accounts/index.tsx:
--------------------------------------------------------------------------------
1 | import { Wrap, WrapItem } from '@chakra-ui/react'
2 | import { useTranslation } from "react-i18next";
3 |
4 | import { useToast } from 'src/hooks';
5 | import PageWrapper, { Layout } from 'src/components/wrappers/Page';
6 | import { useDappProvider } from "src/context/DAppConnectContext";
7 | import NftUsernameCard from 'src/components/NftUsernameCard';
8 | import Block from "src/components/Block";
9 |
10 | UserProfilePage.getLayout = function getLayout(page: React.ReactElement) {
11 | return {page};
12 | };
13 |
14 | export default function UserProfilePage() {
15 |
16 | const { cawAccounts, changeCawAccount } = useDappProvider();
17 | const { t } = useTranslation();
18 | const toast = useToast();
19 |
20 | const handleCawAccountChange = (username: string) => {
21 |
22 |
23 | try {
24 | const acc = cawAccounts.find((acc) => acc.userName === username);
25 | if (!acc)
26 | return;
27 |
28 | changeCawAccount(acc, true);
29 | toast.closeAll();
30 | toast({
31 | description: t('labels.connectedto') + ' : ' + username,
32 | status: 'success',
33 | variant: 'solid',
34 | position: 'bottom',
35 | duration: 2300,
36 | isClosable: true,
37 | });
38 | }
39 | catch (error: any) {
40 | toast.closeAll();
41 | toast({
42 | description: error?.message || 'Something went wrong',
43 | status: 'error',
44 | variant: 'subtle',
45 | position: 'bottom',
46 | duration: 9000,
47 | isClosable: true,
48 | });
49 | }
50 | }
51 |
52 | return (
53 |
54 |
58 |
59 | {cawAccounts.map((acc) => (
60 |
64 |
70 |
71 | ))}
72 |
73 |
74 |
75 | );
76 | }
--------------------------------------------------------------------------------
/src/pages/app/bookmarks/index.tsx:
--------------------------------------------------------------------------------
1 | import PageWrapper, { Layout } from 'src/components/wrappers/Page';
2 |
3 | BookmarksPage.getLayout = function getLayout(page: React.ReactElement) {
4 | return {page};
5 | };
6 |
7 | export default function BookmarksPage() {
8 | return (
9 |
10 |
11 |
Bookmarks page
12 |
13 |
14 | );
15 | }
--------------------------------------------------------------------------------
/src/pages/app/explore/index.tsx:
--------------------------------------------------------------------------------
1 | import PageWrapper, { Layout } from 'src/components/wrappers/Page';
2 |
3 | ExplorePage.getLayout = function getLayout(page: React.ReactElement) {
4 | return {page};
5 | };
6 |
7 | export default function ExplorePage() {
8 | return (
9 |
10 |
11 |
Explore page
12 |
13 |
14 | );
15 | }
--------------------------------------------------------------------------------
/src/pages/app/home/index.tsx:
--------------------------------------------------------------------------------
1 | import { Box, Heading, HStack, Input, InputGroup, InputRightElement, StackDivider, useColorModeValue } from "@chakra-ui/react";
2 | import { useTranslation } from "react-i18next";
3 | import dynamic from "next/dynamic";
4 |
5 | import PageWrapper, { Layout } from 'src/components/wrappers/Page';
6 | import Iconify from "src/components/icons/Iconify";
7 |
8 | const WallPost = dynamic(() => import("src/blocks/wall"), { ssr: false });
9 |
10 | HomePage.getLayout = function getLayout(page: React.ReactElement) {
11 | return {page};
12 | };
13 |
14 | export default function HomePage() {
15 |
16 | const { t } = useTranslation();
17 | const borderRightColor = useColorModeValue('gray.400', 'gray.700');
18 |
19 | return (
20 |
21 | }
26 | >
27 |
28 |
33 | {t('app_home.wall_title')}
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | );
46 | }
47 |
48 | function SearchCawInput() {
49 | return (
50 |
51 |
57 |
58 |
59 |
60 |
61 | );
62 | }
63 |
--------------------------------------------------------------------------------
/src/pages/app/lists/index.tsx:
--------------------------------------------------------------------------------
1 | import PageWrapper, { Layout } from 'src/components/wrappers/Page';
2 |
3 | ListsPage.getLayout = function getLayout(page: React.ReactElement) {
4 | return {page};
5 | };
6 |
7 | export default function ListsPage() {
8 | return (
9 |
10 |
11 |
Lists Page
12 |
13 |
14 | );
15 | }
--------------------------------------------------------------------------------
/src/pages/app/messages/index.tsx:
--------------------------------------------------------------------------------
1 | import PageWrapper, { Layout } from 'src/components/wrappers/Page';
2 |
3 | MessagesPage.getLayout = function getLayout(page: React.ReactElement) {
4 | return {page};
5 | };
6 |
7 | export default function MessagesPage() {
8 | return (
9 |
10 |
11 |
Messages page
12 |
13 |
14 | );
15 | }
--------------------------------------------------------------------------------
/src/pages/app/notifications/index.tsx:
--------------------------------------------------------------------------------
1 | import PageWrapper, { Layout } from 'src/components/wrappers/Page';
2 |
3 | NotificationsPage.getLayout = function getLayout(page: React.ReactElement) {
4 | return {page};
5 | };
6 |
7 | export default function NotificationsPage() {
8 | return (
9 |
10 |
11 |
Notifications page
12 |
13 |
14 | );
15 | }
--------------------------------------------------------------------------------
/src/pages/app/settings/BoxMask.tsx:
--------------------------------------------------------------------------------
1 | import { Box, BoxProps, Center, useColorModeValue, useToken } from "@chakra-ui/react";
2 | import Iconify from "src/components/icons/Iconify";
3 |
4 | export interface BoxMaskProps extends BoxProps {
5 | icon: string;
6 | bg?: string;
7 | iconColor?: string;
8 | text?: string;
9 | }
10 |
11 | export default function BoxMask({ icon, text, bg, iconColor, ...others }: BoxMaskProps) {
12 |
13 | const color = useColorModeValue('gray.50', 'whiteAlpha.50');
14 | const [ bgLight, bgDark ] = useToken('colors', [ 'gray.500', 'gray.50' ]);
15 | const _iconColor = useColorModeValue(bgLight, bgDark);
16 |
17 | return (
18 |
27 |
28 | {text || ''}
29 |
34 |
35 |
36 | );
37 | }
38 |
--------------------------------------------------------------------------------
/src/pages/app/settings/Display.tsx:
--------------------------------------------------------------------------------
1 | import { Stack, Text } from "@chakra-ui/react";
2 | import { useTranslation } from "react-i18next";
3 |
4 | import Block from "src/components/Block";
5 | import SettingMode from "./SettingMode";
6 | // import SettingDirection from "./SettingDirection";
7 | // import SettingColorPresets from "./SettingColorPresets";
8 | // import SettingFullscreen from "./SettingFullscreen";
9 |
10 | export default function DisplaySettings() {
11 | const { t } = useTranslation();
12 | return (
13 |
17 |
24 |
25 |
26 |
27 | {t('labels.mode')}
28 |
29 |
30 |
31 | {/*
32 |
33 | {t('labels.direction')}
34 |
35 |
36 |
*/}
37 |
38 | {/*
39 |
40 |
41 | {t('labels.color_presets')}
42 |
43 |
44 |
45 |
46 |
47 | {t('labels.layout')}
48 |
49 |
50 |
51 | */}
52 |
53 |
54 | );
55 | }
--------------------------------------------------------------------------------
/src/pages/app/settings/Language.tsx:
--------------------------------------------------------------------------------
1 | import { Stack, Text, useColorModeValue } from "@chakra-ui/react";
2 | import { useTranslation } from "react-i18next";
3 |
4 | import Block from "src/components/Block";
5 | import LanguagePopover from 'src/components/settings/LanguagePopover';
6 |
7 | export default function LanguajeSettings() {
8 |
9 | const { t } = useTranslation();
10 | const bgMenu = useColorModeValue('whiteAlpha.900', 'gray.800');
11 |
12 | return (
13 |
17 |
18 |
19 | {t('labels.select_lang')}
20 |
21 |
22 |
23 |
24 | );
25 | }
--------------------------------------------------------------------------------
/src/pages/app/settings/SettingColorPresets.tsx:
--------------------------------------------------------------------------------
1 | import { HStack, useToken } from "@chakra-ui/react";
2 | import BoxMask from "./BoxMask";
3 |
4 | export default function SettingColorPresets() {
5 |
6 | const [ cawColor, blueColor ] = useToken('colors', [ 'caw.500', 'blue.500' ]);
7 |
8 | return (
9 |
13 |
18 |
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/src/pages/app/settings/SettingDirection.tsx:
--------------------------------------------------------------------------------
1 | import { HStack } from "@chakra-ui/react";
2 | import BoxMask from "./BoxMask";
3 |
4 | export default function SettingDirection() {
5 |
6 | return (
7 |
11 |
14 |
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/src/pages/app/settings/SettingFullscreen.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import { Box, HStack } from "@chakra-ui/react";
3 | import { useTranslation } from "react-i18next";
4 |
5 | import { useToast } from 'src/hooks';
6 | import BoxMask from "./BoxMask";
7 |
8 | export default function SettingFullscreen() {
9 |
10 | const { t } = useTranslation();
11 | const toast = useToast();
12 | const [ fullscreen, setFullscreen ] = useState(false);
13 |
14 | const toggleFullScreen = () => {
15 |
16 | if (!document.fullscreenEnabled) {
17 |
18 | toast({
19 | title: t('errors.fullscreen_not_supported'),
20 | status: "error",
21 | duration: 5000,
22 | isClosable: true,
23 | });
24 | return;
25 | }
26 |
27 | if (!document.fullscreenElement) {
28 | document.documentElement.requestFullscreen();
29 | setFullscreen(true);
30 | window.scrollTo({ top: 0, behavior: 'smooth' });
31 | } else if (document.exitFullscreen) {
32 | document.exitFullscreen();
33 | setFullscreen(false);
34 | }
35 | };
36 |
37 | return (
38 |
42 |
47 |
48 |
49 |
50 | );
51 | }
52 |
--------------------------------------------------------------------------------
/src/pages/app/settings/SettingMode.tsx:
--------------------------------------------------------------------------------
1 | import { HStack, useColorMode, useToken } from "@chakra-ui/react";
2 | import BoxMask from "./BoxMask";
3 |
4 | export default function SettingMode() {
5 |
6 | const [ icColorLight, icColorDark ] = useToken('colors', [ 'caw.500', 'gray.100' ]);
7 | const [ bgLight, bgDark ] = useToken('colors', [ 'gray.50', 'gray.800' ]);
8 | const { setColorMode } = useColorMode();
9 |
10 | return (
11 |
15 | setColorMode('light')} />
21 | setColorMode('dark')} />
27 |
28 | );
29 | }
30 |
--------------------------------------------------------------------------------
/src/pages/app/settings/index.tsx:
--------------------------------------------------------------------------------
1 | import { Heading, Stack } from "@chakra-ui/react";
2 | import dynamic from "next/dynamic";
3 | import { useTranslation } from "react-i18next";
4 |
5 | import PageWrapper, { Layout } from 'src/components/wrappers/Page';
6 |
7 | const DisplaySettings = dynamic(() => import("./Display"), { ssr: false });
8 | const LanguageSettings = dynamic(() => import("./Language"), { ssr: false });
9 | const SettingFullscreen = dynamic(() => import("./SettingFullscreen"), { ssr: false });
10 |
11 | SettingsPage.getLayout = function getLayout(page: React.ReactElement) {
12 | return {page};
13 | };
14 |
15 | export default function SettingsPage() {
16 | const { t } = useTranslation();
17 | return (
18 |
19 |
20 | {t('settings_page.title')}
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | );
29 | }
--------------------------------------------------------------------------------
/src/pages/auth/connect/index.tsx:
--------------------------------------------------------------------------------
1 | import { useRouter } from 'next/navigation';
2 | import { Button, Container, Stack, Text, keyframes, Center } from "@chakra-ui/react";
3 | import { useTranslation } from "react-i18next";
4 | import NextLink from 'next/link';
5 | import { m } from "framer-motion";
6 |
7 | import PageWrapper, { Layout } from 'src/components/wrappers/Page';
8 | import { PATH_AUTH, PATH_DASHBOARD } from "src/routes/paths";
9 |
10 | LoginPage.getLayout = function getLayout(page: React.ReactElement) {
11 | return {page};
12 | };
13 |
14 | export const animationKeyframes = keyframes`
15 | 0% { transform: scale(1) rotate(0) translateY(50%); border-radius: 20%; opacity:0; }
16 | 100% { transform: scale(1) rotate(0) translateY(0); border-radius: 20%; opacity:1;}
17 | `;
18 |
19 | export const animation = `${animationKeyframes} 1s cubic-bezier(0.5, 1, 0.5, 1) 0.3s forwards`;
20 |
21 | export default function LoginPage() {
22 |
23 | const { t } = useTranslation();
24 | const router = useRouter();
25 |
26 |
27 | const handleLogin = async () => {
28 | try {
29 | router.push(PATH_DASHBOARD.app.home);
30 | }
31 | catch (error: any) {
32 | console.log(error);
33 | }
34 | }
35 |
36 | return (
37 |
38 |
39 |
50 | {t('access_page.message')}
51 |
52 |
53 |
54 |
61 |
62 |
69 |
70 |
71 |
72 |
73 |
74 | );
75 | }
--------------------------------------------------------------------------------
/src/pages/auth/mint/ConfirmAndMintCard.tsx:
--------------------------------------------------------------------------------
1 | import { Stack, Text, Divider } from "@chakra-ui/react";
2 | import { useTranslation } from "react-i18next";
3 |
4 | import NavbarAccount from 'src/components/contract/wallet/NavbarAccount';
5 | import MintingCost from "./MintingCost";
6 | import UserAcceptance from "./UserAcceptance";
7 |
8 | type Props = {
9 | userName: string;
10 | width: number;
11 | }
12 |
13 | export default function ConfirmAndMintCard({ userName, width }: Props) {
14 |
15 | const { t } = useTranslation();
16 |
17 | return (
18 |
19 |
20 | {t('minting_page.username_label')} : {userName}
21 |
22 |
23 |
24 |
25 | {t('minting_page.owneraddress_label')} :
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | {t('minting_page.press_bnt_action_label')} :
37 |
38 |
39 | {t('minting_page.longerResponse')}
40 |
41 |
42 | );
43 | }
44 |
--------------------------------------------------------------------------------
/src/pages/auth/mint/MintingCost.tsx:
--------------------------------------------------------------------------------
1 | import { Text } from "@chakra-ui/react";
2 | import type { As } from "@chakra-ui/react";
3 |
4 | import { useMintingPageContext } from ".";
5 | import { fDecimal } from "src/utils/formatNumber";
6 |
7 | export default function MintingCost({ title = 'Cost:', renderComp = 'b' }: { title?: string; renderComp?: As; }) {
8 |
9 | const { costVerified, costUSD, costETH, costCAW } = useMintingPageContext();
10 |
11 | return (
12 | <>
13 | {title}
14 | {costVerified ? fDecimal(costCAW, 2) : '--'} CAW (mCAW)
15 | {costVerified ? fDecimal(costETH, 6) : '--'} ETH
16 | {costVerified ? fDecimal(costUSD, 2) : '--'} USD
17 | >
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/src/pages/auth/mint/NftPriceLegend.tsx:
--------------------------------------------------------------------------------
1 | import { Text, useColorModeValue, Link, useDisclosure } from "@chakra-ui/react";
2 | import dynamic from "next/dynamic";
3 | import { useTranslation } from "react-i18next";
4 |
5 | const ProtocolCostModal = dynamic(() => import("src/components/contract/modals/ProtocolCostModal"), { ssr: false });
6 |
7 | export default function NftPriceLegend() {
8 |
9 | const { isOpen, onOpen, onClose } = useDisclosure();
10 | const color = useColorModeValue('gray.800', 'gray.200');
11 | const { t } = useTranslation();
12 | return (
13 | <>
14 |
15 | {t('minting_page.label_cost_the')} {t('minting_page.label_cost_sort')}
16 | {t('minting_page.label_cost_username')}
17 |
21 | {' ' + t('minting_page.label_cost_exp')}
22 |
23 | {' ' + t('minting_page.label_cost_willbe')}
24 |
25 |
26 | >
27 | );
28 | }
29 |
--------------------------------------------------------------------------------
/src/pages/auth/mint/Steps.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import { useState } from "react";
4 | import dynamic from "next/dynamic"
5 |
6 | import useIsMounted from "src/hooks/useIsMounted";
7 | import { useMintingPageContext } from ".";
8 |
9 | const WalletConnection = dynamic(() => import("./WalletConnection"), { ssr: false });
10 | const WalletBalanceCard = dynamic(() => import("./WalletBalance"), { ssr: false });
11 | const MintUserNameCard = dynamic(() => import("./MintUserNameCard"), { ssr: false });
12 | const ConfirmAndMintCard = dynamic(() => import("./ConfirmAndMintCard"), { ssr: false });
13 |
14 |
15 | type Props = {
16 | step: number;
17 | userName: string;
18 | }
19 |
20 | export default function Steps({ step }: Props) {
21 |
22 | const { userName } = useMintingPageContext();
23 | const [ width, setWidth ] = useState(0);
24 | const { mounted } = useIsMounted();
25 |
26 | const onInitilizedBox = (width: number) => {
27 |
28 | if (mounted)
29 | setWidth(width);
30 | }
31 |
32 | // switch (step) {
33 | // case 1:
34 | // return ;
35 | // case 2:
36 | // return ;
37 | // case 3:
38 | // return ;
39 | // case 4:
40 | // return ;
41 | // default:
42 | // return null;
43 | // }
44 |
45 | return (
46 | <>
47 | {step === 1 && }
48 | {step === 2 && }
49 | {step === 3 && }
50 | {step === 4 && }
51 | >
52 | )
53 | }
54 |
--------------------------------------------------------------------------------
/src/pages/auth/minted/[username]/LoaderCard.tsx:
--------------------------------------------------------------------------------
1 | import { Center, Box, Skeleton, SkeletonText } from "@chakra-ui/react";
2 |
3 | export default function LoaderCard() {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/src/pages/discover.tsx:
--------------------------------------------------------------------------------
1 | import { Container } from "@chakra-ui/react";
2 |
3 | import PageWrapper, { Layout } from 'src/components/wrappers/Page';
4 |
5 | DiscoverPage.getLayout = function getLayout(page: React.ReactElement) {
6 | return {page};
7 | };
8 |
9 | export default function DiscoverPage() {
10 | return (
11 |
12 |
13 |
14 |
15 | Find out what's happening in the world right now. Get the latest
16 |
17 |
18 |
19 |
20 | );
21 | }
--------------------------------------------------------------------------------
/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import { Container, Spacer } from "@chakra-ui/react";
2 |
3 | import { useTranslation } from 'src/hooks';
4 | import PageWrapper, { Layout } from "src/components/wrappers/Page"
5 | import { MotionLazyContainer } from "src/components/animate";
6 | import HeroSection from "src/blocks/home/HeroSection";
7 | import PoweredSection from "src/blocks/home/PoweredSection";
8 | import EconomySection from "src/blocks/home/EconomySection";
9 | import CardParallaxSection from "src/blocks/home/CardParallaxSection";
10 |
11 | // const HeroSection = lazy(() => import('src/sections/home/HeroSection'));
12 | // const PoweredSection = lazy(() => import('src/sections/home/PoweredSection'));
13 | // const EconomySection = lazy(() => import('src/sections/home/EconomySection'));
14 | // const CardParallaxSection = lazy(() => import('src/sections/home/CardParallaxSection'));
15 |
16 | HomePage.getLayout = function getLayout(page: React.ReactElement) {
17 | return {page};
18 | };
19 |
20 | export default function HomePage() {
21 |
22 | const { t } = useTranslation();
23 |
24 | return (
25 |
26 |
27 |
28 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | );
42 | }
43 |
--------------------------------------------------------------------------------
/src/pages/maintenance.tsx:
--------------------------------------------------------------------------------
1 | import NextLink from 'next/link';
2 | import { Button, Heading, Text, Container, useColorModeValue } from '@chakra-ui/react';
3 |
4 | import { useTranslation } from 'src/hooks';
5 | import PageWrapper, { Layout } from 'src/components/wrappers/Page';
6 | import MaintenanceIllustration from 'src/assets/illustration_maintenance';
7 |
8 | Maintenance.getLayout = function getLayout(page: React.ReactElement) {
9 | return {page};
10 | };
11 |
12 | export default function Maintenance() {
13 |
14 | const { t } = useTranslation();
15 | const bg = useColorModeValue('gray.50', 'gray.900');
16 |
17 | return (
18 |
19 |
20 |
21 |
22 | {t('maintenance_page.title')}
23 |
24 |
25 | {t('maintenance_page.description')}
26 |
27 |
28 |
29 |
37 |
38 |
39 |
40 |
41 | );
42 | }
43 |
--------------------------------------------------------------------------------
/src/pages/user/profile/[username].tsx:
--------------------------------------------------------------------------------
1 | import PageWrapper, { Layout } from 'src/components/wrappers/Page';
2 |
3 | PrivateUserPage.getLayout = function getLayout(page: React.ReactElement) {
4 | return {page};
5 | };
6 |
7 | export default function PrivateUserPage() {
8 | return (
9 |
10 |
11 |
12 | Public profile page
13 |
14 |
15 |
16 | );
17 | }
--------------------------------------------------------------------------------
/src/routes/paths.ts:
--------------------------------------------------------------------------------
1 |
2 | function path(root: string, sublink: string) {
3 | return `${root}${sublink}`;
4 | }
5 |
6 | const ROOTS_AUTH = '/auth';
7 | const ROOTS_DASHBOARD = '/app';
8 | const ROOTS_USER = '/user';
9 |
10 |
11 | export const PATH_AUTH = {
12 | root: ROOTS_AUTH,
13 | connect: path(ROOTS_AUTH, '/connect'),
14 | mint: path(ROOTS_AUTH, '/mint'),
15 | minted: path(ROOTS_AUTH, '/minted/[username]/[tx]')
16 | };
17 |
18 | export const PATH_PAGE = {
19 | maintenance: '/maintenance',
20 | discover: '/discover',
21 | page404: '/404',
22 | page500: '/500',
23 | };
24 |
25 | export const PATH_DASHBOARD = {
26 | root: ROOTS_DASHBOARD,
27 | app: {
28 | home: path(ROOTS_DASHBOARD, '/home'),
29 | explore: path(ROOTS_DASHBOARD, '/explore'),
30 | messages: path(ROOTS_DASHBOARD, '/messages'),
31 | bookmarks: path(ROOTS_DASHBOARD, '/bookmarks'),
32 | notifications: path(ROOTS_DASHBOARD, '/notifications'),
33 | lists: path(ROOTS_DASHBOARD, '/lists'),
34 | accounts: path(ROOTS_DASHBOARD, '/accounts'),
35 | settings: path(ROOTS_DASHBOARD, '/settings'),
36 | chakra_test: path(ROOTS_DASHBOARD, '/chakra_test'),
37 | },
38 | user: {
39 | profile: path(ROOTS_USER, '/profile/:username'),
40 | },
41 | swap: {
42 | mcaw: path(ROOTS_DASHBOARD, '/swap/mcaw'),
43 | }
44 | };
45 |
--------------------------------------------------------------------------------
/src/styles/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
7 | }
8 |
9 | a {
10 | color: inherit;
11 | text-decoration: none;
12 | }
13 |
14 | * {
15 | box-sizing: border-box;
16 | }
17 |
18 | @media (prefers-color-scheme: dark) {
19 | html {
20 | color-scheme: dark;
21 | }
22 | body {
23 | color: white;
24 | background: black;
25 | }
26 | }
27 |
28 | .parallax {
29 | overflow: hidden;
30 | letter-spacing: -2px;
31 | /* line-height: 0.8; */
32 | margin: 0;
33 | white-space: nowrap;
34 | display: flex;
35 | flex-wrap: nowrap;
36 | }
37 |
38 | .parallax .scroller {
39 | font-weight: 600;
40 | text-transform: uppercase;
41 | font-size: 64px;
42 | display: flex;
43 | white-space: nowrap;
44 | display: flex;
45 | flex-wrap: nowrap;
46 | }
47 |
48 | .header-text {
49 | display: flex;
50 | width: 100%;
51 | height: 100%;
52 | max-width: 100%;
53 | max-height: 100%;
54 | place-items: center;
55 | margin: 0px;
56 | padding: 0px;
57 | list-style-type: none;
58 | opacity: 1;
59 | mask-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgb(0, 0, 0) 12.5%, rgb(0, 0, 0) 87.5%, rgba(0, 0, 0, 0.5) 100%);
60 | overflow: hidden;
61 | }
62 | .rotate {
63 | animation: rotation 2.5s infinite linear;
64 | }
65 |
66 | @keyframes rotation {
67 | from {
68 | transform: rotate(0deg);
69 | }
70 |
71 | to {
72 | transform: rotate(359deg);
73 | }
74 | }
75 | .rounded-full {
76 | border-radius: 9999px;
77 | }
--------------------------------------------------------------------------------
/src/theme/cookie.tsx:
--------------------------------------------------------------------------------
1 | import { ChakraProvider, cookieStorageManagerSSR, localStorageManager } from '@chakra-ui/react'
2 |
3 | export function Chakra({ cookies, children }: { cookies: string, children: any }) {
4 | // b) Pass `colorModeManager` prop
5 | const colorModeManager =
6 | typeof cookies === 'string'
7 | ? cookieStorageManagerSSR(cookies)
8 | : localStorageManager
9 |
10 | return (
11 |
12 | {children}
13 |
14 | )
15 | }
16 |
17 | // also export a reusable function getServerSideProps
18 | export function getServerSideProps({ req }: { req: any }) {
19 | return {
20 | props: {
21 | // first time users will not have any cookies and you may not return
22 | // undefined here, hence ?? is necessary
23 | cookies: req.headers.cookie ?? '',
24 | },
25 | }
26 | }
--------------------------------------------------------------------------------
/src/theme/foundations/blur.ts:
--------------------------------------------------------------------------------
1 | const blur = {
2 | none: '0',
3 | sm: '4px',
4 | base: '8px',
5 | md: '12px',
6 | lg: '16px',
7 | xl: '24px',
8 | '2xl': '40px',
9 | '3xl': '64px',
10 | }
11 |
12 | export default blur
13 |
--------------------------------------------------------------------------------
/src/theme/foundations/borders.ts:
--------------------------------------------------------------------------------
1 | const borders = {
2 | none: 0,
3 | '1px': '1px solid',
4 | '2px': '2px solid',
5 | '4px': '4px solid',
6 | '8px': '8px solid',
7 | }
8 |
9 | export default borders
10 |
--------------------------------------------------------------------------------
/src/theme/foundations/breakpoints.ts:
--------------------------------------------------------------------------------
1 | const breakpoints = ({
2 | base: '0em',
3 | sm: '30em',
4 | md: '48em',
5 | lg: '62em',
6 | xl: '80em',
7 | '2xl': '96em',
8 | })
9 |
10 | export default breakpoints
11 |
--------------------------------------------------------------------------------
/src/theme/foundations/index.ts:
--------------------------------------------------------------------------------
1 | import borders from './borders'
2 | import breakpoints from './breakpoints'
3 | import colors from './colors'
4 | import radii from './radius'
5 | import shadows from './shadows'
6 | import sizes from './sizes'
7 | import spacing from './spacing'
8 | import transition from './transition'
9 | import typography from './typography'
10 | import zIndices from './z-index'
11 | import blur from './blur'
12 |
13 | const foundations = {
14 | breakpoints,
15 | zIndices,
16 | radii,
17 | blur,
18 | colors,
19 | ...typography,
20 | sizes,
21 | shadows,
22 | space: spacing,
23 | borders,
24 | transition,
25 | }
26 |
27 | export default foundations
28 |
--------------------------------------------------------------------------------
/src/theme/foundations/radius.ts:
--------------------------------------------------------------------------------
1 | const radii = {
2 | none: '0',
3 | sm: '0.125rem',
4 | base: '0.25rem',
5 | md: '0.375rem',
6 | lg: '0.5rem',
7 | xl: '0.75rem',
8 | '2xl': '1rem',
9 | '3xl': '1.5rem',
10 | full: '9999px',
11 | }
12 |
13 | export default radii
14 |
--------------------------------------------------------------------------------
/src/theme/foundations/shadows.ts:
--------------------------------------------------------------------------------
1 | const shadows = {
2 | xs: '0 0 0 1px rgba(0, 0, 0, 0.05)',
3 | sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
4 | base: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
5 | md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
6 | lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
7 | xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
8 | '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
9 | outline: '0 0 0 3px rgba(66, 153, 225, 0.6)',
10 | inner: 'inset 0 2px 4px 0 rgba(0,0,0,0.06)',
11 | none: 'none',
12 | 'dark-lg': 'rgba(0, 0, 0, 0.1) 0px 0px 0px 1px, rgba(0, 0, 0, 0.2) 0px 5px 10px, rgba(0, 0, 0, 0.4) 0px 15px 40px',
13 | largeSoft: 'rgba(60, 64, 67, 0.15) 0px 2px 10px 6px;',
14 | }
15 |
16 | export default shadows
17 |
--------------------------------------------------------------------------------
/src/theme/foundations/sizes.ts:
--------------------------------------------------------------------------------
1 | const sizes = {
2 | 1: '0.25rem',
3 | 2: '0.5rem',
4 | 3: '0.75rem',
5 | 4: '1rem',
6 | 5: '1.25rem',
7 | 6: '1.5rem',
8 | 7: '1.75rem',
9 | 8: '2rem',
10 | 9: '2.25rem',
11 | 10: '2.5rem',
12 | 12: '3rem',
13 | 14: '3.5rem',
14 | 16: '4rem',
15 | 20: '5rem',
16 | 24: '6rem',
17 | 28: '7rem',
18 | 32: '8rem',
19 | 36: '9rem',
20 | 40: '10rem',
21 | 44: '11rem',
22 | 48: '12rem',
23 | 52: '13rem',
24 | 56: '14rem',
25 | 60: '15rem',
26 | 64: '16rem',
27 | 72: '18rem',
28 | 80: '20rem',
29 | 96: '24rem',
30 | px: '1px',
31 | '0.5': '0.125rem',
32 | '1.5': '0.375rem',
33 | '2.5': '0.625rem',
34 | '3.5': '0.875rem',
35 | max: 'max-content',
36 | min: 'min-content',
37 | full: '100%',
38 | '3xs': '14rem',
39 | '2xs': '16rem',
40 | xs: '20rem',
41 | sm: '24rem',
42 | md: '28rem',
43 | lg: '32rem',
44 | xl: '36rem',
45 | '2xl': '42rem',
46 | '3xl': '48rem',
47 | '4xl': '56rem',
48 | '5xl': '64rem',
49 | '6xl': '72rem',
50 | '7xl': '80rem',
51 | '8xl': '90rem',
52 | container: {
53 | sm: '640px',
54 | md: '768px',
55 | lg: '1024px',
56 | xl: '1280px',
57 | },
58 | }
59 |
60 | export default sizes
61 |
--------------------------------------------------------------------------------
/src/theme/foundations/spacing.ts:
--------------------------------------------------------------------------------
1 | const spacing = {
2 | 1: '0.25rem',
3 | 2: '0.5rem',
4 | 3: '0.75rem',
5 | 4: '1rem',
6 | 5: '1.25rem',
7 | 6: '1.5rem',
8 | 7: '1.75rem',
9 | 8: '2rem',
10 | 9: '2.25rem',
11 | 10: '2.5rem',
12 | 12: '3rem',
13 | 14: '3.5rem',
14 | 16: '4rem',
15 | 20: '5rem',
16 | 24: '6rem',
17 | 28: '7rem',
18 | 32: '8rem',
19 | 36: '9rem',
20 | 40: '10rem',
21 | 44: '11rem',
22 | 48: '12rem',
23 | 52: '13rem',
24 | 56: '14rem',
25 | 60: '15rem',
26 | 64: '16rem',
27 | 72: '18rem',
28 | 80: '20rem',
29 | 96: '24rem',
30 | px: '1px',
31 | '0.5': '0.125rem',
32 | '1.5': '0.375rem',
33 | '2.5': '0.625rem',
34 | '3.5': '0.875rem',
35 | }
36 |
37 | export default spacing
38 |
--------------------------------------------------------------------------------
/src/theme/foundations/transition.ts:
--------------------------------------------------------------------------------
1 | const transition = {
2 | property: {
3 | common: 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform',
4 | colors: 'background-color, border-color, color, fill, stroke',
5 | dimensions: 'width, height',
6 | position: 'left, right, top, bottom',
7 | background: 'background-color, background-image, background-position',
8 | },
9 | easing: {
10 | 'ease-in': 'cubic-bezier(0.4, 0, 1, 1)',
11 | 'ease-out': 'cubic-bezier(0, 0, 0.2, 1)',
12 | 'ease-in-out': 'cubic-bezier(0.4, 0, 0.2, 1)',
13 | },
14 | duration: {
15 | 'ultra-fast': '50ms',
16 | faster: '100ms',
17 | fast: '150ms',
18 | normal: '200ms',
19 | slow: '300ms',
20 | slower: '400ms',
21 | 'ultra-slow': '500ms',
22 | },
23 | }
24 |
25 | export default transition
26 |
--------------------------------------------------------------------------------
/src/theme/foundations/typography.ts:
--------------------------------------------------------------------------------
1 | const typography = {
2 | letterSpacing: {
3 | tighter: '-0.05em',
4 | tight: '-0.025em',
5 | normal: '0',
6 | wide: '0.025em',
7 | wider: '0.05em',
8 | widest: '0.1em',
9 | },
10 | lineHeights: {
11 | 3: '.75rem',
12 | 4: '1rem',
13 | 5: '1.25rem',
14 | 6: '1.5rem',
15 | 7: '1.75rem',
16 | 8: '2rem',
17 | 9: '2.25rem',
18 | 10: '2.5rem',
19 | normal: 'normal',
20 | none: '1',
21 | shorter: '1.25',
22 | short: '1.375',
23 | base: '1.5',
24 | tall: '1.625',
25 | taller: '2',
26 | },
27 | fontWeights: {
28 | hairline: '100',
29 | thin: '200',
30 | light: '300',
31 | normal: '400',
32 | medium: '500',
33 | semibold: '600',
34 | bold: '700',
35 | extrabold: '800',
36 | black: '900',
37 | },
38 | fonts: {
39 | heading: 'Work Sans, system-ui, sans-serif',
40 | body: 'Inter, system-ui, sans-serif',
41 | mono: 'SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace',
42 | },
43 | fontSizes: {
44 | xs: '0.75rem',
45 | sm: '0.875rem',
46 | md: '1rem',
47 | lg: '1.125rem',
48 | xl: '1.25rem',
49 | '2xl': '1.5rem',
50 | '3xl': '1.875rem',
51 | '4xl': '2.25rem',
52 | '5xl': '3rem',
53 | '6xl': '3.75rem',
54 | '7xl': '4.5rem',
55 | '8xl': '6rem',
56 | '9xl': '8rem',
57 | },
58 | }
59 |
60 | export default typography
61 |
--------------------------------------------------------------------------------
/src/theme/foundations/z-index.ts:
--------------------------------------------------------------------------------
1 | const zIndices = {
2 | hide: -1,
3 | auto: 'auto',
4 | base: 0,
5 | docked: 10,
6 | dropdown: 1000,
7 | sticky: 1100,
8 | banner: 1200,
9 | overlay: 1300,
10 | modal: 1400,
11 | popover: 1500,
12 | skipLink: 1600,
13 | toast: 1700,
14 | tooltip: 1800,
15 | }
16 |
17 | export default zIndices
18 |
--------------------------------------------------------------------------------
/src/types/community-feed.ts:
--------------------------------------------------------------------------------
1 | import { uuidv4 } from "src/utils/helper";
2 |
3 | export type MediaType = 'image' | 'video' | 'audio' | 'file' | 'text' | 'url' | 'nft';
4 |
5 | export type MediaMetaDto = {
6 | id: string;
7 | src: string;
8 | type: MediaType;
9 | width: number;
10 | height: number;
11 | watermark: {
12 | porcentage: number;
13 | };
14 | }
15 |
16 | export type FollowerDto = {
17 | id: string;
18 | avatar: MediaMetaDto;
19 | name: string;
20 | country: string;
21 | isFollowed: boolean;
22 | };
23 |
24 |
25 | export type AuthorDto = {
26 | id: string;
27 | name: string;
28 | userName: string;
29 | media: MediaMetaDto;
30 | wallet: string;
31 | verified: boolean;
32 | followers: number;
33 | following: number;
34 | }
35 |
36 | export type PostDto = {
37 | id: string;
38 | transactionHash: string;
39 | title: string;
40 | content: string;
41 | date: Date;
42 | author: AuthorDto;
43 | votes: number;
44 | likes: number;
45 | commentsCount: number;
46 | media: MediaMetaDto[];
47 | }
48 |
49 | export type AuthUser = {
50 | id: string;
51 | username: string;
52 | wallet: string;
53 | avatar: MediaMetaDto;
54 | }
55 |
56 | export const name_eateregg = 'cawfee';
57 | export const avatar_eateregg_ = 'https://pbs.twimg.com/profile_images/1576311533382078466/jfOC1m_E_400x400.jpg';
58 |
59 | export const user: AuthUser = {
60 | id: uuidv4(),
61 | username: name_eateregg,
62 | wallet: '0x0000000000000000000000000000000000000000',
63 | avatar: {
64 | src: avatar_eateregg_,
65 | width: 100,
66 | height: 100,
67 | id: uuidv4(),
68 | type: 'nft',
69 | watermark: {
70 | porcentage: 0.5,
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/types/dtos.ts:
--------------------------------------------------------------------------------
1 |
2 | export type WalletBalanceModel = {
3 | symbol: string,
4 | name: string,
5 | amount: number
6 | }
7 |
8 | export type CawUserName = {
9 | id: number,
10 | userName: string,
11 | avatar: string,
12 | balance: number
13 | }
--------------------------------------------------------------------------------
/src/types/global.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'react-blockies' {
2 | interface BlockiesProps {
3 | seed: string
4 | size?: number
5 | scale?: number
6 | color?: string
7 | bgColor?: string
8 | spotColor?: string
9 | className?: string
10 | }
11 | const Blockies: React.FC
12 |
13 | export default Blockies
14 | }
15 |
--------------------------------------------------------------------------------
/src/utils/constants.ts:
--------------------------------------------------------------------------------
1 | import { Address } from "wagmi";
2 |
3 | export const MILLION = 1000000;
4 | export const BILLION = MILLION * 1000;
5 | export const CONTRACT_ERR_NOT_INIT = 'Contract not initialized, please try again in a few seconds';
6 | export const APP_NAME = 'CAW Social';
7 | export const APP_DESCRIPTION = 'CAW is a fully decentralized - censorship-resistant on-chain messaging protocol built on top of the Ethereum network for the Future of Decentralized Social Media';
8 | export const DEFAULT_OG = 'https://teh-eyes.vercel.app/logo.jpeg';
9 |
10 | //* CAW CONTRACTS
11 | export const MintableCAW_CONTRACT: Address = '0x0bc5f399265fA0Fb95F5473c8ec1737d1dBB015c';
12 | export const CawName_CONTRACT: Address = '0x3F63Ad5E6309135a9D5fD3540270b93f56FD9CD9';
13 | export const CawActions_CONTRACT = '0x6B22437861eCC2Ea93fEcB742EA3BD5E1d3C7307';
14 | export const CawNameURI_CONTRACT: Address = '0x27108Da237A5200fBcb3fc62eE08Ee07D84a1331';
15 | export const CawNameMinter_CONTRACT: Address = '0x56F0d5DA1Bc735e03d6A4cd988784ED498FD9Ee3';
16 | export const AHuntersDream_CONTRACT: Address = '0xf3b9569F82B18aEf890De263B84189bd33EBe452';
17 |
18 | export const DEFAULT_JSON_RPC_URL = 'https://rpc.builder0x69.io';
--------------------------------------------------------------------------------
/src/utils/createAvatar.ts:
--------------------------------------------------------------------------------
1 | const PRIMARY_NAME = [ 'A', 'N', 'H', 'L', 'Q', '9', '8' ];
2 | const INFO_NAME = [ 'F', 'G', 'T', 'I', 'J', '1', '2', '3' ];
3 | const SUCCESS_NAME = [ 'K', 'D', 'Y', 'B', 'O', '4', '5' ];
4 | const WARNING_NAME = [ 'P', 'E', 'R', 'S', 'C', 'U', '6', '7' ];
5 | const ERROR_NAME = [ 'V', 'W', 'X', 'M', 'Z' ];
6 |
7 | function getFirstCharacter(name: string) {
8 | return name && name.charAt(0).toUpperCase();
9 | }
10 |
11 | function getAvatarColor(name: string) {
12 | if (PRIMARY_NAME.includes(getFirstCharacter(name))) return 'primary';
13 | if (INFO_NAME.includes(getFirstCharacter(name))) return 'info';
14 | if (SUCCESS_NAME.includes(getFirstCharacter(name))) return 'success';
15 | if (WARNING_NAME.includes(getFirstCharacter(name))) return 'warning';
16 | if (ERROR_NAME.includes(getFirstCharacter(name))) return 'error';
17 | return 'default';
18 | }
19 |
20 | export default function createAvatar(name: string) {
21 | return {
22 | name: getFirstCharacter(name || ''),
23 | color: getAvatarColor(name || ''),
24 | } as const;
25 | }
26 |
--------------------------------------------------------------------------------
/src/utils/formatTime.ts:
--------------------------------------------------------------------------------
1 | import { format, getTime, formatDistanceToNow } from 'date-fns';
2 |
3 | export function fDate(date: Date | string | number) {
4 | return format(new Date(date), 'dd MMMM yyyy');
5 | }
6 |
7 | export function fDateTime(date: Date | string | number) {
8 | return format(new Date(date), 'dd MMM yyyy p');
9 | }
10 |
11 | export function fTimestamp(date: Date | string | number) {
12 | return getTime(new Date(date));
13 | }
14 |
15 | export function fDateTimeSuffix(date: Date | string | number) {
16 | return format(new Date(date), 'dd/MM/yyyy hh:mm p');
17 | }
18 |
19 | export function fToNow(date: Date | string | number) {
20 | return formatDistanceToNow(new Date(date), {
21 | addSuffix: true
22 | });
23 | }
24 |
25 | export function fToNowShorter(date: Date | string | number) {
26 |
27 | let res = fToNow(date);
28 |
29 | if (res === 'less than a minute ago')
30 | return 'now';
31 |
32 | //* add regex to remove the word ago, about, less thab, almost, over, etc
33 | res = res.replace(/(about|almost|over|less than|almost|about|over|ago)/g, '');
34 |
35 | //* add regex to replace the word days, hours, minutes, seconds, etc with d, h, m, s
36 | res = res.replace(/(days|day|hours|hour|minutes|minute|seconds|second)/g, function (x) {
37 |
38 | switch (x) {
39 | case 'days':
40 | case 'day':
41 | return 'd';
42 | case 'hours':
43 | case 'hour':
44 | return 'h';
45 | case 'minutes':
46 | case 'minute':
47 | return 'm';
48 | case 'seconds':
49 | case 'second':
50 | return 's';
51 | default:
52 | return x;
53 | }
54 | });
55 |
56 | //* add regex to remove the word and, and replace the word comma with a space
57 | res = res.replace(/(and|,)/g, ' ');
58 |
59 | //* add reg to remove the spaces between the content
60 | res = res.replace(/\s+/g, '');
61 |
62 | return res;
63 | }
64 |
--------------------------------------------------------------------------------
/src/utils/helper.ts:
--------------------------------------------------------------------------------
1 | import packageJson from '../../package.json';
2 |
3 | export function slugify(text: string) {
4 | return text
5 | .toString()
6 | .normalize('NFD')
7 | .replace(/[\u0300-\u036f]/g, '')
8 | .toLowerCase()
9 | .trim()
10 | .replace(/&/g, '-and-') // Replace & with 'and'
11 | .replace(/[\s\W-]+/g, '-'); // Replace spaces, non-word characters and dashes with a single dash (-)
12 | }
13 |
14 | export function uuidv4() {
15 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
16 | const r = (Math.random() * 16) | 0,
17 | v = c === 'x' ? r : (r & 0x3) | 0x8;
18 | return v.toString(16);
19 | });
20 | }
21 |
22 | export const shortenAddress = (address: string) => address ? `${address.slice(0, 4)}...${address.slice(address.length - 4)}` : '';
23 |
24 |
25 | export const sentenceCase = (str: string) => str.charAt(0).toUpperCase() + str.slice(1);
26 |
27 | export const getAppVersion = () => {
28 | const { name, version } = packageJson
29 | return name + '/' + version
30 | }
31 |
32 | export const isMobileDevice = () => {
33 | const math = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
34 | return math;
35 | }
36 |
37 | export const isMetaMaskBrowser = () => {
38 |
39 | const ethereum = window.ethereum;
40 | if (ethereum && ethereum.isMetaMask)
41 | return true;
42 |
43 | const math = /MetaMask/i.test(navigator.userAgent);
44 | return math;
45 | }
46 |
47 | export const isInWalletBrowser = () => {
48 |
49 | //* test MetaMask|Trust Wallet|WalletConnect|Coinbase Wallet|Enjin|Status Wallet
50 | const math = /MetaMask|Trust Wallet|WalletConnect|Enjin|Status Wallet/i.test(navigator.userAgent);
51 |
52 | //* if user-agent end of with "Mobile/15E148" then it is likely a in-wallet browser
53 | if (!math) {
54 |
55 | const strNavigatorUserAgent = navigator.userAgent;
56 | const strEndOfUserAgent = strNavigatorUserAgent.substring(strNavigatorUserAgent.length - 13, strNavigatorUserAgent.length);
57 | if (strEndOfUserAgent.toLowerCase() === 'Mobile/15E148'.toLowerCase())
58 | return true;
59 | }
60 |
61 | if (!math)
62 | return isMetaMaskBrowser();
63 |
64 | return math;
65 | }
--------------------------------------------------------------------------------
/src/utils/mock/boolean.ts:
--------------------------------------------------------------------------------
1 | export const boolean = [
2 | true,
3 | true,
4 | true,
5 | false,
6 | false,
7 | true,
8 | false,
9 | false,
10 | false,
11 | false,
12 | true,
13 | true,
14 | true,
15 | false,
16 | false,
17 | false,
18 | true,
19 | false,
20 | false,
21 | false,
22 | true,
23 | false,
24 | false,
25 | true,
26 | true,
27 | true,
28 | false,
29 | false,
30 | true,
31 | true,
32 | false,
33 | true,
34 | false,
35 | true,
36 | true,
37 | true,
38 | false,
39 | true,
40 | false,
41 | false
42 | ];
43 |
--------------------------------------------------------------------------------
/src/utils/mock/funcs.ts:
--------------------------------------------------------------------------------
1 |
2 | export function randomNumber(number: number) {
3 | return Math.floor(Math.random() * number) + 1;
4 | }
5 |
6 | export function randomNumberRange(min: number, max: number) {
7 | return Math.floor(Math.random() * (max - min + 1)) + min;
8 | }
9 |
10 | export function randomInArray(array: any) {
11 | return array[ Math.floor(Math.random() * array.length) ];
12 | }
13 |
--------------------------------------------------------------------------------
/src/utils/mock/mock.ts:
--------------------------------------------------------------------------------
1 | import { sub } from 'date-fns';
2 | import { boolean } from './boolean';
3 | import { firstName, lastName, fullName } from './name';
4 | import { title, sentence, description } from './text';
5 | import { price, rating, age, percent } from './number';
6 |
7 | const _mock = {
8 | id: (index: number) => `e99f09a7-dd88-49d5-b1c8-1daf80c2d7b${index + 1}`,
9 | time: (index: number) => sub(new Date(), { days: index, hours: index }),
10 | boolean: (index: number) => boolean[ index ],
11 | name: {
12 | firstName: (index: number) => firstName[ index ],
13 | lastName: (index: number) => lastName[ index ],
14 | fullName: (index: number) => fullName[ index ],
15 | userName: (index: number) => fullName[ index ].replace(/\s/g, '').toLowerCase(),
16 | },
17 | text: {
18 | title: (index: number) => title[ index ],
19 | sentence: (index: number) => sentence[ index ],
20 | description: (index: number) => description[ index ],
21 | },
22 | number: {
23 | percent: (index: number) => percent[ index ],
24 | rating: (index: number) => rating[ index ],
25 | age: (index: number) => age[ index ],
26 | price: (index: number) => price[ index ],
27 | },
28 | image: {
29 | cover: (index: number) =>
30 | `https://picsum.photos/seed/${index}/600/400`,
31 | feed: (index: number) =>
32 | `https://picsum.photos/seed/${index}/600/400`,
33 | product: (index: number) =>
34 | `https://picsum.photos/seed/${index}/600/400`,
35 | avatar: (index: number) =>
36 | index === 0 ? 'https://pbs.twimg.com/profile_images/1529794585362407424/npkH5ILQ_400x400.jpg' : `https://picsum.photos/seed/${index}/600/400`,
37 | },
38 | };
39 |
40 | export default _mock;
41 |
--------------------------------------------------------------------------------
/src/utils/mock/name.ts:
--------------------------------------------------------------------------------
1 | export const fullName = [
2 | 'CAWMmunity',
3 | 'SafetyMeasures',
4 | 'Lucian Obrien',
5 | 'Deja Brady',
6 | 'Harrison Stein',
7 | 'Reece Chung',
8 | 'Lainey Davidson',
9 | 'Cristopher Cardenas',
10 | 'Melanie Noble',
11 | 'Chase Day',
12 | 'Shawn Manning',
13 | 'Soren Durham',
14 | 'Cortez Herring',
15 | 'itsyaboi',
16 | 'Giana Brandt',
17 | 'Aspen Schmitt',
18 | 'Maker',
19 | 'Angelique Morse',
20 | 'Selina Boyer',
21 | 'Lawson Bass',
22 | 'Ariana Lang',
23 | 'Amiah Pruitt',
24 | 'Harold Mcgrath',
25 | 'Esperanza Mcintyre',
26 | 'Mireya Conner',
27 | 'Jamie Kline',
28 | 'Laney Vazquez',
29 | 'Tiffany May',
30 | 'Dexter Shepherd',
31 | 'Jaqueline Spencer',
32 | 'Londyn Jarvis',
33 | 'V.eseni Talik',
34 | 'Jayvon Hull',
35 | 'Izayah Pope',
36 | 'Ayana Hunter',
37 | 'EyesoftheVoid',
38 | 'Isabell Bender',
39 | 'Desiree Schmidt',
40 | 'Aidan Stout',
41 | 'Jace Bush',
42 | 'Janiya Williamson',
43 | ];
44 |
45 | export const firstName = [
46 | '🌙',
47 | 'Mossie',
48 | 'David',
49 | 'Ebba',
50 | 'Chester',
51 | 'Eula',
52 | 'Jaren',
53 | 'Boyd',
54 | 'Brady',
55 | 'Aida',
56 | 'Anastasia',
57 | 'Gregoria',
58 | 'Julianne',
59 | 'Ila',
60 | 'Elyssa',
61 | 'Lucio',
62 | 'Lewis',
63 | 'Jacinthe',
64 | 'Molly',
65 | 'Brown',
66 | 'Fritz',
67 | 'Keon',
68 | 'Ella',
69 | 'Ken',
70 | 'Whitney',
71 | 'Monte',
72 | 'Rose',
73 | 'Shana',
74 | 'Devon',
75 | 'Jaleel',
76 | 'Laury',
77 | 'Brooks',
78 | 'Bruce',
79 | 'Avery',
80 | 'Esperanza',
81 | 'Helene',
82 | 'Heloise',
83 | 'Elinor',
84 | 'Adeline',
85 | 'Haley',
86 | 'Anabelle',
87 | ];
88 |
89 | export const lastName = [
90 | 'Carroll',
91 | 'Simonis',
92 | 'Yost',
93 | 'Hand',
94 | 'Emmerich',
95 | 'Wilderman',
96 | 'Howell',
97 | 'Sporer',
98 | 'Boehm',
99 | 'Morar',
100 | 'Koch',
101 | 'Reynolds',
102 | 'Padberg',
103 | 'Watsica',
104 | 'Upton',
105 | 'Yundt',
106 | 'Pfeffer',
107 | 'Parker',
108 | 'Zulauf',
109 | 'Treutel',
110 | 'McDermott',
111 | 'McDermott',
112 | 'Cruickshank',
113 | 'Parisian',
114 | 'Auer',
115 | 'Turner',
116 | 'Dooley',
117 | 'Wiegand',
118 | 'Abbott',
119 | 'Wisoky',
120 | 'Fahey',
121 | 'Satterfield',
122 | 'Bahringer',
123 | 'Schulist',
124 | 'Durgan',
125 | 'Carroll',
126 | 'Jones',
127 | 'Leffler',
128 | 'Gutkowski',
129 | 'Homenick',
130 | ];
131 |
--------------------------------------------------------------------------------
/src/utils/mock/number.ts:
--------------------------------------------------------------------------------
1 | export const price = [
2 | 16.19, 35.71, 34.3, 93.1, 55.47, 89.09, 44.39, 26.92, 45.35, 26.96, 78.22, 35.54, 90.69, 63.61,
3 | 67.55, 94.75, 75.78, 39.6, 52.84, 72.8, 83.08, 85.02, 69.22, 60.96, 84.7, 16.68, 78.83, 58.07,
4 | 65.8, 55.69, 87.55, 44.74, 27.42, 84, 76.17, 43.83, 76.39, 17.42, 42.3, 12.45
5 | ];
6 |
7 | export const rating = [
8 | 2.5, 2, 4.9, 2, 4, 5, 4.9, 5, 3.7, 2.5, 2, 4.9, 4.8, 4, 2, 3.7, 1.4, 2.4, 1.8, 5, 2.9, 3.9, 3.9,
9 | 1.8, 5, 2.6, 3.1, 3.9, 1.2, 3.2, 4.1, 5, 4.5, 4.1, 2.3, 2.4, 5, 3.1, 4.9, 1.7
10 | ];
11 |
12 | export const age = [
13 | 52, 43, 56, 25, 22, 53, 38, 50, 55, 37, 16, 27, 55, 41, 52, 32, 34, 52, 31, 53, 23, 48, 43, 41,
14 | 19, 21, 17, 29, 32, 54, 38, 34, 49, 33, 55, 50, 24, 27, 23, 23
15 | ];
16 |
17 | export const percent = [
18 | 8.62, 86.36, 73.99, 79, 63.41, 58.79, 12.32, 88.44, 45.06, 91.64, 88.41, 73.08, 39.14, 89.34,
19 | 43.37, 34.45, 24.04, 80.96, 72.91, 47.59, 2.46, 3.33, 99.31, 47.6, 34.09, 50.61, 66.13, 46.69,
20 | 92.43, 31.41, 90.85, 36.32, 38.84, 25.6, 87.61, 1.31, 89.32, 41.23, 85.9, 62.63
21 | ];
22 |
--------------------------------------------------------------------------------
/src/utils/mock/wallposts.ts:
--------------------------------------------------------------------------------
1 | import { PostDto } from 'src/types/community-feed';
2 | import _mock from './mock';
3 | import { randomNumberRange } from "./funcs";
4 |
5 |
6 | export const posts: PostDto[] = Array.from({ length: 41 }, (_, i) => ({
7 | id: _mock.id(i),
8 | transactionHash: _mock.id(i),
9 | title: _mock.text.title(i),
10 | content: _mock.text.description(i),
11 | author: {
12 | id: _mock.id(i),
13 | name: _mock.name.fullName(i),
14 | userName: _mock.name.userName(i),
15 | media: {
16 | id: _mock.id(i),
17 | src: _mock.image.avatar(i),
18 | height: 100,
19 | type: 'nft',
20 | width: 100,
21 | watermark: {
22 | porcentage: 0,
23 | }
24 | },
25 | wallet: _mock.id(i),
26 | verified: _mock.boolean(i),
27 | followers: randomNumberRange(999, 99999),
28 | following: randomNumberRange(999, 99999),
29 | },
30 | votes: randomNumberRange(999, 99999),
31 | commentsCount: randomNumberRange(999, 99999),
32 | likes: randomNumberRange(999, 99999),
33 | date: _mock.time(i),
34 | media: Array.from({ length: 10 }, (_, i) => ({
35 | id: _mock.id(i),
36 | src: _mock.image.avatar(i),
37 | height: 100,
38 | type: 'image',
39 | width: 100,
40 | watermark: {
41 | porcentage: 0,
42 | }
43 | })),
44 | }));
45 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "target": "es5",
5 | "lib": [
6 | "dom",
7 | "dom.iterable",
8 | "esnext"
9 | ],
10 | // "paths": {
11 | // "@components*": [
12 | // "src/components*"
13 | // ],
14 | // "@utils*": [
15 | // "src/utils*"
16 | // ],
17 | // "@lib*": [
18 | // "src/lib*"
19 | // ],
20 | // "@tpes*": [
21 | // "src/types*"
22 | // ]
23 | // },
24 | "allowJs": true,
25 | "skipLibCheck": true,
26 | "strict": true,
27 | "forceConsistentCasingInFileNames": true,
28 | "noEmit": true,
29 | "esModuleInterop": true,
30 | "module": "ESNext",
31 | "moduleResolution": "node",
32 | "resolveJsonModule": true,
33 | "isolatedModules": true,
34 | "jsx": "preserve",
35 | "incremental": true
36 | },
37 | "include": [
38 | "next-env.d.ts",
39 | "app-env.d.ts",
40 | "**/*.ts",
41 | "**/*.tsx"
42 | ],
43 | "exclude": [
44 | "node_modules"
45 | ]
46 | }
--------------------------------------------------------------------------------