diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 25e4c7c..829d612 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,13 +17,13 @@ jobs: - uses: actions/setup-node@v3 with: node-version: 16.x - cache: 'yarn' + cache: 'pnpm' - name: Install dependencies - run: rm -rf node_modules && yarn install --frozen-lockfile + run: rm -rf node_modules && pnpm install --frozen-lockfile - name: Build - run: yarn build + run: pnpm build lint: runs-on: ubuntu-latest @@ -32,13 +32,13 @@ jobs: - uses: actions/setup-node@v3 with: node-version: 16.x - cache: 'yarn' + cache: 'pnpm' - name: Install dependencies - run: rm -rf node_modules && yarn install --frozen-lockfile + run: rm -rf node_modules && pnpm install --frozen-lockfile - name: Lint - run: yarn ci:test:lint + run: pnpm ci:test:lint typecheck: runs-on: ubuntu-latest @@ -47,13 +47,13 @@ jobs: - uses: actions/setup-node@v3 with: node-version: 16.x - cache: 'yarn' + cache: 'pnpm' - name: Install dependencies - run: rm -rf node_modules && yarn install --frozen-lockfile + run: rm -rf node_modules && pnpm install --frozen-lockfile - name: Test types - run: yarn ci:test:types + run: pnpm ci:test:types unit: runs-on: ${{ matrix.os }} @@ -71,10 +71,10 @@ jobs: with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ - cache: yarn + cache: pnpm - name: Install dependencies - run: rm -rf node_modules && yarn install --frozen-lockfile + run: rm -rf node_modules && pnpm install --frozen-lockfile - name: Unit test - run: yarn ci:test:unit + run: pnpm ci:test:unit diff --git a/package.json b/package.json index 858f58a..a61b482 100644 --- a/package.json +++ b/package.json @@ -17,18 +17,27 @@ "format:eslint": "run-s \" lint:eslint --fix \"", "format:prettier": "run-s \" lint:prettier --write \"", "format:stylelint": "run-s \" lint:stylelint --fix \"", - "lint": "run-p lint:*", - "lint:eslint": "eslint . --ext .js,.ts,.tsx --max-warnings 0 --ignore-path .gitignore", + "lint": "npm-run-all -p lint:*", + "lint:eslint": "eslint . --ext .js,.ts,.tsx --max-warnings 0 --ignore-path .gitignore --fix", "lint:prettier": "prettier \"**/*.(md|json|yml)\" --ignore-path .gitignore --check", - "lint:stylelint": "stylelint \"**/*.css\" --ignore-path .gitignore", + "lint:stylelint": "stylelint \"**/*.css\" --ignore-path .gitignore --fix", "test": "jest", "test:types": "tsc --noEmit", "prepare": "simple-git-hooks" }, "dependencies": { + "@ant-design/cssinjs": "1.18.4", "@eduardoac-skimlinks/webext-redux": "3.0.1-release-candidate", + "@emotion/react": "11.11.3", + "@emotion/styled": "11.11.0", "@material-ui/core": "4.12.4", "@material-ui/icons": "4.11.3", + "@mui/base": "5.0.0-beta.33", + "@mui/lab": "5.0.0-alpha.162", + "@mui/system": "5.15.6", + "ahooks": "3.7.9", + "@mui/icons-material": "5.15.5", + "@mui/material": "5.15.5", "@reduxjs/toolkit": "1.8.4", "@types/redux-thunk": "2.1.0", "clsx": "2.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 80a40bc..06b7abd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,21 +5,48 @@ settings: excludeLinksFromLockfile: false dependencies: + '@ant-design/cssinjs': + specifier: 1.18.4 + version: 1.18.4(react-dom@18.2.0)(react@18.2.0) '@eduardoac-skimlinks/webext-redux': specifier: 3.0.1-release-candidate version: 3.0.1-release-candidate(redux@4.2.1) + '@emotion/react': + specifier: 11.11.3 + version: 11.11.3(@types/react@18.0.17)(react@18.2.0) + '@emotion/styled': + specifier: 11.11.0 + version: 11.11.0(@emotion/react@11.11.3)(@types/react@18.0.17)(react@18.2.0) '@material-ui/core': specifier: 4.12.4 version: 4.12.4(@types/react@18.0.17)(react-dom@18.2.0)(react@18.2.0) '@material-ui/icons': specifier: 4.11.3 version: 4.11.3(@material-ui/core@4.12.4)(@types/react@18.0.17)(react-dom@18.2.0)(react@18.2.0) + '@mui/base': + specifier: 5.0.0-beta.33 + version: 5.0.0-beta.33(@types/react@18.0.17)(react-dom@18.2.0)(react@18.2.0) + '@mui/icons-material': + specifier: 5.15.5 + version: 5.15.5(@mui/material@5.15.5)(@types/react@18.0.17)(react@18.2.0) + '@mui/lab': + specifier: 5.0.0-alpha.162 + version: 5.0.0-alpha.162(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@5.15.5)(@types/react@18.0.17)(react-dom@18.2.0)(react@18.2.0) + '@mui/material': + specifier: 5.15.5 + version: 5.15.5(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@types/react@18.0.17)(react-dom@18.2.0)(react@18.2.0) + '@mui/system': + specifier: 5.15.6 + version: 5.15.6(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@types/react@18.0.17)(react@18.2.0) '@reduxjs/toolkit': specifier: 1.8.4 version: 1.8.4(react-redux@7.2.8)(react@18.2.0) '@types/redux-thunk': specifier: 2.1.0 version: 2.1.0(redux@4.2.1) + ahooks: + specifier: 3.7.9 + version: 3.7.9(react@18.2.0) clsx: specifier: 2.1.0 version: 2.1.0 @@ -221,6 +248,26 @@ packages: '@jridgewell/trace-mapping': 0.3.18 dev: true + /@ant-design/cssinjs@1.18.4(react-dom@18.2.0)(react@18.2.0): + resolution: + { + integrity: sha512-IrUAOj5TYuMG556C9gdbFuOrigyhzhU5ZYpWb3gYTxAwymVqRbvLzFCZg6OsjLBR6GhzcxYF3AhxKmjB+rA2xA==, + } + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + dependencies: + '@babel/runtime': 7.23.8 + '@emotion/hash': 0.8.0 + '@emotion/unitless': 0.7.5 + classnames: 2.5.1 + csstype: 3.1.3 + rc-util: 5.38.1(react-dom@18.2.0)(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + stylis: 4.2.0 + dev: false + /@babel/code-frame@7.22.5: resolution: { @@ -229,7 +276,6 @@ packages: engines: { node: '>=6.9.0' } dependencies: '@babel/highlight': 7.22.5 - dev: true /@babel/compat-data@7.22.9: resolution: @@ -433,7 +479,6 @@ packages: engines: { node: '>=6.9.0' } dependencies: '@babel/types': 7.22.5 - dev: true /@babel/helper-module-transforms@7.22.9(@babel/core@7.22.9): resolution: @@ -536,7 +581,6 @@ packages: integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==, } engines: { node: '>=6.9.0' } - dev: true /@babel/helper-validator-identifier@7.22.5: resolution: @@ -544,7 +588,6 @@ packages: integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==, } engines: { node: '>=6.9.0' } - dev: true /@babel/helper-validator-option@7.22.5: resolution: @@ -590,7 +633,6 @@ packages: '@babel/helper-validator-identifier': 7.22.5 chalk: 2.4.2 js-tokens: 4.0.0 - dev: true /@babel/parser@7.22.7: resolution: @@ -2018,6 +2060,16 @@ packages: dependencies: regenerator-runtime: 0.13.11 + /@babel/runtime@7.23.8: + resolution: + { + integrity: sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==, + } + engines: { node: '>=6.9.0' } + dependencies: + regenerator-runtime: 0.14.1 + dev: false + /@babel/template@7.22.5: resolution: { @@ -2061,7 +2113,6 @@ packages: '@babel/helper-string-parser': 7.22.5 '@babel/helper-validator-identifier': 7.22.5 to-fast-properties: 2.0.0 - dev: true /@bcoe/v8-coverage@0.2.3: resolution: @@ -2354,6 +2405,38 @@ packages: redux: 4.2.1 dev: false + /@emotion/babel-plugin@11.11.0: + resolution: + { + integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==, + } + dependencies: + '@babel/helper-module-imports': 7.22.5 + '@babel/runtime': 7.22.6 + '@emotion/hash': 0.9.1 + '@emotion/memoize': 0.8.1 + '@emotion/serialize': 1.1.3 + babel-plugin-macros: 3.1.0 + convert-source-map: 1.9.0 + escape-string-regexp: 4.0.0 + find-root: 1.1.0 + source-map: 0.5.7 + stylis: 4.2.0 + dev: false + + /@emotion/cache@11.11.0: + resolution: + { + integrity: sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==, + } + dependencies: + '@emotion/memoize': 0.8.1 + '@emotion/sheet': 1.2.2 + '@emotion/utils': 1.2.1 + '@emotion/weak-memoize': 0.3.1 + stylis: 4.2.0 + dev: false + /@emotion/hash@0.8.0: resolution: { @@ -2361,6 +2444,136 @@ packages: } dev: false + /@emotion/hash@0.9.1: + resolution: + { + integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==, + } + dev: false + + /@emotion/is-prop-valid@1.2.1: + resolution: + { + integrity: sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==, + } + dependencies: + '@emotion/memoize': 0.8.1 + dev: false + + /@emotion/memoize@0.8.1: + resolution: + { + integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==, + } + dev: false + + /@emotion/react@11.11.3(@types/react@18.0.17)(react@18.2.0): + resolution: + { + integrity: sha512-Cnn0kuq4DoONOMcnoVsTOR8E+AdnKFf//6kUWc4LCdnxj31pZWn7rIULd6Y7/Js1PiPHzn7SKCM9vB/jBni8eA==, + } + peerDependencies: + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.6 + '@emotion/babel-plugin': 11.11.0 + '@emotion/cache': 11.11.0 + '@emotion/serialize': 1.1.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) + '@emotion/utils': 1.2.1 + '@emotion/weak-memoize': 0.3.1 + '@types/react': 18.0.17 + hoist-non-react-statics: 3.3.2 + react: 18.2.0 + dev: false + + /@emotion/serialize@1.1.3: + resolution: + { + integrity: sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==, + } + dependencies: + '@emotion/hash': 0.9.1 + '@emotion/memoize': 0.8.1 + '@emotion/unitless': 0.8.1 + '@emotion/utils': 1.2.1 + csstype: 3.1.2 + dev: false + + /@emotion/sheet@1.2.2: + resolution: + { + integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==, + } + dev: false + + /@emotion/styled@11.11.0(@emotion/react@11.11.3)(@types/react@18.0.17)(react@18.2.0): + resolution: + { + integrity: sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==, + } + peerDependencies: + '@emotion/react': ^11.0.0-rc.0 + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.6 + '@emotion/babel-plugin': 11.11.0 + '@emotion/is-prop-valid': 1.2.1 + '@emotion/react': 11.11.3(@types/react@18.0.17)(react@18.2.0) + '@emotion/serialize': 1.1.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) + '@emotion/utils': 1.2.1 + '@types/react': 18.0.17 + react: 18.2.0 + dev: false + + /@emotion/unitless@0.7.5: + resolution: + { + integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==, + } + dev: false + + /@emotion/unitless@0.8.1: + resolution: + { + integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==, + } + dev: false + + /@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@18.2.0): + resolution: + { + integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==, + } + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 18.2.0 + dev: false + + /@emotion/utils@1.2.1: + resolution: + { + integrity: sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==, + } + dev: false + + /@emotion/weak-memoize@0.3.1: + resolution: + { + integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==, + } + dev: false + /@esbuild/linux-loong64@0.14.54: resolution: { @@ -2406,6 +2619,46 @@ packages: - supports-color dev: true + /@floating-ui/core@1.5.3: + resolution: + { + integrity: sha512-O0WKDOo0yhJuugCx6trZQj5jVJ9yR0ystG2JaNAemYUWce+pmM6WUEFIibnWyEJKdrDxhm75NoSRME35FNaM/Q==, + } + dependencies: + '@floating-ui/utils': 0.2.1 + dev: false + + /@floating-ui/dom@1.5.4: + resolution: + { + integrity: sha512-jByEsHIY+eEdCjnTVu+E3ephzTOzkQ8hgUfGwos+bg7NlH33Zc5uO+QHz1mrQUOgIKKDD1RtS201P9NvAfq3XQ==, + } + dependencies: + '@floating-ui/core': 1.5.3 + '@floating-ui/utils': 0.2.1 + dev: false + + /@floating-ui/react-dom@2.0.6(react-dom@18.2.0)(react@18.2.0): + resolution: + { + integrity: sha512-IB8aCRFxr8nFkdYZgH+Otd9EVQPJoynxeFRGTB8voPoZMRWo8XjYuCRgpI1btvuKY69XMiLnW+ym7zoBHM90Rw==, + } + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/dom': 1.5.4 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@floating-ui/utils@0.2.1: + resolution: + { + integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==, + } + dev: false + /@humanwhocodes/config-array@0.9.5: resolution: { @@ -2919,6 +3172,273 @@ packages: react-is: 17.0.2 dev: false + /@mui/base@5.0.0-beta.32(@types/react@18.0.17)(react-dom@18.2.0)(react@18.2.0): + resolution: + { + integrity: sha512-4VptvYeLUYMJhZapWBkD50GmKfOc0XT381KJcTK3ncZYIl8MdBhpR6l8jOyeP5cixUPBJhstjrnmQEAHjCLriw==, + } + engines: { node: '>=12.0.0' } + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@floating-ui/react-dom': 2.0.6(react-dom@18.2.0)(react@18.2.0) + '@mui/types': 7.2.13(@types/react@18.0.17) + '@mui/utils': 5.15.6(@types/react@18.0.17)(react@18.2.0) + '@popperjs/core': 2.11.8 + '@types/react': 18.0.17 + clsx: 2.1.0 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@mui/base@5.0.0-beta.33(@types/react@18.0.17)(react-dom@18.2.0)(react@18.2.0): + resolution: + { + integrity: sha512-WcSpoJUw/UYHXpvgtl4HyMar2Ar97illUpqiS/X1gtSBp6sdDW6kB2BJ9OlVQ+Kk/RL2GDp/WHA9sbjAYV35ow==, + } + engines: { node: '>=12.0.0' } + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@floating-ui/react-dom': 2.0.6(react-dom@18.2.0)(react@18.2.0) + '@mui/types': 7.2.13(@types/react@18.0.17) + '@mui/utils': 5.15.6(@types/react@18.0.17)(react@18.2.0) + '@popperjs/core': 2.11.8 + '@types/react': 18.0.17 + clsx: 2.1.0 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@mui/core-downloads-tracker@5.15.6: + resolution: + { + integrity: sha512-0aoWS4qvk1uzm9JBs83oQmIMIQeTBUeqqu8u+3uo2tMznrB5fIKqQVCbCgq+4Tm4jG+5F7dIvnjvQ2aV7UKtdw==, + } + dev: false + + /@mui/icons-material@5.15.5(@mui/material@5.15.5)(@types/react@18.0.17)(react@18.2.0): + resolution: + { + integrity: sha512-qiql0fd1JY7TZ1wm1RldvU7sL8QUatE9OC12i/qm5rnm/caTFyAfOyTIR7qqxorsJvoZGyrzwoMkal6Ij9kM0A==, + } + engines: { node: '>=12.0.0' } + peerDependencies: + '@mui/material': ^5.0.0 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@mui/material': 5.15.5(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@types/react@18.0.17)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.0.17 + react: 18.2.0 + dev: false + + /@mui/lab@5.0.0-alpha.162(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@5.15.5)(@types/react@18.0.17)(react-dom@18.2.0)(react@18.2.0): + resolution: + { + integrity: sha512-nSdlhq1YVozKXn6mtItWmnU9b/gQ708RSWG6C+M/Y096MlQ7Mz1gdNWOEwcGw2HaNoNgDvuG0+0HKARAMIMaLg==, + } + engines: { node: '>=12.0.0' } + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@mui/material': '>=5.15.0' + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@emotion/react': 11.11.3(@types/react@18.0.17)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.3)(@types/react@18.0.17)(react@18.2.0) + '@mui/base': 5.0.0-beta.33(@types/react@18.0.17)(react-dom@18.2.0)(react@18.2.0) + '@mui/material': 5.15.5(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@types/react@18.0.17)(react-dom@18.2.0)(react@18.2.0) + '@mui/system': 5.15.6(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@types/react@18.0.17)(react@18.2.0) + '@mui/types': 7.2.13(@types/react@18.0.17) + '@mui/utils': 5.15.6(@types/react@18.0.17)(react@18.2.0) + '@types/react': 18.0.17 + clsx: 2.1.0 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@mui/material@5.15.5(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@types/react@18.0.17)(react-dom@18.2.0)(react@18.2.0): + resolution: + { + integrity: sha512-2KfA39f/UWeQl0O22UJs3x1nG3chYlyu9wnux5vTnxUTLzkgYIzQIHaH+ZOGpv5JiZBMKktAPNfhqyhSaQ49qQ==, + } + engines: { node: '>=12.0.0' } + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@emotion/react': 11.11.3(@types/react@18.0.17)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.3)(@types/react@18.0.17)(react@18.2.0) + '@mui/base': 5.0.0-beta.32(@types/react@18.0.17)(react-dom@18.2.0)(react@18.2.0) + '@mui/core-downloads-tracker': 5.15.6 + '@mui/system': 5.15.6(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@types/react@18.0.17)(react@18.2.0) + '@mui/types': 7.2.13(@types/react@18.0.17) + '@mui/utils': 5.15.6(@types/react@18.0.17)(react@18.2.0) + '@types/react': 18.0.17 + '@types/react-transition-group': 4.4.10 + clsx: 2.1.0 + csstype: 3.1.3 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-is: 18.2.0 + react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0) + dev: false + + /@mui/private-theming@5.15.6(@types/react@18.0.17)(react@18.2.0): + resolution: + { + integrity: sha512-ZBX9E6VNUSscUOtU8uU462VvpvBS7eFl5VfxAzTRVQBHflzL+5KtnGrebgf6Nd6cdvxa1o0OomiaxSKoN2XDmg==, + } + engines: { node: '>=12.0.0' } + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@mui/utils': 5.15.6(@types/react@18.0.17)(react@18.2.0) + '@types/react': 18.0.17 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /@mui/styled-engine@5.15.6(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(react@18.2.0): + resolution: + { + integrity: sha512-KAn8P8xP/WigFKMlEYUpU9z2o7jJnv0BG28Qu1dhNQVutsLVIFdRf5Nb+0ijp2qgtcmygQ0FtfRuXv5LYetZTg==, + } + engines: { node: '>=12.0.0' } + peerDependencies: + '@emotion/react': ^11.4.1 + '@emotion/styled': ^11.3.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@emotion/cache': 11.11.0 + '@emotion/react': 11.11.3(@types/react@18.0.17)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.3)(@types/react@18.0.17)(react@18.2.0) + csstype: 3.1.2 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /@mui/system@5.15.6(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@types/react@18.0.17)(react@18.2.0): + resolution: + { + integrity: sha512-J01D//u8IfXvaEHMBQX5aO2l7Q+P15nt96c4NskX7yp5/+UuZP8XCQJhtBtLuj+M2LLyXHYGmCPeblsmmscP2Q==, + } + engines: { node: '>=12.0.0' } + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@emotion/react': 11.11.3(@types/react@18.0.17)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.3)(@types/react@18.0.17)(react@18.2.0) + '@mui/private-theming': 5.15.6(@types/react@18.0.17)(react@18.2.0) + '@mui/styled-engine': 5.15.6(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(react@18.2.0) + '@mui/types': 7.2.13(@types/react@18.0.17) + '@mui/utils': 5.15.6(@types/react@18.0.17)(react@18.2.0) + '@types/react': 18.0.17 + clsx: 2.1.0 + csstype: 3.1.2 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /@mui/types@7.2.13(@types/react@18.0.17): + resolution: + { + integrity: sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g==, + } + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.0.17 + dev: false + + /@mui/utils@5.15.6(@types/react@18.0.17)(react@18.2.0): + resolution: + { + integrity: sha512-qfEhf+zfU9aQdbzo1qrSWlbPQhH1nCgeYgwhOVnj9Bn39shJQitEnXpSQpSNag8+uty5Od6PxmlNKPTnPySRKA==, + } + engines: { node: '>=12.0.0' } + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/prop-types': 15.7.11 + '@types/react': 18.0.17 + prop-types: 15.8.1 + react: 18.2.0 + react-is: 18.2.0 + dev: false + /@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1: resolution: { @@ -2958,6 +3478,13 @@ packages: fastq: 1.15.0 dev: true + /@popperjs/core@2.11.8: + resolution: + { + integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==, + } + dev: false + /@reduxjs/toolkit@1.8.4(react-redux@7.2.8)(react@18.2.0): resolution: { @@ -3388,7 +3915,6 @@ packages: { integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==, } - dev: true /@types/parse5@6.0.3: resolution: @@ -3404,6 +3930,13 @@ packages: } dev: true + /@types/prop-types@15.7.11: + resolution: + { + integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==, + } + dev: false + /@types/prop-types@15.7.5: resolution: { @@ -3892,6 +4425,26 @@ packages: - supports-color dev: true + /ahooks@3.7.9(react@18.2.0): + resolution: + { + integrity: sha512-1nuCnaBe/DvZD2QAZVGLLmu0vDi6jxbiAP3Ghkj6Ocqk9YSXI6ydwo2x5I3lXowZyM8MNJDnHFvIo0vJS1CuFw==, + } + engines: { node: '>=8.0.0' } + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@babel/runtime': 7.23.8 + dayjs: 1.11.10 + intersection-observer: 0.12.2 + js-cookie: 2.2.1 + lodash-es: 4.17.21 + react: 18.2.0 + resize-observer-polyfill: 1.5.1 + screenfull: 5.2.0 + tslib: 2.6.1 + dev: false + /ajv@6.12.6: resolution: { @@ -3942,7 +4495,6 @@ packages: engines: { node: '>=4' } dependencies: color-convert: 1.9.3 - dev: true /ansi-styles@4.3.0: resolution: @@ -4257,7 +4809,6 @@ packages: '@babel/runtime': 7.22.6 cosmiconfig: 7.1.0 resolve: 1.22.2 - dev: true /babel-plugin-polyfill-corejs2@0.4.5(@babel/core@7.22.9): resolution: @@ -4532,7 +5083,6 @@ packages: integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, } engines: { node: '>=6' } - dev: true /camelcase-css@2.0.1: resolution: @@ -4587,7 +5137,6 @@ packages: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 supports-color: 5.5.0 - dev: true /chalk@3.0.0: resolution: @@ -4689,6 +5238,13 @@ packages: } dev: true + /classnames@2.5.1: + resolution: + { + integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==, + } + dev: false + /cli-cursor@3.1.0: resolution: { @@ -4773,7 +5329,6 @@ packages: } dependencies: color-name: 1.1.3 - dev: true /color-convert@2.0.1: resolution: @@ -4790,7 +5345,6 @@ packages: { integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==, } - dev: true /color-name@1.1.4: resolution: @@ -4906,7 +5460,6 @@ packages: { integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==, } - dev: true /core-js-compat@3.32.0: resolution: @@ -4947,7 +5500,6 @@ packages: parse-json: 5.2.0 path-type: 4.0.0 yaml: 1.10.2 - dev: true /cosmiconfig@8.2.0: resolution: @@ -5087,6 +5639,13 @@ packages: integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==, } + /csstype@3.1.3: + resolution: + { + integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==, + } + dev: false + /damerau-levenshtein@1.0.8: resolution: { @@ -5114,6 +5673,13 @@ packages: whatwg-url: 11.0.0 dev: true + /dayjs@1.11.10: + resolution: + { + integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==, + } + dev: false + /debug@2.6.9: resolution: { @@ -5491,7 +6057,6 @@ packages: } dependencies: is-arrayish: 0.2.1 - dev: true /es-abstract@1.22.1: resolution: @@ -5884,7 +6449,6 @@ packages: integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==, } engines: { node: '>=0.8.0' } - dev: true /escape-string-regexp@2.0.0: resolution: @@ -5900,7 +6464,6 @@ packages: integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, } engines: { node: '>=10' } - dev: true /escodegen@2.1.0: resolution: @@ -6552,7 +7115,6 @@ packages: { integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==, } - dev: true /find-up@4.1.0: resolution: @@ -6695,7 +7257,6 @@ packages: { integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==, } - dev: true /function.prototype.name@1.1.5: resolution: @@ -6994,7 +7555,6 @@ packages: integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==, } engines: { node: '>=4' } - dev: true /has-flag@4.0.0: resolution: @@ -7047,7 +7607,6 @@ packages: engines: { node: '>= 0.4.0' } dependencies: function-bind: 1.1.1 - dev: true /hoist-non-react-statics@3.3.2: resolution: @@ -7224,7 +7783,6 @@ packages: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - dev: true /import-lazy@4.0.0: resolution: @@ -7330,6 +7888,13 @@ packages: side-channel: 1.0.4 dev: true + /intersection-observer@0.12.2: + resolution: + { + integrity: sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==, + } + dev: false + /is-arguments@1.1.1: resolution: { @@ -7357,7 +7922,6 @@ packages: { integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==, } - dev: true /is-bigint@1.0.4: resolution: @@ -7404,7 +7968,6 @@ packages: } dependencies: has: 1.0.3 - dev: true /is-date-object@1.0.5: resolution: @@ -8247,6 +8810,13 @@ packages: - ts-node dev: true + /js-cookie@2.2.1: + resolution: + { + integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==, + } + dev: false + /js-tokens@4.0.0: resolution: { @@ -8357,7 +8927,6 @@ packages: { integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==, } - dev: true /json-schema-traverse@0.4.1: resolution: @@ -8588,7 +9157,6 @@ packages: { integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, } - dev: true /load-json-file@4.0.0: resolution: @@ -8623,6 +9191,13 @@ packages: p-locate: 5.0.0 dev: true + /lodash-es@4.17.21: + resolution: + { + integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==, + } + dev: false + /lodash.assignin@4.2.0: resolution: { @@ -9393,7 +9968,6 @@ packages: engines: { node: '>=6' } dependencies: callsites: 3.1.0 - dev: true /parse-json@4.0.0: resolution: @@ -9417,7 +9991,6 @@ packages: error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - dev: true /parse-passwd@1.0.0: resolution: @@ -9490,7 +10063,6 @@ packages: { integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, } - dev: true /path-type@3.0.0: resolution: @@ -9508,7 +10080,6 @@ packages: integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==, } engines: { node: '>=8' } - dev: true /picocolors@1.0.0: resolution: @@ -9819,6 +10390,21 @@ packages: engines: { node: '>=10' } dev: true + /rc-util@5.38.1(react-dom@18.2.0)(react@18.2.0): + resolution: + { + integrity: sha512-e4ZMs7q9XqwTuhIK7zBIVFltUtMSjphuPPQXHoHlzRzNdOwUxDejo0Zls5HYaJfRKNURcsS/ceKVULlhjBrxng==, + } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.23.8 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-is: 18.2.0 + dev: false + /react-dom@18.2.0(react@18.2.0): resolution: { @@ -9848,7 +10434,6 @@ packages: { integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==, } - dev: true /react-redux@7.2.8(react-dom@18.2.0)(react@18.2.0): resolution: @@ -10048,6 +10633,13 @@ packages: integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==, } + /regenerator-runtime@0.14.1: + resolution: + { + integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==, + } + dev: false + /regenerator-transform@0.15.1: resolution: { @@ -10132,6 +10724,13 @@ packages: } dev: false + /resize-observer-polyfill@1.5.1: + resolution: + { + integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==, + } + dev: false + /resolve-cwd@3.0.0: resolution: { @@ -10159,7 +10758,6 @@ packages: integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, } engines: { node: '>=4' } - dev: true /resolve-from@5.0.0: resolution: @@ -10197,7 +10795,6 @@ packages: is-core-module: 2.12.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - dev: true /resolve@1.22.3: resolution: @@ -10345,6 +10942,14 @@ packages: dependencies: loose-envify: 1.4.0 + /screenfull@5.2.0: + resolution: + { + integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==, + } + engines: { node: '>=0.10.0' } + dev: false + /semver@5.7.2: resolution: { @@ -10498,6 +11103,11 @@ packages: source-map: 0.6.1 dev: true + /source-map@0.5.7: + resolution: { integrity: sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= } + engines: { node: '>=0.10.0' } + dev: false + /source-map@0.6.1: resolution: { @@ -10838,6 +11448,13 @@ packages: - supports-color dev: true + /stylis@4.2.0: + resolution: + { + integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==, + } + dev: false + /supports-color@5.5.0: resolution: { @@ -10846,7 +11463,6 @@ packages: engines: { node: '>=4' } dependencies: has-flag: 3.0.0 - dev: true /supports-color@7.2.0: resolution: @@ -10885,7 +11501,6 @@ packages: integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, } engines: { node: '>= 0.4' } - dev: true /svg-tags@1.0.0: resolution: @@ -11035,7 +11650,6 @@ packages: integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, } engines: { node: '>=4' } - dev: true /to-regex-range@5.0.1: resolution: @@ -11173,7 +11787,6 @@ packages: { integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==, } - dev: true /tsutils@3.21.0(typescript@4.7.4): resolution: @@ -11736,7 +12349,6 @@ packages: integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==, } engines: { node: '>= 6' } - dev: true /yargs-parser@20.2.9: resolution: diff --git a/public/avatar.png b/public/avatar.png new file mode 100644 index 0000000..7e288d5 Binary files /dev/null and b/public/avatar.png differ diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx new file mode 100644 index 0000000..5aba5de --- /dev/null +++ b/src/components/Button/index.tsx @@ -0,0 +1,50 @@ +import React from 'react'; +import { Button as MButton, ButtonProps } from '@mui/material/'; +import { styled } from '@mui/material/styles'; + +const BasicStyleButton = styled(MButton)({ + border: '1px soild', + borderColor: '#9A6CF9', + color: '#A67CFE', + backgroundColor: '#FFFFFF', + borderRadius: '9999px', + textTransform: 'none', + lineHeight: '1.5', + '&:hover': { + borderColor: '#9A6CF9', + backgroundColor: '#FFFFFF', + }, +}); + +const PrimaryStyleButton = styled(MButton)({ + boxShadow: 'none', + color: '#FFFFFF', + backgroundColor: '#9A6CF9', + borderRadius: '9999px', + textTransform: 'none', + lineHeight: '1.5', + '&:hover': { + boxShadow: 'none', + backgroundColor: '#9A6CF9', + }, +}); + +const BasicButton = (props: ButtonProps) => { + return ( + + {props.children} + + ); +}; + +const PrimaryButton = (props: ButtonProps) => { + return ( + + {props.children} + + ); +}; + +export { BasicButton, PrimaryButton }; + +export default MButton; diff --git a/src/components/Divider/index.tsx b/src/components/Divider/index.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx new file mode 100644 index 0000000..4cdd802 --- /dev/null +++ b/src/components/Modal/index.tsx @@ -0,0 +1,61 @@ +import React from 'react'; +import { Modal as MModal, ModalProps } from '@mui/material'; + +interface ExtraModalProps extends ModalProps { + width?: number | string; +} + +const Close = () => ( + + + + +); + +const Modal = (props: ExtraModalProps) => { + return ( + +
+
+
props.onClose?.(e, 'backdropClick')} + className="absolute right-[30px] cursor-pointer z-50" + > + +
+ {props.children} +
+
+
+ ); +}; + +export default Modal; diff --git a/src/components/buttons/loginButton.tsx b/src/components/buttons/loginButton.tsx new file mode 100644 index 0000000..a81c0e6 --- /dev/null +++ b/src/components/buttons/loginButton.tsx @@ -0,0 +1,84 @@ +import * as React from 'react'; +import Button from '@mui/material/Button'; +import Stack from '@mui/material/Stack'; +import { styled } from '@mui/material/styles'; + +export const NextButton = styled(Button)({ + boxShadow: 'none', + textTransform: 'none', + fontSize: 16, + fontWeight: 'bold', + padding: '10px 94px', + borderRadius: '50px', + lineHeight: 1.5, + backgroundColor: '#9A6CF9', + borderColor: '#9A6CF9', + fontFamily: [ + '-apple-system', + 'BlinkMacSystemFont', + '"Segoe UI"', + 'Roboto', + '"Helvetica Neue"', + 'Arial', + 'sans-serif', + '"Apple Color Emoji"', + '"Segoe UI Emoji"', + '"Segoe UI Symbol"', + ].join(','), + '&:hover': { + backgroundColor: '#B08DF6', + borderColor: '#B08DF6', + boxShadow: 'none', + }, + '&:active': { + boxShadow: 'none', + backgroundColor: '#9C70F4', + borderColor: '#9C70F4', + }, + '&:focus': { + boxShadow: '0 0 0 0.2rem rgba(0,123,255,.5)', + }, +}); + +export const VerifyButton = styled(Button)({ + boxShadow: 'none', + textTransform: 'none', + fontSize: 14, + height: '25px', + width: '54px', + fontWeight: 'normal', + borderRadius: '27px', + lineHeight: 1, + backgroundColor: '#2C2A2A', + borderColor: '#2C2A2A', + fontFamily: [ + '-apple-system', + 'BlinkMacSystemFont', + '"Segoe UI"', + 'Roboto', + '"Helvetica Neue"', + 'Arial', + 'sans-serif', + '"Apple Color Emoji"', + '"Segoe UI Emoji"', + '"Segoe UI Symbol"', + ].join(','), + '&:hover': { + backgroundColor: '#2C2A2A', + borderColor: '#2C2A2A', + boxShadow: 'none', + }, + '&:focus': { + boxShadow: '0 0 0 0.2rem rgba(0,123,255,.5)', + }, +}); + +export default function CustomizedButtons() { + return ( + + + Bootstrap + + + ); +} diff --git a/src/components/twitterAdded/feedsPage/ethIcon.tsx b/src/components/twitterAdded/feedsPage/ethIcon.tsx new file mode 100644 index 0000000..39b4151 --- /dev/null +++ b/src/components/twitterAdded/feedsPage/ethIcon.tsx @@ -0,0 +1,73 @@ +import React, { FC } from 'react'; + +import '../../../tailwind.css'; + +interface FriendPriceProps { + price: number; // 假设价格是一个数字 +} + +export const FriendPrice: FC = ({ price }) => { + return ( +
+ + + + + + + + + + + + + + + +

{price}

+
+ ); +}; diff --git a/src/components/twitterAdded/feedsPage/voteIcon.tsx b/src/components/twitterAdded/feedsPage/voteIcon.tsx new file mode 100644 index 0000000..49eb339 --- /dev/null +++ b/src/components/twitterAdded/feedsPage/voteIcon.tsx @@ -0,0 +1,88 @@ +import React, { FC, useState } from 'react'; + +import '../../../tailwind.css'; + +interface VoteTwitterProps { + twitterId: string; + userName: string; +} + +export const VoteTwitter: FC = ({ twitterId, userName }) => { + const [voted, setVoted] = useState(false); + return ( +
setVoted(!voted)} + > + {!voted ? ( + + + + + + + + + + + + + + + + ) : ( + + + + + + + + + + + + + + + + )} +
+ ); +}; diff --git a/src/content/Content.tsx b/src/content/Content.tsx index 7a5bab4..b284d63 100644 --- a/src/content/Content.tsx +++ b/src/content/Content.tsx @@ -8,7 +8,7 @@ const Content = (): ReactElement => { style={{ position: 'fixed', zIndex: 999, - bottom: 0, + top: 0, right: 0, }} > diff --git a/src/content/addToTwitter.tsx b/src/content/addToTwitter.tsx new file mode 100644 index 0000000..a2e089a --- /dev/null +++ b/src/content/addToTwitter.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import { createRoot } from 'react-dom/client'; + +import { FriendPrice } from '../components/twitterAdded/feedsPage/ethIcon'; +import { VoteTwitter } from '../components/twitterAdded/feedsPage/voteIcon'; + +export const addPriceComponent = (element: Element, tweetId: string) => { + const priceContainer = document.createElement('div'); + const specificElement = element.querySelector( + 'article > div > div > div:nth-child(2) > div:nth-child(1)' + ); + + if (specificElement) { + const root = createRoot(priceContainer); + root.render( +
+ +
+ ); + specificElement.appendChild(priceContainer); + } +}; + +export const addVoteComponent = (element: Element, tweetId: string, userName: string) => { + const voteContainer = document.createElement('div'); + const specificElement = element.querySelector( + 'article > div > div > div:nth-child(2) > div:nth-child(2) > div:nth-child(4) > div > div' + ); + + if (specificElement) { + const root = createRoot(voteContainer); + root.render( +
+ +
+ ); + specificElement.appendChild(voteContainer); + } else { + // 如果不存在图文, div:nth-child(4) 便不存在,选在 div:nth-child(3) 的位置插入 + const specificElement2 = element.querySelector( + 'article > div > div > div:nth-child(2) > div:nth-child(2) > div:nth-child(3) > div > div' + ); + if (specificElement2) { + const root = createRoot(voteContainer); + root.render( +
+ +
+ ); + specificElement2.appendChild(voteContainer); + } + } +}; diff --git a/src/content/drawer/index.tsx b/src/content/drawer/index.tsx index 6475521..56f8037 100644 --- a/src/content/drawer/index.tsx +++ b/src/content/drawer/index.tsx @@ -1,85 +1,49 @@ -import React from 'react'; -import Divider from '@material-ui/core/Divider'; -import Drawer from '@material-ui/core/Drawer'; -import IconButton from '@material-ui/core/IconButton'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemText from '@material-ui/core/ListItemText'; -import { createStyles, makeStyles, Theme, useTheme } from '@material-ui/core/styles'; -import ChevronLeftIcon from '@material-ui/icons/ChevronLeft'; -import ChevronRightIcon from '@material-ui/icons/ChevronRight'; -import MailIcon from '@material-ui/icons/Mail'; -import MenuIcon from '@material-ui/icons/Menu'; -import InboxIcon from '@material-ui/icons/MoveToInbox'; -import clsx from 'clsx'; +import * as React from 'react'; +import ChevronRightIcon from '@mui/icons-material/ChevronRight'; +import MenuIcon from '@mui/icons-material/Menu'; +import Box from '@mui/material/Box'; +import Divider from '@mui/material/Divider'; +import Drawer from '@mui/material/Drawer'; +import IconButton from '@mui/material/IconButton'; +import { styled } from '@mui/material/styles'; -import { Counter } from '../features/counter/Counter'; +import Profile from '../../welcome/Profile'; +import Wallet from '../../welcome/Wallet'; +import CongratulationPage from '../loginPage/congratulationPage'; +import InvitePage from '../loginPage/invitePage'; +import SignInWithXPage from '../loginPage/signInWithXPage'; -const drawerWidth = 340; +import '../../tailwind.css'; -const useStyles = makeStyles((theme: Theme) => - createStyles({ - root: { - display: 'flex', - }, - appBar: { - transition: theme.transitions.create(['margin', 'width'], { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.leavingScreen, - }), - }, - appBarShift: { - width: `calc(100% - ${drawerWidth}px)`, - transition: theme.transitions.create(['margin', 'width'], { - easing: theme.transitions.easing.easeOut, - duration: theme.transitions.duration.enteringScreen, - }), - marginRight: drawerWidth, - }, - title: { - flexGrow: 1, - }, - hide: { - display: 'none', - }, - drawer: { - width: drawerWidth, - flexShrink: 0, - }, - drawerPaper: { - width: drawerWidth, - }, - drawerHeader: { - display: 'flex', - alignItems: 'center', - padding: theme.spacing(0, 1), - // necessary for content to be below app bar - ...theme.mixins.toolbar, - justifyContent: 'flex-start', - }, - content: { - flexGrow: 1, - padding: theme.spacing(3), - transition: theme.transitions.create('margin', { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.leavingScreen, - }), - marginRight: -drawerWidth, - }, - contentShift: { - transition: theme.transitions.create('margin', { - easing: theme.transitions.easing.easeOut, - duration: theme.transitions.duration.enteringScreen, - }), - marginRight: 0, - }, - }) -); +const drawerWidth = 463; + +const Main = styled('main', { shouldForwardProp: (prop) => prop !== 'open' })<{ + open?: boolean; +}>(({ theme, open }) => ({ + // flexGrow: 1, + // padding: theme.spacing(3), + transition: theme.transitions.create('margin', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + marginRight: -drawerWidth, + ...(open && { + transition: theme.transitions.create('margin', { + easing: theme.transitions.easing.easeOut, + duration: theme.transitions.duration.enteringScreen, + }), + marginRight: 0, + }), + /** + * This is necessary to enable the selection of content. In the DOM, the stacking order is determined + * by the order of appearance. Following this rule, elements appearing later in the markup will overlay + * those that appear earlier. Since the Drawer comes after the Main content, this adjustment ensures + * proper interaction with the underlying content. + */ + position: 'relative', +})); export default function PersistentDrawerRight() { - const classes = useStyles(); - const theme = useTheme(); const [open, setOpen] = React.useState(false); const handleDrawerOpen = () => { @@ -90,59 +54,52 @@ export default function PersistentDrawerRight() { setOpen(false); }; + const [pageState, setPageState] = React.useState('login'); + return ( -
+ - + -
-
-
+
-
- - {theme.direction === 'rtl' ? : } - +
+
+ +
+ + {pageState === 'login' && ( + setPageState('invite')} /> + )} + {pageState === 'invite' && ( + setPageState('congratulation')} /> + )} + {pageState === 'congratulation' && ( + setPageState('profile')} /> + )} + {pageState === 'profile' && setPageState('wallet')} />} + {pageState === 'wallet' && setPageState('profile')} />}
- - - - - {['Inbox', 'Starred', 'Send email'].map((text, index) => ( - - {index % 2 === 0 ? : } - - - ))} - - - {['All mail', 'Trash', 'Spam'].map((text, index) => ( - - {index % 2 === 0 ? : } - - - ))} - -
+
); } diff --git a/src/content/index.tsx b/src/content/index.tsx index 62c464e..129b295 100644 --- a/src/content/index.tsx +++ b/src/content/index.tsx @@ -5,55 +5,59 @@ import { Store } from '@eduardoac-skimlinks/webext-redux'; import { proxyStore as store } from '../app/proxyStore'; +import { addPriceComponent, addVoteComponent } from './addToTwitter'; import Content from './Content'; +const addTwitterComponent = () => { + const thirdElement = document.querySelectorAll( + '#react-root > div > div > div > main > div > div > div > div > div > div > div' + )[3]; + + // 现有元素的处理逻辑 + const targetElements = thirdElement.querySelectorAll('section > div > div > div'); + targetElements.forEach(function (element, index) { + const anchorElements = element.querySelectorAll('a'); + const hrefs = Array.from(anchorElements).map((anchor) => anchor.href); + const twitterUrlString = hrefs[hrefs.length - 1]; + if (twitterUrlString !== undefined) { + const urlObject = new URL(twitterUrlString); + const pathSegments = urlObject.pathname.split('/'); + const username = pathSegments[1]; + const tweetId = pathSegments[3]; + + // 判断是否存在已经插入的元素 + const existingPriceElement = document.getElementById('xfans-price-' + tweetId); + const existingVoteElement = document.getElementById('xfans-vote-' + tweetId); + + if (!existingPriceElement) { + addPriceComponent(element, tweetId); + } else { + // console.log('Element already exists for tweetId:', tweetId); + } + + if (!existingVoteElement) { + addVoteComponent(element, tweetId, username); + } else { + // console.log('Element already exists for tweetId:', tweetId); + } + } + }); +}; + withProxyStore(, store).then((component) => { const container = document.createElement('my-extension-root'); document.body.append(container); createRoot(container).render(component); - // 延迟执行的代码 + // 延迟执行的代码 3000毫秒后执行,即3秒 setTimeout(() => { - const thirdElement = document.querySelectorAll( - '#react-root > div > div > div > main > div > div > div > div > div > div > div' - )[3]; - - // 创建 MutationObserver 实例并传入回调函数 - const observer = new MutationObserver((mutationsList, observer) => { - mutationsList.forEach((mutation) => { - if (mutation.type === 'childList') { - mutation.addedNodes.forEach((node) => { - // 确保 node 是一个 Element 类型 - if (node.nodeType === Node.ELEMENT_NODE) { - const elementNode = node as Element; - const newAnchorElements = elementNode.querySelectorAll('a'); - - // 遍历并获取 href 属性 - const newHrefs = Array.from(newAnchorElements).map((anchor) => { - // 明确 anchor 是 HTMLAnchorElement 类型 - return (anchor as HTMLAnchorElement).href; - }); - - // 处理新的 hrefs - console.log('New hrefs:', newHrefs); - } - }); - } - }); - }); - - // 开始观察 thirdElement 的子元素 - observer.observe(thirdElement, { childList: true }); - - // 现有元素的处理逻辑 - const targetElements = thirdElement.querySelectorAll('section > div > div > div'); - targetElements.forEach(function (element, index) { - // const htmlElement = element as HTMLElement; - const anchorElements = element.querySelectorAll('a'); - const hrefs = Array.from(anchorElements).map((anchor) => anchor.href); - console.log('Element ' + (index + 1) + ' links: ', hrefs); - }); - }, 3000); // 3000毫秒后执行,即3秒 + setInterval(() => { + addTwitterComponent(); + }, 1000); // 每秒执行一次 + + // 也可以根据需要设置 clearInterval + // clearInterval(intervalId); + }, 3000); }); async function withProxyStore(children: ReactElement, proxyStore: Store): Promise { diff --git a/src/content/loginPage/congratulationPage.tsx b/src/content/loginPage/congratulationPage.tsx new file mode 100644 index 0000000..2db5844 --- /dev/null +++ b/src/content/loginPage/congratulationPage.tsx @@ -0,0 +1,71 @@ +import React, { FC } from 'react'; + +import { NextButton, VerifyButton } from '../../components/buttons/loginButton'; + +import '../../tailwind.css'; + +interface CongratulationPageProps { + handleButtonClick: () => void; // 定义一个函数类型的属性 +} + +const CongratulationPage: FC = ({ handleButtonClick }) => { + return ( +
+

+ Congration! +

+

+ Complete the following tasks to activate your account +

+
+ + + +

+ Follow @Letsmeme on Twitter +

+ undefined}> + verify + +
+
+ + + + +

+ Follow @Letsmeme on Twitter +

+ undefined}> + GO + +
+ + Start + +
+ ); +}; + +export default CongratulationPage; diff --git a/src/content/loginPage/invitePage.tsx b/src/content/loginPage/invitePage.tsx new file mode 100644 index 0000000..8f7b365 --- /dev/null +++ b/src/content/loginPage/invitePage.tsx @@ -0,0 +1,72 @@ +import React, { FC, useState } from 'react'; +import { styled } from '@mui/material/styles'; +import TextField from '@mui/material/TextField'; + +import { NextButton } from '../../components/buttons/loginButton'; + +import '../../tailwind.css'; + +const InviteCodeInput = styled(TextField)({ + width: '302px', + '& label.Mui-focused': { + color: '#A0AAB4', + }, + '& .MuiInput-underline:after': { + borderBottomColor: '#B2BAC2', + }, + '& .MuiOutlinedInput-root': { + '& fieldset': { + borderColor: '#E0E3E7', + borderRadius: '12px', + }, + '&:hover fieldset': { + borderColor: '#B2BAC2', + borderRadius: '12px', + }, + '&.Mui-focused fieldset': { + borderColor: '#6F7E8C', + borderRadius: '12px', + }, + }, +}); + +interface InvitePageProps { + handleButtonClick: (inviteCode: string) => void; // 修改函数类型以接收邀请码作为参数 +} + +const InvitePage: FC = ({ handleButtonClick }) => { + const [inviteCode, setInviteCode] = useState(''); // 添加状态来存储邀请码 + + const handleNextButtonClick = () => { + // 在点击事件中获取输入值并调用传入的函数 + if (inviteCode.trim() !== '') { + handleButtonClick(inviteCode); // 传递邀请码给父组件的函数 + } else { + // 如果邀请码为空,可以在这里添加提示或者错误处理 + alert('Invite code is required.'); + } + }; + return ( +
+

+ Invite Code +

+

+ To complete the registration you need to enter an invitation code, we released a small + number of invitation codes during the beta period, see our tweets +

+ ) => setInviteCode(e.target.value)} + label="Please enter the invitation code" + id="custom-css-outlined-input" + /> +
+ + Next + +
+ ); +}; + +export default InvitePage; diff --git a/src/content/loginPage/signInWithXPage.tsx b/src/content/loginPage/signInWithXPage.tsx new file mode 100644 index 0000000..d8bf2a9 --- /dev/null +++ b/src/content/loginPage/signInWithXPage.tsx @@ -0,0 +1,57 @@ +import React, { FC } from 'react'; + +import { NextButton } from '../../components/buttons/loginButton'; + +import '../../tailwind.css'; + +interface SignInWithXPageProps { + handleButtonClick: () => void; // 定义一个函数类型的属性 +} + +const SignInWithXPage: FC = ({ handleButtonClick }) => { + return ( +
+ + + + + + + + +

+ Log in to your account +

+

+ Grow with Creators, Win Wealth Together. +

+ + Sign in with X + +
+ ); +}; + +export default SignInWithXPage; diff --git a/src/manifest.ts b/src/manifest.ts index bf62d40..b325254 100644 --- a/src/manifest.ts +++ b/src/manifest.ts @@ -10,11 +10,11 @@ const manifest: ManifestV3Export = { }, content_scripts: [ { - matches: ['http://*/*', 'https://*/*', 'file:///*'], + matches: ['https://twitter.com/*'], js: ['src/content/index.tsx'], }, ], - host_permissions: [''], + host_permissions: ['https://twitter.com/*', 'https://x.com/*'], options_ui: { page: 'src/options/options.html', open_in_tab: true, @@ -25,7 +25,7 @@ const manifest: ManifestV3Export = { // this file is web accessible; it supports HMR b/c it's declared in `rollupOptions.input` 'src/welcome/welcome.html', ], - matches: [''], + matches: ['https://twitter.com/*', 'https://x.com/*'], }, ], action: { diff --git a/src/welcome/Profile/Claim.tsx b/src/welcome/Profile/Claim.tsx new file mode 100644 index 0000000..977b4bd --- /dev/null +++ b/src/welcome/Profile/Claim.tsx @@ -0,0 +1,229 @@ +import React from 'react'; +import { Divider } from '@mui/material'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TableRow from '@mui/material/TableRow'; +import { useToggle } from 'ahooks'; + +import { BasicButton, PrimaryButton } from '../../components/Button'; +import Modal from '../../components/Modal'; + +const Icon = () => ( + + + + + + + + + + + + + + + +); + +const rows = [ + { + date: '2023/02/01', + creator: 'Devon Lane', + rank: '#2', + total: ( +
+ + 0.234 +
+ ), + reward: ( +
+ + 0.001 +
+ ), + }, + { + date: '2023/02/01', + creator: 'Devon Lane', + rank: '#2', + total: ( +
+ + 0.234 +
+ ), + reward: ( +
+ + 0.001 +
+ ), + }, + { + date: '2023/02/01', + creator: 'Devon Lane', + rank: '#2', + total: ( +
+ + 0.234 +
+ ), + reward: ( +
+ + 0.001 +
+ ), + }, +]; + +const Claim = () => { + const [isOpen, { setLeft: close, setRight: open }] = useToggle(false); + + return ( + <> + + Claim + + +
+

Claim Reward

+
+ +
+
+ Reward: +
+ $294.3 +
+ + 0.2 +
+
+
+ + + Claim + +
+ + + + + + + + + Date + + + Creator + + + Rank + + + Total Reward + + + Your Reward + + + + + {rows.map((row, i) => ( + + + {row.date} + + + {row.creator} + + + {row.rank} + + + {row.total} + + + {row.reward} + + + ))} + +
+
+
+
+ + ); +}; + +export default Claim; diff --git a/src/welcome/Profile/Explore.tsx b/src/welcome/Profile/Explore.tsx new file mode 100644 index 0000000..eadcd9e --- /dev/null +++ b/src/welcome/Profile/Explore.tsx @@ -0,0 +1,261 @@ +import React from 'react'; +import TabContext from '@mui/lab/TabContext'; +import TabList from '@mui/lab/TabList'; +import TabPanel from '@mui/lab/TabPanel'; +import Box from '@mui/material/Box'; +import Tab from '@mui/material/Tab'; + +const Icon = () => ( + + + + + + + + + + + + + + + +); + +const Explore = () => { + const list = Array(7).fill(''); + + const [value, setValue] = React.useState('1'); + + const handleChange = (event: React.SyntheticEvent, newValue: string) => { + setValue(newValue); + }; + return ( +
+ + + + + + + + + + +
    + {list.map((item, i) => ( +
  • + 1 + avatar +
    +
    + JamesXYC@MAP Protocol -Bitcoin + @IDOC +
    + +
    +
    + Price + + 2.34 +
    + +
    + Tweet Avg Rank: + #3 +
    +
    +
    +
  • + ))} +
+
+ +
    + {list.map((item, i) => ( +
  • + 1 + avatar +
    +
    + JamesXYC@MAP Protocol -Bitcoin + @IDOC +
    + +
    +
    + Price + + 2.34 +
    + +
    + Tweet Avg Rank: + #3 +
    +
    +
    +
  • + ))} +
+
+ +
    + {list.map((item, i) => ( +
  • + 1 + avatar +
    +
    + JamesXYC@MAP Protocol -Bitcoin + @IDOC +
    + +
    +
    + Price + + 2.34 +
    + +
    + Tweet Avg Rank: + #3 +
    +
    +
    +
  • + ))} +
+
+ +
    + {list.map((item, i) => ( +
  • + 2024/01/10 12:14 +
    +
    +
    + avatar + @Devon +
    + + Bought + +
    + avatar + @Devon +
    +
    + +
    + +2 Shares +
    + + - 0.2025 +
    +
    +
    +
  • + ))} +
+
+
+
+ ); +}; + +export default Explore; diff --git a/src/welcome/Profile/History.tsx b/src/welcome/Profile/History.tsx new file mode 100644 index 0000000..cb7ac03 --- /dev/null +++ b/src/welcome/Profile/History.tsx @@ -0,0 +1,228 @@ +import React from 'react'; +import { Divider } from '@mui/material'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TableRow from '@mui/material/TableRow'; +import { useToggle } from 'ahooks'; + +import { BasicButton } from '../../components/Button'; +import Modal from '../../components/Modal'; + +const Icon = () => ( + + + + + + + + + + + + + + + +); + +const rows = [ + { + date: '2023/02/01', + creator: 'Devon Lane', + rank: '#2', + total: ( +
+ + 0.234 +
+ ), + reward: ( +
+ + 0.001 +
+ ), + }, + { + date: '2023/02/01', + creator: 'Devon Lane', + rank: '#2', + total: ( +
+ + 0.234 +
+ ), + reward: ( +
+ + 0.001 +
+ ), + }, + { + date: '2023/02/01', + creator: 'Devon Lane', + rank: '#2', + total: ( +
+ + 0.234 +
+ ), + reward: ( +
+ + 0.001 +
+ ), + }, +]; + +const History = () => { + const [isOpen, { setLeft: close, setRight: open }] = useToggle(false); + + return ( + <> + + History + + +
+

Claim History

+
+ +
+
+ Reward: +
+ $294.3 +
+ + 0.2 +
+
+
+
+ + + + + + + + + Date + + + Creator + + + Rank + + + Total Reward + + + Your Reward + + + + + {rows.map((row, i) => ( + + + {row.date} + + + {row.creator} + + + {row.rank} + + + {row.total} + + + {row.reward} + + + ))} + +
+
+
+
+ + ); +}; + +export default History; diff --git a/src/welcome/Profile/Reward.tsx b/src/welcome/Profile/Reward.tsx new file mode 100644 index 0000000..89eb817 --- /dev/null +++ b/src/welcome/Profile/Reward.tsx @@ -0,0 +1,191 @@ +import React from 'react'; +import TabContext from '@mui/lab/TabContext'; +import TabList from '@mui/lab/TabList'; +import TabPanel from '@mui/lab/TabPanel'; +import { Divider } from '@mui/material'; +import Box from '@mui/material/Box'; +import Tab from '@mui/material/Tab'; + +import Claim from './Claim'; +import History from './History'; + +const Icon = () => ( + + + + + + + + + + + + + + + +); + +const Reward = () => { + const list = Array(7).fill(''); + const [value, setValue] = React.useState('1'); + + const handleChange = (event: React.SyntheticEvent, newValue: string) => { + setValue(newValue); + }; + + return ( + <> +
+
+
+
+ + 2 +
+ Pool +
+ +
+
+ + 0.4 +
+ Your Reward +
+
+ +
+ + +
+
+ +
+ + + + + + + + +
    + {list.map((item, i) => ( +
  • +
    +
    + +
    + Devon + Jan 05 2024, 14:32 +
    +
    + + #3 +
    + +

    + History is always extremely similar bitcoin is the invention of satoshi + nakamoto, Chinese people early to give him dry up ethereum is v god made +

    + + +
  • + ))} +
+
+ +
    +
  • +
    +
    + +
    + Devon + Jan 05 2024, 14:32 +
    +
    + + #3 +
    + +

    + History is always extremely similar bitcoin is the invention of satoshi nakamoto, + Chinese people early to give him dry up ethereum is v god made +

    + + +
  • +
+
+
+
+ + ); +}; + +export default Reward; diff --git a/src/welcome/Profile/index.tsx b/src/welcome/Profile/index.tsx new file mode 100644 index 0000000..ae47752 --- /dev/null +++ b/src/welcome/Profile/index.tsx @@ -0,0 +1,136 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import React, { useState } from 'react'; + +import Explore from './Explore'; +import Reward from './Reward'; + +const Profile = (props: { handleButtonClick?: () => void }) => { + const [key, setKey] = useState('explore'); + + const tapMap = [ + { + title: 'explore', + onClick: () => setKey('explore'), + }, + { + title: 'community', + onClick: () => setKey('community'), + }, + { + title: 'reward', + onClick: () => setKey('reward'), + }, + ]; + + const componentMap: Record = { + explore: , + reward: , + }; + + return ( +
+
+
+ + + + + + + + + + +
+ +
+ Holding: + + + + + + + + + + + + + + + + 0.02 +
+ +
props.handleButtonClick?.()} + className="px-4 py-1 flex items-center justify-center rounded-full border border-black text-[15px] font-medium cursor-pointer" + > + Wallet +
+
+ +
+ {tapMap.map((item, i) => ( +
+ {item.title} +
+ ))} +
+ + {componentMap[key]} +
+ ); +}; + +export default Profile; diff --git a/src/welcome/Wallet/BuyModal.tsx b/src/welcome/Wallet/BuyModal.tsx new file mode 100644 index 0000000..2ba5f2a --- /dev/null +++ b/src/welcome/Wallet/BuyModal.tsx @@ -0,0 +1,163 @@ +import React from 'react'; +import { Divider } from '@mui/material'; +import { useToggle } from 'ahooks'; + +import { BasicButton, PrimaryButton } from '../../components/Button'; +import Modal from '../../components/Modal'; + +const Icon = () => ( + + + + + + + + + + + + + + + +); + +const Left = () => ( + + + + +); + +const BuyModal = () => { + const [isOpen, { setLeft: close, setRight: open }] = useToggle(false); + + return ( + <> + + Buy + + +
+

Buy Shares of Willaim

+
+ +
+ Price: + + 0.2 +
+ +
+ Amount + 2 +
+ +
+ Minimum unit: + 0.1 +
+ + + +
+
+ From + 0x41...64fd +
+
+ To + 0x41...64fd +
+
+ Transaction Fee +
+ + 0.002 +
+
+
+ Est. Gas Fee +
+ + 0.002 +
+
+
+ + + +
+
+ You Pay(Including Fees) +
+ + 0.052 +
+
+
+ Wallet Balance +
+ + 20.2928 +
+
+
+ +
+ +
+ + Go Back +
+
+ + Buy + +
+
+
+ + ); +}; + +export default BuyModal; diff --git a/src/welcome/Wallet/Deposit.tsx b/src/welcome/Wallet/Deposit.tsx new file mode 100644 index 0000000..73fae20 --- /dev/null +++ b/src/welcome/Wallet/Deposit.tsx @@ -0,0 +1,91 @@ +import React from 'react'; +import { useToggle } from 'ahooks'; + +import { BasicButton, PrimaryButton } from '../../components/Button'; +import Modal from '../../components/Modal'; + +const Left = () => ( + + + + +); + +const Deposit = () => { + const [isOpen, { setLeft: close, setRight: open }] = useToggle(false); + + return ( + <> + + Deposit + + +
+

Deposit

+
+ +
+
+ Network +
+ Blast +
+
+
+ Address +
+ 0x415eB....c2764fd +
+
+
+ Asset +
+ ETH +
+
+
+
+ +
+ + Go Back +
+
+ + Transfer + +
+
+
+ + ); +}; + +export default Deposit; diff --git a/src/welcome/Wallet/InviteFriends.tsx b/src/welcome/Wallet/InviteFriends.tsx new file mode 100644 index 0000000..02c86cc --- /dev/null +++ b/src/welcome/Wallet/InviteFriends.tsx @@ -0,0 +1,132 @@ +import React from 'react'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TableRow from '@mui/material/TableRow'; +import { useToggle } from 'ahooks'; + +import { BasicButton } from '../../components/Button'; +import Modal from '../../components/Modal'; + +const Copy = () => ( + + + + +); + +const rows = [ + { + time: 'Jan 05 2024, 14:32', + user: 'Cody Fisher', + value: 0.001, + }, + { + time: 'Jan 05 2024, 14:32', + user: 'Cody Fisher', + value: 0.001, + }, + { + time: 'Jan 05 2024, 14:32', + user: 'Cody Fisher', + value: 0.001, + }, +]; + +const InviteFriends = () => { + const [isOpen, { setLeft: close, setRight: open }] = useToggle(false); + + return ( + <> + + Invite Friends + + +
+

Invite Friends

+
+ +
+
+
+
+ Your Invite + 5 +
+
+
+
+
+ Invite Points + 0.05 +
+
+
+
+ +
+
+ 0x415eB....c2764fd +
+
+
+ Copy Invite Code + +
+
+
+ + + + + + Holder + Hold shares + Shares Value + + + + {rows.map((row, i) => ( + + + {row.time} + + {row.user} + {row.value} + + ))} + +
+
+
+
+ + ); +}; + +export default InviteFriends; diff --git a/src/welcome/Wallet/Profile.tsx b/src/welcome/Wallet/Profile.tsx new file mode 100644 index 0000000..f53c8d6 --- /dev/null +++ b/src/welcome/Wallet/Profile.tsx @@ -0,0 +1,198 @@ +import React, { useState } from 'react'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TableRow from '@mui/material/TableRow'; +import { useToggle } from 'ahooks'; + +import { BasicButton } from '../../components/Button'; +import Modal from '../../components/Modal'; + +import BuyModal from './BuyModal'; +import SellModal from './SellModal'; + +const Icon = () => ( + + + + + + + + + + + + + + + +); + +const rows = [ + { + holder: ( +
+ + Devon Lane +
+ ), + shares: 1, + value: ( +
+ + 0.002 +
+ ), + }, + { + holder: ( +
+ + Devon Lane +
+ ), + shares: 1, + value: ( +
+ + 0.002 +
+ ), + }, + { + holder: ( +
+ + Devon Lane +
+ ), + shares: 1, + value: ( +
+ + 0.002 +
+ ), + }, +]; + +const ProfileModal = () => { + const [isOpen, { setLeft: close, setRight: open }] = useToggle(false); + const [key, setKey] = useState(0); + const list = [ + { + text: 'Holders (20)', + }, + { + text: 'Holders (16)', + }, + { + text: ' Tweet Ranking', + }, + ]; + + return ( + <> + + Profile + + +
+

Profile

+
+ +
+
+ avatar +
+ + Devonkokl + + @Idoc +
+ Floor Price: + + 0.2 +
+
+
+ +
+ + +
+
+ +
+ +
+ {list.map((item, i) => ( +
setKey(i)} + key={item.text} + className={`rounded-full py-2 px-[18px] font-medium leading-[18px] border border-[#0F1419] ${ + key === i ? 'bg-[#2C2A2A] text-white' : 'text-[#0F1419] bg-white cursor-pointer' + }`} + > + {item.text} +
+ ))} +
+ + + + + + Holder + Hold shares + Shares Value + + + + {rows.map((row, i) => ( + + + {row.holder} + + {row.shares} + {row.value} + + ))} + +
+
+
+
+ + ); +}; + +export default ProfileModal; diff --git a/src/welcome/Wallet/SellModal.tsx b/src/welcome/Wallet/SellModal.tsx new file mode 100644 index 0000000..b94f22c --- /dev/null +++ b/src/welcome/Wallet/SellModal.tsx @@ -0,0 +1,170 @@ +import React from 'react'; +import { Divider } from '@mui/material'; +import { useToggle } from 'ahooks'; + +import { BasicButton, PrimaryButton } from '../../components/Button'; +import Modal from '../../components/Modal'; + +const Icon = () => ( + + + + + + + + + + + + + + + +); + +const Left = () => ( + + + + +); + +const SellModal = () => { + const [isOpen, { setLeft: close, setRight: open }] = useToggle(false); + + return ( + <> + + Sell + + +
+

Sell Shares of Willaim

+
+ +
+
+ Price: + + 0.2 +
+ +
+ You Own: + 5 +
+
+ +
+ Amount + 2 +
+ +
+ Minimum unit: + 0.1 +
+ + + +
+
+ From + 0x41...64fd +
+
+ To + 0x41...64fd +
+
+ Transaction Fee +
+ + 0.002 +
+
+
+ Est. Gas Fee +
+ + 0.002 +
+
+
+ + + +
+
+ You Pay(Including Fees) +
+ + 0.052 +
+
+
+ Wallet Balance +
+ + 20.2928 +
+
+
+ +
+ +
+ + Go Back +
+
+ + Buy + +
+
+
+ + ); +}; + +export default SellModal; diff --git a/src/welcome/Wallet/WithDraw.tsx b/src/welcome/Wallet/WithDraw.tsx new file mode 100644 index 0000000..a1d3984 --- /dev/null +++ b/src/welcome/Wallet/WithDraw.tsx @@ -0,0 +1,126 @@ +import React from 'react'; +import { styled, TextField as MTextField } from '@mui/material'; +import { useToggle } from 'ahooks'; + +import { BasicButton, PrimaryButton } from '../../components/Button'; +import Modal from '../../components/Modal'; + +const Icon = () => ( + + + + + + + + + + + + + + + +); + +const TextField = styled(MTextField)({ + width: '493px', + '& label.Mui-focused': { + color: '#A0AAB4', + }, + '& .MuiOutlinedInput-root': { + '& fieldset': { + borderColor: '#E0E3E7', + borderRadius: '8px', + }, + '&:hover fieldset': { + borderColor: '#9A6CF9', + borderRadius: '8px', + }, + '&.Mui-focused fieldset': { + borderColor: '#9A6CF9', + borderRadius: '8px', + }, + }, +}); + +const Left = () => ( + + + + +); + +const WithDraw = () => { + const [isOpen, { setLeft: close, setRight: open }] = useToggle(false); + + return ( + <> + + Withdraw + + +
+

Withdraw

+
+

+ Send your ETH to another wallet address on the blast network +

+ +
+ + +
+ +
+ Wallet Balance: +
+ + 0.02 +
+
+
+ +
+ + Go Back +
+
+ + Transfer + +
+
+
+ + ); +}; + +export default WithDraw; diff --git a/src/welcome/Wallet/index.tsx b/src/welcome/Wallet/index.tsx new file mode 100644 index 0000000..24442e2 --- /dev/null +++ b/src/welcome/Wallet/index.tsx @@ -0,0 +1,238 @@ +import React from 'react'; + +import Deposit from './Deposit'; +import InviteFriends from './InviteFriends'; +import WithDraw from './WithDraw'; + +const Copy = () => ( + + + + +); + +const Network = () => ( + + + + + + + + + + +); + +const WalletIcon = () => ( + + + + + + +); + +const Fire = () => ( + + + +); + +const Gift = () => ( + + + + + + + +); + +const Icon = () => ( + + + + + + + + + + + + + + + +); + +const GoBack = () => ( + + + + +); + +const Wallet = (props: { handleButtonClick?: () => void }) => { + return ( +
+
+
props.handleButtonClick?.()}> + +
+ Home +
+
+
+
+ avatar +
+ @Deovokoejhdnad +
+ #919099 + +
+
+ Network:Blast + +
+
+
+ +
+ +
+
+
+
+ + Wallet Balance +
+
+ + 390 +
+
+ +
+
+ + Transaction Fee Earned +
+
+ + 0.289 +
+
+ +
+
+ + Reward Earned +
+
+ + 22.9092 +
+
+
+
+ +
+ {/*
+ + +
*/} +
+ + +
+ +
+ Log Out +
+
+
+
+ ); +}; + +export default Wallet; diff --git a/src/welcome/Welcome.tsx b/src/welcome/Welcome.tsx index 6ce57e7..b2895d2 100644 --- a/src/welcome/Welcome.tsx +++ b/src/welcome/Welcome.tsx @@ -1,9 +1,11 @@ import React, { ReactElement } from 'react'; +import Profile from './Profile'; + const Welcome = (): ReactElement => { return ( -
-

Welcome

+
+
); }; diff --git a/src/welcome/assets/avatar.png b/src/welcome/assets/avatar.png new file mode 100644 index 0000000..7e288d5 Binary files /dev/null and b/src/welcome/assets/avatar.png differ diff --git a/src/welcome/index.tsx b/src/welcome/index.tsx index bebf642..c1d5af2 100644 --- a/src/welcome/index.tsx +++ b/src/welcome/index.tsx @@ -1,12 +1,13 @@ import React from 'react'; import { createRoot } from 'react-dom/client'; -import Welcome from './Welcome'; +import Wallet from './Wallet'; import '../tailwind.css'; createRoot(document.getElementById('root') as HTMLElement).render( - + {/* */} + );