From a3a49681ea652a00ec738eeac90ff062415bf6bf Mon Sep 17 00:00:00 2001 From: Cindy Sun Date: Thu, 6 May 2021 15:11:17 -0700 Subject: [PATCH] v1.0.15 --- .env.template | 6 + .eslintrc.json | 67 + .github/workflows/merge-request.yml | 19 + .gitignore | 38 + .gitlab-ci.yml | 105 + .prettierrc.js | 5 + Dockerfile | 34 + README.md | 72 + babel.config.json | 15 + .../AssetDisplay/AssetDisplay.styled.ts | 42 + components/AssetDisplay/AssetImage.tsx | 60 + components/AssetDisplay/AssetModel.tsx | 51 + components/AssetDisplay/AssetVideo.tsx | 16 + components/AssetDisplay/index.tsx | 39 + .../AssetFormBuy/AssetFormBuy.styled.ts | 73 + components/AssetFormBuy/index.tsx | 119 + .../AssetFormPopupMenu.styled.ts | 80 + components/AssetFormPopupMenu/index.tsx | 142 + components/AssetFormSell/index.tsx | 82 + .../AssetFormTitle/AssetFormTitle.styled.ts | 54 + components/AssetFormTitle/index.tsx | 74 + components/AssetMeta/index.tsx | 139 + components/Banner/Banner.styled.ts | 37 + components/Banner/index.tsx | 46 + components/Button/Button.styled.ts | 66 + components/Button/index.tsx | 41 + components/ChooseCollection/index.tsx | 104 + .../CollectionBox/CollectionBox.styled.ts | 43 + components/CollectionBox/index.tsx | 28 + .../CollectionIcon/CollectionIcon.styled.ts | 15 + components/CollectionIcon/index.tsx | 42 + .../CollectionsCarousel.styled.ts | 136 + components/CollectionsCarousel/index.tsx | 186 + .../CreatePageLayout.styled.ts | 104 + components/CreatePageLayout/index.tsx | 54 + components/CreateTemplate/index.tsx | 166 + .../DetailsLayout/DetailsLayout.styled.ts | 69 + components/DetailsLayout/index.tsx | 117 + .../DragDropFileUploadLg.styled.ts | 107 + components/DragDropFileUploadLg/index.tsx | 136 + .../DragDropFileUploadSm.styled.ts | 39 + components/DragDropFileUploadSm/index.tsx | 90 + .../EmptyUserContent.styled.ts | 52 + components/EmptyUserContent/index.tsx | 32 + components/Error/Error.styled.ts | 37 + components/Error/index.tsx | 31 + components/ExploreCard/ExploreCard.styled.ts | 103 + components/ExploreCard/index.tsx | 62 + .../FeaturedCarousel.styled.ts | 125 + components/FeaturedCarousel/index.tsx | 186 + components/FeaturedGrid/index.tsx | 78 + components/Footer/Footer.styled.ts | 55 + components/Footer/index.tsx | 45 + components/Grid/Grid.styled.ts | 22 + components/Grid/index.tsx | 72 + .../HomepageStatistics.styled.ts | 106 + components/HomepageStatistics/index.tsx | 89 + components/InitialMint/index.tsx | 164 + components/InputField/InputField.styled.ts | 87 + components/InputField/index.tsx | 146 + components/LoadingPage/LoadingPage.styled.ts | 14 + components/LoadingPage/index.tsx | 20 + .../MobileCreatePagePlaceholder.styled.ts | 43 + .../MobileCreatePagePlaceholder/index.tsx | 24 + components/Modal/BurnAssetModal.tsx | 76 + components/Modal/CancelSaleModal.tsx | 127 + components/Modal/ClaimBalanceModal.tsx | 74 + components/Modal/CollectionModal.tsx | 357 + components/Modal/CreateSaleModal.tsx | 245 + components/Modal/MintAssetModal.tsx | 155 + components/Modal/Modal.styled.ts | 165 + components/Modal/TransferModal.tsx | 132 + components/Modal/index.tsx | 10 + components/NavBar/NavBar.styled.ts | 281 + components/NavBar/index.tsx | 257 + .../CreateNftSuccess.styled.ts | 79 + components/NftCreateSuccess/index.tsx | 51 + components/PageHeader/PageHeader.styled.tsx | 93 + components/PageHeader/index.tsx | 107 + components/PageLayout/PageLayout.styled.ts | 25 + components/PageLayout/index.tsx | 97 + .../PaginationButton.styled.ts | 32 + components/PaginationButton/index.tsx | 44 + components/ProfileTabs/ProfileTabs.styled.ts | 28 + components/ProfileTabs/index.tsx | 36 + components/Provider/AuthProvider.tsx | 141 + components/Provider/CreateAssetProvider.tsx | 56 + components/Provider/ModalProvider.tsx | 140 + components/Provider/index.ts | 17 + .../ReadMoreDescription.ts | 23 + components/ReadMoreDescription/index.tsx | 85 + .../SalesHistoryTable.styled.ts | 5 + components/SalesHistoryTable/index.tsx | 349 + .../SalesHistoryTableCell.styled.ts | 20 + components/SalesHistoryTableCell/index.tsx | 77 + components/SearchInput/SearchInput.styled.ts | 126 + components/SearchInput/index.tsx | 173 + .../SearchInputResultsList.styled.ts | 45 + components/SearchInputResultsList/index.tsx | 118 + .../ShareOnSocial/ShareOnSocial.styled.ts | 91 + components/ShareOnSocial/index.tsx | 88 + components/Spinner/Spinner.styled.ts | 40 + components/Spinner/index.tsx | 28 + .../TableContentWrapper.styled.ts | 11 + components/TableContentWraper/index.tsx | 48 + .../TableDataCell/TableDataCell.styled.ts | 26 + components/TableDataCell/index.tsx | 30 + .../TableHeaderCell/TableHeaderCell.styled.ts | 23 + components/TableHeaderCell/index.tsx | 11 + .../TableHeaderRow/TableHeader.styled.ts | 5 + components/TableHeaderRow/index.tsx | 11 + components/TableRow/TableRow.styled.ts | 8 + components/TableRow/index.tsx | 11 + .../TemplateCard/TemplateCard.styled.ts | 140 + components/TemplateCard/index.tsx | 196 + .../TemplateImage/TemplateImage.styled.ts | 29 + components/TemplateImage/index.tsx | 56 + .../TemplateVideo/TemplateVideo.styled.ts | 54 + components/TemplateVideo/index.tsx | 55 + components/Tooltip/Tooltip.styled.ts | 43 + components/Tooltip/index.tsx | 38 + hooks/index.ts | 154 + next-env.d.ts | 3 + next.config.js | 29 + package.json | 62 + pages/[collection]/[templateId].tsx | 206 + pages/[collection]/index.tsx | 199 + pages/_app.tsx | 67 + pages/_document.tsx | 69 + pages/api/profile.ts | 45 + pages/api/upload.ts | 85 + pages/create.tsx | 285 + .../[collection]/[templateId].tsx | 238 + pages/index.tsx | 23 + pages/search.tsx | 140 + pages/user/[chainAccount].tsx | 272 + public/Explore.png | Bin 0 -> 2825043 bytes public/ExploreMobile.png | Bin 0 -> 646393 bytes public/arrow.svg | 1 + public/audio.svg | 12 + public/banner-rectangle.png | Bin 0 -> 913204 bytes public/banner-square.png | Bin 0 -> 1471992 bytes public/beta-logo.svg | 1 + public/check.svg | 1 + public/chevron-right.svg | 1 + public/close.svg | 1 + public/default-avatar.png | Bin 0 -> 3304 bytes public/down-arrow.svg | 1 + public/ellipsis.svg | 1 + public/facebook-icon.svg | 1 + public/favicon.png | Bin 0 -> 2806 bytes public/fonts/CircularStd-Bold.woff | Bin 0 -> 38952 bytes public/fonts/CircularStd-Book.woff | Bin 0 -> 34468 bytes public/fonts/CircularStd-Medium.woff | Bin 0 -> 41824 bytes public/icon-light-chevron-down.svg | 1 + public/icon-light-close-16-px.svg | 1 + public/icon-light-search-24-px.svg | 1 + public/icon-monsters.png | Bin 0 -> 23420 bytes public/icons-close.svg | 1 + public/icons-small-menu.svg | 1 + public/launch.svg | 10 + public/link-icon.svg | 1 + public/linkedin-icon.svg | 1 + public/loading.svg | 1 + public/logo-colored@3x.png | Bin 0 -> 20935 bytes public/logo.svg | 1 + public/logo@3x.png | Bin 0 -> 14074 bytes public/mobile-create.png | Bin 0 -> 104677 bytes public/more.svg | 12 + public/nfts-created.svg | 1 + public/placeholder-asset.svg | 1 + public/placeholder-template-image.png | Bin 0 -> 38436 bytes public/plus-icon.png | Bin 0 -> 11891 bytes public/proton.svg | 1 + public/sales-today.svg | 1 + public/total-sales.svg | 1 + public/transactions.svg | 1 + public/twitter-icon.svg | 1 + public/upload-icon-small-circle.svg | 1 + public/upload-icon-small-shape.svg | 1 + public/upload-icon.svg | 1 + public/vercel.svg | 4 + public/video.svg | 12 + public/x.svg | 1 + server.js | 18 + services/assets.ts | 248 + services/collections.ts | 125 + services/fees.ts | 133 + services/firebase.ts | 42 + services/offers.ts | 63 + services/proton-rpc.ts | 170 + services/proton.ts | 1407 +++ services/sales.ts | 282 + services/statistics.ts | 154 + services/templates.ts | 539 + services/upload.ts | 18 + styles/Breakpoints.ts | 54 + styles/FadeInImageContainer.styled.ts | 15 + styles/MaxWidth.styled.ts | 13 + styles/Title.styled.ts | 19 + styles/customprogress.css | 15 + styles/globals.css | 36 + styles/index.styled.ts | 13 + styles/reset.css | 47 + tsconfig.json | 32 + types/index.d.ts | 11 + utils/browser-fetch.ts | 54 + utils/constants.ts | 94 + utils/gtag.ts | 42 + utils/index.ts | 101 + utils/init-middleware.ts | 13 + utils/node-fetch.ts | 71 + yarn.lock | 9168 +++++++++++++++++ 213 files changed, 24391 insertions(+) create mode 100644 .env.template create mode 100644 .eslintrc.json create mode 100644 .github/workflows/merge-request.yml create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 .prettierrc.js create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 babel.config.json create mode 100644 components/AssetDisplay/AssetDisplay.styled.ts create mode 100644 components/AssetDisplay/AssetImage.tsx create mode 100644 components/AssetDisplay/AssetModel.tsx create mode 100644 components/AssetDisplay/AssetVideo.tsx create mode 100644 components/AssetDisplay/index.tsx create mode 100644 components/AssetFormBuy/AssetFormBuy.styled.ts create mode 100644 components/AssetFormBuy/index.tsx create mode 100644 components/AssetFormPopupMenu/AssetFormPopupMenu.styled.ts create mode 100644 components/AssetFormPopupMenu/index.tsx create mode 100644 components/AssetFormSell/index.tsx create mode 100644 components/AssetFormTitle/AssetFormTitle.styled.ts create mode 100644 components/AssetFormTitle/index.tsx create mode 100644 components/AssetMeta/index.tsx create mode 100644 components/Banner/Banner.styled.ts create mode 100644 components/Banner/index.tsx create mode 100644 components/Button/Button.styled.ts create mode 100644 components/Button/index.tsx create mode 100644 components/ChooseCollection/index.tsx create mode 100644 components/CollectionBox/CollectionBox.styled.ts create mode 100644 components/CollectionBox/index.tsx create mode 100644 components/CollectionIcon/CollectionIcon.styled.ts create mode 100644 components/CollectionIcon/index.tsx create mode 100644 components/CollectionsCarousel/CollectionsCarousel.styled.ts create mode 100644 components/CollectionsCarousel/index.tsx create mode 100644 components/CreatePageLayout/CreatePageLayout.styled.ts create mode 100644 components/CreatePageLayout/index.tsx create mode 100644 components/CreateTemplate/index.tsx create mode 100644 components/DetailsLayout/DetailsLayout.styled.ts create mode 100644 components/DetailsLayout/index.tsx create mode 100644 components/DragDropFileUploadLg/DragDropFileUploadLg.styled.ts create mode 100644 components/DragDropFileUploadLg/index.tsx create mode 100644 components/DragDropFileUploadSm/DragDropFileUploadSm.styled.ts create mode 100644 components/DragDropFileUploadSm/index.tsx create mode 100644 components/EmptyUserContent/EmptyUserContent.styled.ts create mode 100644 components/EmptyUserContent/index.tsx create mode 100644 components/Error/Error.styled.ts create mode 100644 components/Error/index.tsx create mode 100644 components/ExploreCard/ExploreCard.styled.ts create mode 100644 components/ExploreCard/index.tsx create mode 100644 components/FeaturedCarousel/FeaturedCarousel.styled.ts create mode 100644 components/FeaturedCarousel/index.tsx create mode 100644 components/FeaturedGrid/index.tsx create mode 100644 components/Footer/Footer.styled.ts create mode 100644 components/Footer/index.tsx create mode 100644 components/Grid/Grid.styled.ts create mode 100644 components/Grid/index.tsx create mode 100644 components/HomepageStatistics/HomepageStatistics.styled.ts create mode 100644 components/HomepageStatistics/index.tsx create mode 100644 components/InitialMint/index.tsx create mode 100644 components/InputField/InputField.styled.ts create mode 100644 components/InputField/index.tsx create mode 100644 components/LoadingPage/LoadingPage.styled.ts create mode 100644 components/LoadingPage/index.tsx create mode 100644 components/MobileCreatePagePlaceholder/MobileCreatePagePlaceholder.styled.ts create mode 100644 components/MobileCreatePagePlaceholder/index.tsx create mode 100644 components/Modal/BurnAssetModal.tsx create mode 100644 components/Modal/CancelSaleModal.tsx create mode 100644 components/Modal/ClaimBalanceModal.tsx create mode 100644 components/Modal/CollectionModal.tsx create mode 100644 components/Modal/CreateSaleModal.tsx create mode 100644 components/Modal/MintAssetModal.tsx create mode 100644 components/Modal/Modal.styled.ts create mode 100644 components/Modal/TransferModal.tsx create mode 100644 components/Modal/index.tsx create mode 100644 components/NavBar/NavBar.styled.ts create mode 100644 components/NavBar/index.tsx create mode 100644 components/NftCreateSuccess/CreateNftSuccess.styled.ts create mode 100644 components/NftCreateSuccess/index.tsx create mode 100644 components/PageHeader/PageHeader.styled.tsx create mode 100644 components/PageHeader/index.tsx create mode 100644 components/PageLayout/PageLayout.styled.ts create mode 100644 components/PageLayout/index.tsx create mode 100644 components/PaginationButton/PaginationButton.styled.ts create mode 100644 components/PaginationButton/index.tsx create mode 100644 components/ProfileTabs/ProfileTabs.styled.ts create mode 100644 components/ProfileTabs/index.tsx create mode 100644 components/Provider/AuthProvider.tsx create mode 100644 components/Provider/CreateAssetProvider.tsx create mode 100644 components/Provider/ModalProvider.tsx create mode 100644 components/Provider/index.ts create mode 100644 components/ReadMoreDescription/ReadMoreDescription.ts create mode 100644 components/ReadMoreDescription/index.tsx create mode 100644 components/SalesHistoryTable/SalesHistoryTable.styled.ts create mode 100644 components/SalesHistoryTable/index.tsx create mode 100644 components/SalesHistoryTableCell/SalesHistoryTableCell.styled.ts create mode 100644 components/SalesHistoryTableCell/index.tsx create mode 100644 components/SearchInput/SearchInput.styled.ts create mode 100644 components/SearchInput/index.tsx create mode 100644 components/SearchInputResultsList/SearchInputResultsList.styled.ts create mode 100644 components/SearchInputResultsList/index.tsx create mode 100644 components/ShareOnSocial/ShareOnSocial.styled.ts create mode 100644 components/ShareOnSocial/index.tsx create mode 100644 components/Spinner/Spinner.styled.ts create mode 100644 components/Spinner/index.tsx create mode 100644 components/TableContentWraper/TableContentWrapper.styled.ts create mode 100644 components/TableContentWraper/index.tsx create mode 100644 components/TableDataCell/TableDataCell.styled.ts create mode 100644 components/TableDataCell/index.tsx create mode 100644 components/TableHeaderCell/TableHeaderCell.styled.ts create mode 100644 components/TableHeaderCell/index.tsx create mode 100644 components/TableHeaderRow/TableHeader.styled.ts create mode 100644 components/TableHeaderRow/index.tsx create mode 100644 components/TableRow/TableRow.styled.ts create mode 100644 components/TableRow/index.tsx create mode 100644 components/TemplateCard/TemplateCard.styled.ts create mode 100644 components/TemplateCard/index.tsx create mode 100644 components/TemplateImage/TemplateImage.styled.ts create mode 100644 components/TemplateImage/index.tsx create mode 100644 components/TemplateVideo/TemplateVideo.styled.ts create mode 100644 components/TemplateVideo/index.tsx create mode 100644 components/Tooltip/Tooltip.styled.ts create mode 100644 components/Tooltip/index.tsx create mode 100644 hooks/index.ts create mode 100644 next-env.d.ts create mode 100644 next.config.js create mode 100644 package.json create mode 100644 pages/[collection]/[templateId].tsx create mode 100644 pages/[collection]/index.tsx create mode 100644 pages/_app.tsx create mode 100644 pages/_document.tsx create mode 100644 pages/api/profile.ts create mode 100644 pages/api/upload.ts create mode 100644 pages/create.tsx create mode 100644 pages/details/[chainAccount]/[collection]/[templateId].tsx create mode 100644 pages/index.tsx create mode 100644 pages/search.tsx create mode 100644 pages/user/[chainAccount].tsx create mode 100644 public/Explore.png create mode 100644 public/ExploreMobile.png create mode 100644 public/arrow.svg create mode 100644 public/audio.svg create mode 100644 public/banner-rectangle.png create mode 100644 public/banner-square.png create mode 100644 public/beta-logo.svg create mode 100644 public/check.svg create mode 100644 public/chevron-right.svg create mode 100644 public/close.svg create mode 100644 public/default-avatar.png create mode 100644 public/down-arrow.svg create mode 100644 public/ellipsis.svg create mode 100644 public/facebook-icon.svg create mode 100644 public/favicon.png create mode 100644 public/fonts/CircularStd-Bold.woff create mode 100644 public/fonts/CircularStd-Book.woff create mode 100644 public/fonts/CircularStd-Medium.woff create mode 100644 public/icon-light-chevron-down.svg create mode 100644 public/icon-light-close-16-px.svg create mode 100644 public/icon-light-search-24-px.svg create mode 100644 public/icon-monsters.png create mode 100644 public/icons-close.svg create mode 100644 public/icons-small-menu.svg create mode 100644 public/launch.svg create mode 100644 public/link-icon.svg create mode 100644 public/linkedin-icon.svg create mode 100644 public/loading.svg create mode 100644 public/logo-colored@3x.png create mode 100644 public/logo.svg create mode 100644 public/logo@3x.png create mode 100644 public/mobile-create.png create mode 100644 public/more.svg create mode 100644 public/nfts-created.svg create mode 100644 public/placeholder-asset.svg create mode 100644 public/placeholder-template-image.png create mode 100644 public/plus-icon.png create mode 100644 public/proton.svg create mode 100644 public/sales-today.svg create mode 100644 public/total-sales.svg create mode 100644 public/transactions.svg create mode 100644 public/twitter-icon.svg create mode 100644 public/upload-icon-small-circle.svg create mode 100644 public/upload-icon-small-shape.svg create mode 100644 public/upload-icon.svg create mode 100644 public/vercel.svg create mode 100644 public/video.svg create mode 100644 public/x.svg create mode 100644 server.js create mode 100644 services/assets.ts create mode 100644 services/collections.ts create mode 100644 services/fees.ts create mode 100644 services/firebase.ts create mode 100644 services/offers.ts create mode 100644 services/proton-rpc.ts create mode 100644 services/proton.ts create mode 100644 services/sales.ts create mode 100644 services/statistics.ts create mode 100644 services/templates.ts create mode 100644 services/upload.ts create mode 100644 styles/Breakpoints.ts create mode 100644 styles/FadeInImageContainer.styled.ts create mode 100644 styles/MaxWidth.styled.ts create mode 100644 styles/Title.styled.ts create mode 100644 styles/customprogress.css create mode 100644 styles/globals.css create mode 100644 styles/index.styled.ts create mode 100644 styles/reset.css create mode 100644 tsconfig.json create mode 100644 types/index.d.ts create mode 100644 utils/browser-fetch.ts create mode 100644 utils/constants.ts create mode 100644 utils/gtag.ts create mode 100644 utils/index.ts create mode 100644 utils/init-middleware.ts create mode 100644 utils/node-fetch.ts create mode 100644 yarn.lock diff --git a/.env.template b/.env.template new file mode 100644 index 0000000..066e02a --- /dev/null +++ b/.env.template @@ -0,0 +1,6 @@ +NEXT_PUBLIC_CHAIN_ENDPOINTS='https://testnet.protonchain.com' +NEXT_PUBLIC_BLOCK_EXPLORER='https://proton-test.bloks.io/block/' +NEXT_PUBLIC_NFT_ENDPOINT='https://test.proton.api.atomicassets.io' +FIREBASE_API_KEY='string' +FIREBASE_AUTH_DOMAIN='string' +FIREBASE_PROJECT_ID='string' \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..a55c17a --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,67 @@ +{ + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": 12, + "sourceType": "module" + }, + "env": { + "browser": true, + "es2021": true, + "jest": true, + "node": true + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:react/recommended", + "plugin:jsx-a11y/recommended", + "plugin:react-hooks/recommended", + "prettier/@typescript-eslint", + "plugin:prettier/recommended" // keep this last so prettier config overrides other formatting rules + ], + "plugins": [ + "react" + ], + "rules": { + "react-hooks/exhaustive-deps": "off", + "react/react-in-jsx-scope": "off", + "react/prop-types": "off", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/explicit-function-return-type": "off", + "prettier/prettier": ["error", {}, { "usePrettierrc": true }], // Use our .prettierrc file as source + "@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }], // ignore args with _ (needed for React.forwardRef fix + "jsx-a11y/accessible-emoji": "off", + "jsx-a11y/anchor-is-valid": [ + "error", + { + "components": ["Link"], + "specialLink": ["hrefLeft", "hrefRight"], + "aspects": ["invalidHref", "preferButton"] + } + ], + "prefer-destructuring": ["error", { + "VariableDeclarator": { + "array": false, + "object": true + }, + "AssignmentExpression": { + "array": true, + "object": true + } + }, { + "enforceForRenamedProperties": false + }] + }, + "globals": { + "React": "writable" + }, + "settings": { + "react": { + "version": "17.0.1" + } + } +} diff --git a/.github/workflows/merge-request.yml b/.github/workflows/merge-request.yml new file mode 100644 index 0000000..074769e --- /dev/null +++ b/.github/workflows/merge-request.yml @@ -0,0 +1,19 @@ +name: merge-request +on: + pull_request: + branches: [ master, develop ] +jobs: + typecheck: + name: Run Prettier, Linter, and Typecheck + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + - name: Install packages + run: yarn + - name: Prettier + run: yarn format + - name: Linter + run: yarn lint + - name: Typecheck + run: yarn typecheck diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bdf9ecd --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +package-lock.json + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel + +# env files +.env diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..6ad0877 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,105 @@ +image: docker:18 + +variables: + GIT_SSL_NO_VERIFY: 1 + DOCKER_DRIVER: overlay2 + REPOSITORY_HOST: 830055101690.dkr.ecr.us-west-2.amazonaws.com + REPOSITORY_IMAGE: metal/proton-market + SERVICE_NAME: proton-market + +stages: + - test + - build + - release + +test: + image: nikolaik/python-nodejs + stage: test + only: + - merge_requests + script: + - yarn + - yarn format + - yarn typecheck + - yarn lint + - yarn build + +build development: + stage: build + only: + - develop@proton/proton-market + services: + - docker:dind + before_script: + - docker info + - apk add --no-cache curl jq python py-pip + - pip install awscli yq + script: + - export IMAGE=devel-$CI_COMMIT_SHA + - $(aws ecr get-login --no-include-email --region us-west-2) + - docker build --no-cache + --build-arg NPM_TOKEN=${NPM_TOKEN} + --build-arg NEXT_PUBLIC_BLOCK_EXPLORER=${NEXT_PUBLIC_BLOCK_EXPLORER} + --build-arg NEXT_PUBLIC_CHAIN_ENDPOINTS=${NEXT_PUBLIC_CHAIN_ENDPOINTS} + --build-arg NEXT_PUBLIC_GA_TRACKING_ID=${NEXT_PUBLIC_GA_TRACKING_ID} + --build-arg NEXT_PUBLIC_NFT_ENDPOINT=${NEXT_PUBLIC_NFT_ENDPOINT} + - docker tag $REPOSITORY_IMAGE:latest $REPOSITORY_HOST/$REPOSITORY_IMAGE:latest + - docker tag $REPOSITORY_IMAGE:latest $REPOSITORY_HOST/$REPOSITORY_IMAGE:$IMAGE + - docker push $REPOSITORY_HOST/$REPOSITORY_IMAGE:latest + - docker push $REPOSITORY_HOST/$REPOSITORY_IMAGE:$IMAGE + +build acceptance: + stage: build + only: + - /^release-.*/@proton/proton-market + variables: + DEPLOYMENT_ENVIRONMENT: "PRODUCTION" + services: + - docker:dind + before_script: + - docker info + - apk add --no-cache curl jq python py-pip + - pip install awscli yq + script: + - export IMAGE=$(cat package.json | jq .version -r) + - $(aws ecr get-login --no-include-email --region us-west-2) + - docker build --no-cache + --build-arg NPM_TOKEN=${NPM_TOKEN} + --build-arg NEXT_PUBLIC_BLOCK_EXPLORER=${NEXT_PUBLIC_BLOCK_EXPLORER} + --build-arg NEXT_PUBLIC_CHAIN_ENDPOINTS=${NEXT_PUBLIC_CHAIN_ENDPOINTS} + --build-arg NEXT_PUBLIC_GA_TRACKING_ID=${NEXT_PUBLIC_GA_TRACKING_ID} + --build-arg NEXT_PUBLIC_NFT_ENDPOINT=${NEXT_PUBLIC_NFT_ENDPOINT} + - docker tag $REPOSITORY_IMAGE:latest $REPOSITORY_HOST/$REPOSITORY_IMAGE:latest + - docker tag $REPOSITORY_IMAGE:latest $REPOSITORY_HOST/$REPOSITORY_IMAGE:$IMAGE + - docker push $REPOSITORY_HOST/$REPOSITORY_IMAGE:latest + - docker push $REPOSITORY_HOST/$REPOSITORY_IMAGE:$IMAGE + +update development helm chart: + image: 830055101690.dkr.ecr.us-west-2.amazonaws.com/metal/ci:latest + stage: release + only: + - develop@proton/proton-market + script: + - export IMAGE=devel-$CI_COMMIT_SHA + - git clone -b develop git@ci.metalpay.network:metalpay/metal-devops.git + - cd metal-devops/helm/proton + - touch values-development.yaml + - cat values-development.yaml | yq '."'$SERVICE_NAME'".image.tag="'$IMAGE'"' -y > new-values.yaml + - mv -f new-values.yaml values-development.yaml + - git add values-development.yaml + - if [[ -z $(git status -s) ]]; then echo 'Tree is clean'; else git commit -m "Update $SERVICE_NAME image tag to $IMAGE"; git push; fi + +update acceptance helm chart: + image: 830055101690.dkr.ecr.us-west-2.amazonaws.com/metal/ci:latest + stage: release + only: + - /^release-.*/@proton/proton-market + script: + - export IMAGE=$(cat package.json | jq .version -r) + - git clone -b develop git@ci.metalpay.network:metalpay/metal-devops.git + - cd metal-devops/helm/proton + - touch values-acceptance.yaml + - cat values-acceptance.yaml | yq '."'$SERVICE_NAME'".image.tag="'$IMAGE'"' -y > new-values.yaml + - mv -f new-values.yaml values-acceptance.yaml + - git add values-acceptance.yaml + - if [[ -z $(git status -s) ]]; then echo 'Tree is clean'; else git commit -m "Update $SERVICE_NAME image tag to $IMAGE"; git push; fi \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..c4ca7a1 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,5 @@ +module.exports = { + singleQuote: true, + jsxBracketSameLine: true, + semi: true, +}; diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..df8b188 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,34 @@ +FROM node:14-alpine + +ARG NPM_TOKEN +ARG NEXT_PUBLIC_GA_TRACKING_ID +ARG NEXT_PUBLIC_CHAIN_ENDPOINTS +ARG NEXT_PUBLIC_BLOCK_EXPLORER +ARG NEXT_PUBLIC_NFT_ENDPOINT +ENV NEXT_PUBLIC_CHAIN_ENDPOINTS=$NEXT_PUBLIC_CHAIN_ENDPOINTS +ENV NEXT_PUBLIC_BLOCK_EXPLORER=$NEXT_PUBLIC_BLOCK_EXPLORER +ENV NEXT_PUBLIC_GA_TRACKING_ID=$NEXT_PUBLIC_GA_TRACKING_ID +ENV NEXT_PUBLIC_NFT_ENDPOINT=$NEXT_PUBLIC_NFT_ENDPOINT + +# COPY .npmrc .npmrc +COPY package.json . +COPY components components +COPY hooks hooks +COPY pages pages +COPY public public +COPY services services +COPY styles styles +COPY types types +COPY utils utils +COPY tsconfig.json . +COPY next.config.js . +COPY next-env.d.ts . +COPY babel.config.json . +COPY .prettierrc.js . +COPY .eslintrc.json . +COPY server.js . +RUN npm i && npm run build + +EXPOSE 3000 + +CMD [ "npm", "run", "start" ] diff --git a/README.md b/README.md new file mode 100644 index 0000000..02dcb53 --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ + +# Proton Marketplace + +This application shows the basic functionality of NFTs on the Proton chain through the use of the [Proton Web SDK](https://www.npmjs.com/package/@proton/web-sdk). + +This is built off of atomicassets NFT framework. + +- [API Documentation for atomicassets (mainnet)](https://proton.api.atomicassets.io/atomicassets/docs/swagger/) +- [API Documentation for atomicmarket (mainnet)](https://proton.api.atomicassets.io/atomicmarket/docs/swagger/) +- [API Documentation for atomicassets (testnet)](https://test.proton.api.atomicassets.io/atomicassets/docs/swagger/) +- [API Documentation for atomicmarket (testnet)](https://test.proton.api.atomicassets.io/atomicmarket/docs/swagger/) + +## To build and run locally + +### Docker + +Run a docker container: + +``` +docker build nft-demo . + +docker images + +docker run -p 3000:3000 -i -d [image id] +``` + +### npm + +``` +git clone https://github.com/ProtonProtocol/nft-demo.git + +npm install + +npm run dev +``` + +## Environment + +Create a copy of `.env.template` and name it `.env.local`: + +For mainnet: +``` +NEXT_PUBLIC_CHAIN_ENDPOINTS='https://proton.eoscafeblock.com, https://proton.greymass.com' +NEXT_PUBLIC_BLOCK_EXPLORER='https://proton.bloks.io/block/' +NEXT_PUBLIC_NFT_ENDPOINT='https://proton.api.atomicassets.io' +``` + +For testnet: +``` +NEXT_PUBLIC_CHAIN_ENDPOINTS='https://testnet.protonchain.com' +NEXT_PUBLIC_BLOCK_EXPLORER='https://proton-test.bloks.io/block/' +NEXT_PUBLIC_NFT_ENDPOINT='https://test.proton.api.atomicassets.io' +``` + +## Marketplace + +The marketplace page consists of templates of a specific `collection_name`. + +### Custom flags + +- The `Template` object is extended with the following custom property: `lowestPrice`. + - `lowestPrice` (string) is determined by checking the Sales API for assets listed for sale and finding the lowest price of the assets of that particular template. + +## My NFTs + +The `My NFTs` page consists of the current user's assets. Each user is only allowed to view their own collection page in this demo. + +### Custom flags + +- The `Asset` object is extended with the following custom properties: `isForSale` and `salePrice`. + - `isForSale` (boolean) is determined by checking the Sales API for currently listed sales using the `asset_id` and `seller` (current user's `chainAccount`) + - `salePrice` (string) is determined by checking the Sales API and combining an asset's `listing_price` and `listing_symbol` diff --git a/babel.config.json b/babel.config.json new file mode 100644 index 0000000..730696f --- /dev/null +++ b/babel.config.json @@ -0,0 +1,15 @@ +{ + "presets": [ + "next/babel" + ], + "plugins": [ + [ + "styled-components", + { + "ssr": true, + "displayName": true, + "preprocess": true + } + ] + ] +} \ No newline at end of file diff --git a/components/AssetDisplay/AssetDisplay.styled.ts b/components/AssetDisplay/AssetDisplay.styled.ts new file mode 100644 index 0000000..94c4f93 --- /dev/null +++ b/components/AssetDisplay/AssetDisplay.styled.ts @@ -0,0 +1,42 @@ +import styled from 'styled-components'; +import { FadeInImageContainer } from '../../styles/FadeInImageContainer.styled'; +import { breakpoint } from '../../styles/Breakpoints'; + +export const AssetDisplayContainer = styled(FadeInImageContainer)` + width: 100%; + display: flex; + justify-content: center; + align-items: center; + max-height: 500px; + + > div { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + } + + ${breakpoint.tablet` + max-width: 294px; + `}; + + ${breakpoint.mobile` + max-width: 100%; + margin: 0px auto 32px; + `}; +`; + +export const Image = styled.img` + object-fit: contain; + max-width: 100%; + max-height: 100%; + cursor: pointer; +`; + +export const Video = styled.video` + width: 100%; + max-height: 100%; + border-radius: 16px; + outline: none; +`; diff --git a/components/AssetDisplay/AssetImage.tsx b/components/AssetDisplay/AssetImage.tsx new file mode 100644 index 0000000..271595a --- /dev/null +++ b/components/AssetDisplay/AssetImage.tsx @@ -0,0 +1,60 @@ +import { SRLWrapper, useLightbox } from 'simple-react-lightbox'; +import { Image } from './AssetDisplay.styled'; +import { IPFS_RESOLVER_IMAGE, RESIZER_IMAGE } from '../../utils/constants'; +import { useState } from 'react'; + +const lightboxOptions = { + thumbnails: { + showThumbnails: false, + }, + buttons: { + showDownloadButton: false, + showThumbnailsButton: false, + showAutoplayButton: false, + showNextButton: false, + showPrevButton: false, + }, + settings: { + overlayColor: 'rgba(0, 0, 0)', + }, +}; + +const AssetImage = ({ + image, + templateName, + lightbox, +}: { + image: string; + templateName: string; + lightbox?: boolean; +}): JSX.Element => { + const resizedSrc = `${RESIZER_IMAGE}${IPFS_RESOLVER_IMAGE}${image}`; + const highResSrc = `${IPFS_RESOLVER_IMAGE}${image}`; + + const { openLightbox } = useLightbox(); + const [src, setSrc] = useState(resizedSrc); + + const onImageError = (e) => { + e.currentTarget.onerror = null; + setSrc(highResSrc); + }; + const onImageClick = (_) => lightbox && openLightbox(); + const lightboxElements = [{ src: highResSrc, width: 'auto', height: 'auto' }]; + + return ( +
+ {templateName} + + {lightbox && ( + + )} +
+ ); +}; + +export default AssetImage; diff --git a/components/AssetDisplay/AssetModel.tsx b/components/AssetDisplay/AssetModel.tsx new file mode 100644 index 0000000..f82babe --- /dev/null +++ b/components/AssetDisplay/AssetModel.tsx @@ -0,0 +1,51 @@ +import '@google/model-viewer'; +import { IPFS_RESOLVER_VIDEO } from '../../utils/constants'; + +function parseModelIpfs(imageUrl: string) { + if (!imageUrl) { + return imageUrl; + } + + if (imageUrl.substring(0, 2) === 'Qm') { + imageUrl = `${IPFS_RESOLVER_VIDEO}${imageUrl}`; + } + + return imageUrl; +} + +const AssetModel = ({ + model, + stage, + skybox, + width, + height, +}: { + model: string; + stage: string; + skybox: string; + width?: string; + height?: string; +}): JSX.Element => { + return ( + + ); +}; + +export default AssetModel; diff --git a/components/AssetDisplay/AssetVideo.tsx b/components/AssetDisplay/AssetVideo.tsx new file mode 100644 index 0000000..4ec07c9 --- /dev/null +++ b/components/AssetDisplay/AssetVideo.tsx @@ -0,0 +1,16 @@ +import { Video } from './AssetDisplay.styled'; +import { IPFS_RESOLVER_VIDEO } from '../../utils/constants'; + +const AssetVideo = ({ video }: { video: string }): JSX.Element => ( +