diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 1f16343693..aad094128a 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -4,16 +4,12 @@ closes # Submission checklist: -> Remove anything below that is not applicable + -- [x] Functionality -- - [x] Feature works as intended after change -- - [x] Applicable dependancies have been deployed +#### Layout +- [] Change looks good in the desktop web ui +- - [] Change looks good in the mobile web ui -- [x] Layout -- - [x] Change looks good in the desktop web ui -- - [x] Change looks good in the mobile web ui - -- [x] Theme -- - [x] Components / elements inspected in light mode -- - [x] Components / elements inspected in dark mode \ No newline at end of file +#### Theme +- [] Components / elements inspected in light mode +- [] Components / elements inspected in dark mode diff --git a/.github/workflows/lingui-extract-gaming.yml b/.github/workflows/lingui-extract-gaming.yml deleted file mode 100644 index aca20cda66..0000000000 --- a/.github/workflows/lingui-extract-gaming.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Lingui extract - Gaming -on: - pull_request: - branches: - - "dev" - paths: - - "packages/gaming-ui/**/*" -jobs: - # extract any new translatable string - # and commit if there are new ones - # and if the user submitting the PR isn't weblate - extract: - name: lingui-extract - runs-on: ubuntu-latest - if: ${{ github.actor != 'weblate' }} - steps: - - uses: actions/checkout@v2 - with: - ref: ${{ github.event.pull_request.head.ref }} - ssh-key: ${{ secrets.LINGUI_GH_ACTION_COMMIT_KEY }} - - name: set user - run: | - git config --global user.name 'GitHub Actions' - git config --global user.email 'actions@github.com' - - # use node module caching - - uses: actions/cache@v2 - with: - path: '**/node_modules' - key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - - - name: install packages - run: yarn install --immutable - - - name: lingui-extract and commit - if: ${{ github.actor != 'weblate' }} - run: | - (cd packages/gaming-ui && yarn extract --clean) - git add packages/gaming-ui/src/locales/* - if git commit -m "lingui extract"; then git push; else echo 'exiting successfully without commit'; fi diff --git a/README.md b/README.md index b9736e21ad..18ec6322b1 100644 --- a/README.md +++ b/README.md @@ -20,10 +20,6 @@ Theme context and other utilities for generating and using the theming capabilit The UI for Chainsafe Files -#### **`packages/gaming-ui`** - -The UI for Chainsafe Gaming - #### **`packages/storage-ui`** The UI for Chainsafe Storage diff --git a/package.json b/package.json index a62f07950c..6696a69830 100644 --- a/package.json +++ b/package.json @@ -38,9 +38,6 @@ "build:files-ui": "yarn wsrun -p files-ui -c build", "release:files-ui": "yarn wsrun -p files-ui -c release", "start:files-ui": "yarn wsrun -p files-ui -c start", - "build:gaming-ui": "yarn wsrun -p gaming-ui -c build", - "release:gaming-ui": "yarn wsrun -p gaming-ui -c release", - "start:gaming-ui": "yarn wsrun -p gaming-ui -c start", "build:storage-ui": "yarn wsrun -p storage-ui -c build", "release:storage-ui": "yarn wsrun -p storage-ui -c release", "start:storage-ui": "yarn wsrun -p storage-ui -c start", diff --git a/packages/common-components/package.json b/packages/common-components/package.json index a694ce3a86..db8116bd7a 100644 --- a/packages/common-components/package.json +++ b/packages/common-components/package.json @@ -10,7 +10,7 @@ }, "scripts": { "storybook": "start-storybook -p 6006", - "build:storybook": "build-storybook", + "build:storybook": "(export NODE_OPTIONS=--openssl-legacy-provider; build-storybook)", "build": "rollup -c", "start": "rollup -c -w", "lint": "eslint './{src, cypress}/**/*.{js,jsx,ts,tsx}'" diff --git a/packages/common-components/src/Button/Button.tsx b/packages/common-components/src/Button/Button.tsx index 05ae395162..01b7a8c37a 100644 --- a/packages/common-components/src/Button/Button.tsx +++ b/packages/common-components/src/Button/Button.tsx @@ -361,7 +361,7 @@ const Button: React.FC = ({ {loading && ( <> diff --git a/packages/common-components/src/Icons/icons/Sort.icon.tsx b/packages/common-components/src/Icons/icons/Sort.icon.tsx new file mode 100644 index 0000000000..680e24b8df --- /dev/null +++ b/packages/common-components/src/Icons/icons/Sort.icon.tsx @@ -0,0 +1,7 @@ +import * as React from "react" +import createSvgIcon from "../createSvgIcon" +import { ReactComponent as SortSvg } from "../svgs/sort.svg" + +export { SortSvg } + +export default createSvgIcon() diff --git a/packages/common-components/src/Icons/index.ts b/packages/common-components/src/Icons/index.ts index 410cd3113b..ee5a1f9dc8 100644 --- a/packages/common-components/src/Icons/index.ts +++ b/packages/common-components/src/Icons/index.ts @@ -67,6 +67,7 @@ export { default as SearchIcon, SearchSvg } from "./icons/Search.icon" export { default as SettingIcon, SettingSvg } from "./icons/Setting.icon" export { default as ShareAltIcon, ShareAltSvg } from "./icons/ShareAlt.icon" export { default as StarIcon, StarSvg } from "./icons/Star.icon" +export { default as SortIcon, SortSvg } from "./icons/Sort.icon" export { default as SunIcon, SunSvg } from "./icons/Sun.icon" export { default as SubscriptionPlanIcon, SubscriptionSvg } from "./icons/SubscriptionPlan.icon" export { default as TableIcon, TableSvg } from "./icons/Table.icon" diff --git a/packages/common-components/src/Icons/svgs/sort.svg b/packages/common-components/src/Icons/svgs/sort.svg new file mode 100644 index 0000000000..00c6c7e54e --- /dev/null +++ b/packages/common-components/src/Icons/svgs/sort.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/common-components/src/Spinner/Loading.tsx b/packages/common-components/src/Spinner/Loading.tsx index 96e5c97287..e22b4e53f2 100644 --- a/packages/common-components/src/Spinner/Loading.tsx +++ b/packages/common-components/src/Spinner/Loading.tsx @@ -1,8 +1,8 @@ -import React from "react" +import React, { useMemo } from "react" import { ITheme, useTheme } from "@chainsafe/common-theme" export interface ILoadingProps { - type?: "inherit" | "primary" | "dark" | "light" + type?: "initial" | "primary" | "dark" | "light" size?: number className?: string } @@ -13,6 +13,42 @@ const Loading: React.FC = ({ className }) => { const theme: ITheme = useTheme() + + const uniqueKey = `${Math.random()}-${Math.random()}` + + const { + start, + end + } = useMemo(() => { + switch (type) { + case "primary": + return { + start: theme.palette.primary.main, + end: "transparent" + } + case "light": + return { + start: theme.palette.common.white.main, + end: "transparent" + } + case "dark": + return { + start: theme.palette.common.black.main, + end: "transparent" + } + case "initial": + return { + start: "#FFFFFF", + end: "transparent" + } + default: + return { + start: "#FFFFFF", + end: "transparent" + } + } + }, [type, theme.palette]) + return ( = ({ > = ({ > @@ -50,7 +78,7 @@ const Loading: React.FC = ({ cx="50" cy="50" r="47" - stroke="url(#gradient)" + stroke={`url(#gradient-${uniqueKey})`} strokeWidth="6" fill="none" transform="rotate(90 50 50)" diff --git a/packages/files-ui/cypress/support/commands.ts b/packages/files-ui/cypress/support/commands.ts index baf73539aa..693b9f9ed8 100644 --- a/packages/files-ui/cypress/support/commands.ts +++ b/packages/files-ui/cypress/support/commands.ts @@ -26,17 +26,16 @@ // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) import { authenticationPage } from "./page-objects/authenticationPage" -import { apiTestHelper } from "./utils/apiTestHelper" +import { apiTestHelper, ClearBucketType } from "./utils/apiTestHelper" import { ethers, Wallet } from "ethers" import { homePage } from "./page-objects/homePage" import { testPrivateKey, testAccountPassword, localHost } from "../fixtures/loginData" import { CustomizedBridge } from "./utils/CustomBridge" import "cypress-file-upload" import "cypress-pipe" -import { BucketType } from "@chainsafe/files-api-client" import { navigationMenu } from "./page-objects/navigationMenu" -Cypress.Commands.add("clearBucket", (bucketType: BucketType) => { +Cypress.Commands.add("clearBucket", (bucketType: ClearBucketType) => { apiTestHelper.clearBucket(bucketType) }) @@ -47,6 +46,7 @@ export interface Web3LoginOptions { clearCSFBucket?: boolean clearTrashBucket?: boolean deleteShareBucket?: boolean + withNewUser?: boolean } Cypress.Commands.add( @@ -56,7 +56,8 @@ Cypress.Commands.add( url = localHost, clearCSFBucket = false, clearTrashBucket = false, - deleteShareBucket = false + deleteShareBucket = false, + withNewUser = true }: Web3LoginOptions = {}) => { cy.on("window:before:load", (win) => { @@ -64,32 +65,49 @@ Cypress.Commands.add( "https://rinkeby.infura.io/v3/4bf032f2d38a4ed6bb975b80d6340847", 4 ) - const signer = new Wallet(testPrivateKey, provider) + const signer = withNewUser + ? Wallet.createRandom() + : new Wallet(testPrivateKey, provider) // inject ethereum object in the global window Object.defineProperty(win, "ethereum", { - get: () => new CustomizedBridge(signer as any, provider as any) + get: () => new CustomizedBridge(signer as any, signer.address, provider as any) }) }) - // with nothing in localstorage (and in session storage) - // the whole login flow should kick in - cy.session("web3login", () => { - cy.visit(url) - authenticationPage.web3Button().click() - authenticationPage.showMoreButton().click() - authenticationPage.detectedWallet().click() - authenticationPage.web3SignInButton().safeClick() - authenticationPage.loginPasswordButton().click() - authenticationPage.loginPasswordInput().type(`${testAccountPassword}{enter}`) - - if (saveBrowser) { - // this is taking forever for test accounts - authenticationPage.saveBrowserButton().click() - } else { - authenticationPage.doNotSaveBrowserButton().click() - } - homePage.appHeaderLabel().should("be.visible") - }) + if (withNewUser){ + cy.session("web3loginNewUser", () => { + cy.visit(url) + authenticationPage.web3Button().click() + authenticationPage.showMoreButton().click() + authenticationPage.detectedWallet().click() + authenticationPage.web3SignInButton().safeClick() + authenticationPage.signInExplainerContinueButton().safeClick() + // we are using the testAccount password here, but we could input anything + authenticationPage.signInSetupPasswordInput().type(`${testAccountPassword}`) + authenticationPage.signInSetupPasswordVerificationInput().type(`${testAccountPassword}{enter}`) + + homePage.appHeaderLabel().should("be.visible") + }) + } else { + cy.session("web3loginTestUser", () => { + cy.visit(url) + authenticationPage.web3Button().click() + authenticationPage.showMoreButton().click() + authenticationPage.detectedWallet().click() + authenticationPage.web3SignInButton().safeClick() + authenticationPage.loginPasswordButton().click() + authenticationPage.loginPasswordInput().type(`${testAccountPassword}{enter}`) + + if (saveBrowser) { + // this is taking forever for test accounts + authenticationPage.saveBrowserButton().click() + } else { + authenticationPage.doNotSaveBrowserButton().click() + } + homePage.appHeaderLabel().should("be.visible") + }) + } + cy.visit(url) homePage.appHeaderLabel().should("be.visible") @@ -115,7 +133,7 @@ Cypress.Commands.add( } ) -Cypress.Commands.add("safeClick", { prevSubject: "element" }, $element => { +Cypress.Commands.add("safeClick", { prevSubject: "element" }, ($element?: JQuery) => { const click = ($el: JQuery) => $el.trigger("click") return cy .wrap($element) @@ -137,9 +155,10 @@ declare global { * @param {Boolean} options.clearCSFBucket - (default: false) - whether any file in the csf bucket should be deleted. * @param {Boolean} options.clearTrashBucket - (default: false) - whether any file in the trash bucket should be deleted. * @param {Boolean} options.deleteShareBucket - (default: false) - whether any shared bucket should be deleted. + * @param {Boolean} options.withNewUser - (default: true) - whether to create a new user for this session. * @example cy.web3Login({saveBrowser: true, url: 'http://localhost:8080'}) */ - web3Login: (options?: Web3LoginOptions) => Chainable + web3Login: (options?: Web3LoginOptions) => void /** * Use this when encountering race condition issues resulting in @@ -153,8 +172,14 @@ declare global { * https://github.com/cypress-io/cypress/issues/7306 * */ - safeClick: () => Chainable + safeClick: ($element?: JQuery) => Chainable + /** + * Clear a bucket. + * @param {BucketType} - what bucket type to clear for this user. + * @example cy.clearBucket("csf") + */ + clearBucket: (bucketType: ClearBucketType) => void } } } diff --git a/packages/files-ui/cypress/support/index.ts b/packages/files-ui/cypress/support/index.ts index f0febdb6c2..80de34037f 100644 --- a/packages/files-ui/cypress/support/index.ts +++ b/packages/files-ui/cypress/support/index.ts @@ -19,13 +19,9 @@ import "./commands" // the following gets rid of the exception "ResizeObserver loop limit exceeded" // which someone on the internet says we can safely ignore // source https://stackoverflow.com/questions/49384120/resizeobserver-loop-limit-exceeded -Cypress.on("uncaught:exception", (err) => { +Cypress.on("uncaught:exception", () => { /* returning false here prevents Cypress from failing the test */ - if (err.message.includes("ResizeObserver loop limit exceeded")) { - // returning false here prevents Cypress from - // failing the test - return false - } + return false }) // Hide fetch/XHR requests diff --git a/packages/files-ui/cypress/support/page-objects/authenticationPage.ts b/packages/files-ui/cypress/support/page-objects/authenticationPage.ts index 2c408c7cd3..5d8e68b258 100644 --- a/packages/files-ui/cypress/support/page-objects/authenticationPage.ts +++ b/packages/files-ui/cypress/support/page-objects/authenticationPage.ts @@ -12,6 +12,10 @@ export const authenticationPage = { // sign in section elements loginPasswordButton: () => cy.get("[data-cy=login-password-button]", { timeout: 20000 }), loginPasswordInput: () => cy.get("[data-cy=login-password-input]"), + signInExplainerContinueButton: () => cy.get("[data-cy=button-sign-in-explainer-continue]", { timeout: 20000 }), + signInSetupPasswordInput: () => cy.get("[data-cy=input-sign-in-password]"), + signInSetupPasswordVerificationInput: () => cy.get("[data-cy=input-sign-in-password-verification]"), + signInSetupPasswordSubmitButton: () => cy.get("[data-cy=button-sign-in-password]"), // save browser section elements saveBrowserButton: () => cy.get("[data-cy=save-browser-button]"), diff --git a/packages/files-ui/cypress/support/page-objects/modals/createSharedFolderModal.ts b/packages/files-ui/cypress/support/page-objects/modals/createSharedFolderModal.ts index 60659ab35d..f709cdfc09 100644 --- a/packages/files-ui/cypress/support/page-objects/modals/createSharedFolderModal.ts +++ b/packages/files-ui/cypress/support/page-objects/modals/createSharedFolderModal.ts @@ -7,5 +7,17 @@ export const createEditSharedFolderModal = { tagViewPermissionUser: () => cy.get("[data-cy=tag-view-permission-user]"), tagEditPermissionUser: () => cy.get("[data-cy=tag-edit-permission-user]"), updateButton: () => cy.get("[data-cy=button-update-shared-folder]", { timeout: 10000 }), - viewOnlyPermissionInput: () => cy.get("[data-cy=input-view-permission") -} \ No newline at end of file + viewOnlyPermissionInput: () => cy.get("[data-cy=input-view-permission"), + + // link sharing related elements + shareLink: () => cy.get("[data-cy=link-share]"), + activeShareLink: () => cy.get("[data-cy=link-active-share]"), + labelPermissionType: () => cy.get("[data-cy=label-permission-type]"), + copyLinkButton: () => cy.get("[data-cy=button-copy-link]"), + linkKebabMenu: () => cy.get("[data-testid=menu-title-link-kebab]"), + deleteLinkMenuOption: () => cy.get("[data-cy=menu-delete-active-link]"), + permissionTypeDropdown: () => cy.get("[data-testid=dropdown-title-permission]"), + viewOnlyOption: () => cy.get("[data-cy=menu-read]"), + canEditOption: () => cy.get("[data-cy=menu-write]"), + createLinkButton: () => cy.get("[data-cy=button-create-link]") +} diff --git a/packages/files-ui/cypress/support/page-objects/sharedPage.ts b/packages/files-ui/cypress/support/page-objects/sharedPage.ts index 072482022d..2c25afc7a4 100644 --- a/packages/files-ui/cypress/support/page-objects/sharedPage.ts +++ b/packages/files-ui/cypress/support/page-objects/sharedPage.ts @@ -1,5 +1,7 @@ +import { sharedFolderName } from "../../fixtures/filesTestData" import { basePage } from "./basePage" import { fileBrowser } from "./fileBrowser" +import { createEditSharedFolderModal } from "./modals/createSharedFolderModal" export const sharedPage = { ...basePage, @@ -15,5 +17,15 @@ export const sharedPage = { leaveMenuOption: () => cy.get("[data-cy=menu-leave]"), manageAccessMenuOption: () => cy.get("[data-cy=menu-manage-access]"), renameMenuOption: () => cy.get("[data-cy=menu-rename]"), - uploadButton: () => cy.get("[data-cy=button-upload-file]") + uploadButton: () => cy.get("[data-cy=button-upload-file]"), + + // helpers and convenience functions + createSharedFolder() { + sharedPage.createSharedFolderButton().click() + createEditSharedFolderModal.body().should("be.visible") + createEditSharedFolderModal.folderNameInput().type(sharedFolderName) + createEditSharedFolderModal.createButton().safeClick() + createEditSharedFolderModal.body().should("not.exist") + sharedPage.sharedFolderItemRow().should("have.length", 1) + } } diff --git a/packages/files-ui/cypress/support/utils/CustomBridge.ts b/packages/files-ui/cypress/support/utils/CustomBridge.ts index 4924ecbbff..ff1fd4c19c 100644 --- a/packages/files-ui/cypress/support/utils/CustomBridge.ts +++ b/packages/files-ui/cypress/support/utils/CustomBridge.ts @@ -1,8 +1,15 @@ import { Eip1193Bridge } from "@ethersproject/experimental/lib/eip1193-bridge" +import { ethers } from "ethers" import { toUtf8String } from "ethers/lib/utils" -import { testAddress } from "../../fixtures/loginData" export class CustomizedBridge extends Eip1193Bridge { + expectedAddress = "" + + constructor(signer: ethers.Signer, address: string, provider?: ethers.providers.Provider) { + super(signer as any, provider as any) + this.expectedAddress = address + } + async sendAsync(...args: Array) { return this.send(...args) } @@ -30,17 +37,17 @@ export class CustomizedBridge extends Eip1193Bridge { const message = params[0] if ( - (addr as string).toLowerCase() !== testAddress.toLowerCase() + (addr as string).toLowerCase() !== this.expectedAddress.toLowerCase() ) { return Promise.reject( - `Wrong address, expected ${testAddress}, but got ${addr}` + `Wrong address, expected ${this.expectedAddress}, but got ${addr}` ) } try { const sig = await this.signer.signMessage(toUtf8String(message)) return sig - } catch (e) { + } catch (e: any) { return Promise.reject( `Error in CustomizedBridge for personal_sign: ${e.message}` ) @@ -49,9 +56,9 @@ export class CustomizedBridge extends Eip1193Bridge { if (method === "eth_requestAccounts" || method === "eth_accounts") { if (isCallbackForm) { - callback({ result: [testAddress] }) + callback({ result: [this.expectedAddress] }) } else { - return Promise.resolve([testAddress]) + return Promise.resolve([this.expectedAddress]) } } diff --git a/packages/files-ui/cypress/support/utils/apiTestHelper.ts b/packages/files-ui/cypress/support/utils/apiTestHelper.ts index 50cd2e053a..4be4ea8ab8 100644 --- a/packages/files-ui/cypress/support/utils/apiTestHelper.ts +++ b/packages/files-ui/cypress/support/utils/apiTestHelper.ts @@ -7,6 +7,7 @@ import { homePage } from "../page-objects/homePage" const API_BASE_USE = "https://stage.imploy.site/api/v1" const REFRESH_TOKEN_KEY = "csf.refreshToken" +export type ClearBucketType = Exclude const getApiClient = () => { // Disable the internal Axios JSON deserialization as this is handled by the client const axiosInstance = axios.create({ transformResponse: [] }) @@ -34,7 +35,7 @@ export const apiTestHelper = { }) }) }, - clearBucket(bucketType: BucketType) { + clearBucket(bucketType: ClearBucketType) { const apiClient = getApiClient() return new Cypress.Promise(async (resolve) => { diff --git a/packages/files-ui/cypress/tests/link-sharing-spec.ts b/packages/files-ui/cypress/tests/link-sharing-spec.ts new file mode 100644 index 0000000000..ebf27609a6 --- /dev/null +++ b/packages/files-ui/cypress/tests/link-sharing-spec.ts @@ -0,0 +1,77 @@ +import { createEditSharedFolderModal } from "../support/page-objects/modals/createSharedFolderModal" +import { navigationMenu } from "../support/page-objects/navigationMenu" +import { sharingExplainerKey } from "../fixtures/filesTestData" +import { sharedPage } from "../support/page-objects/sharedPage" + +describe("Link Sharing", () => { + + context("desktop", () => { + + it("can create, copy and remove links to shared folders", () => { + // intercept and stub the response to ensure the explainer is not displayed + cy.intercept("GET", "**/user/store", { + body: { [sharingExplainerKey]: "true" } + }) + + cy.web3Login({ deleteShareBucket: true }) + + // create a shared folder + navigationMenu.sharedNavButton().click() + sharedPage.createSharedFolder() + sharedPage.fileItemKebabButton() + .should("be.visible") + .click() + sharedPage.manageAccessMenuOption().click() + createEditSharedFolderModal.body().should("be.visible") + + // ensure default state of displayed elements is correct + createEditSharedFolderModal.activeShareLink().should("not.exist") + createEditSharedFolderModal.labelPermissionType().should("not.exist") + createEditSharedFolderModal.copyLinkButton().should("not.exist") + createEditSharedFolderModal.linkKebabMenu().should("not.exist") + createEditSharedFolderModal.permissionTypeDropdown().should("be.visible") + createEditSharedFolderModal.createLinkButton().should("be.visible") + + // ensure "view-only" and "can-edit" options are present + createEditSharedFolderModal.permissionTypeDropdown().click() + createEditSharedFolderModal.viewOnlyOption() + .scrollIntoView() + .should("be.visible") + createEditSharedFolderModal.canEditOption() + .scrollIntoView() + .should("be.visible") + + // create a "view-only" link + createEditSharedFolderModal.viewOnlyOption().click() + createEditSharedFolderModal.createLinkButton().click() + createEditSharedFolderModal.activeShareLink().should("have.length", 1) + createEditSharedFolderModal.labelPermissionType().should("have.length", 1) + createEditSharedFolderModal.copyLinkButton().should("have.length", 1) + + // ensure only the can-edit option is present if a "view-only" link exists + createEditSharedFolderModal.permissionTypeDropdown().click() + createEditSharedFolderModal.viewOnlyOption().should("not.exist") + createEditSharedFolderModal.canEditOption() + .scrollIntoView() + .should("be.visible") + + // create a "can-edit" link + createEditSharedFolderModal.canEditOption().click() + createEditSharedFolderModal.createLinkButton().click() + createEditSharedFolderModal.activeShareLink().should("have.length", 2) + createEditSharedFolderModal.labelPermissionType().should("have.length", 2) + createEditSharedFolderModal.copyLinkButton().should("have.length", 2) + + // ensure create button and drop down are not shown if links exist + createEditSharedFolderModal.permissionTypeDropdown().should("not.exist") + createEditSharedFolderModal.createLinkButton().should("not.exist") + + // delete one of the links + createEditSharedFolderModal.linkKebabMenu().first().click() + createEditSharedFolderModal.deleteLinkMenuOption().first() + .scrollIntoView() + .click() + createEditSharedFolderModal.activeShareLink().should("have.length", 1) + }) + }) +}) diff --git a/packages/files-ui/cypress/tests/survey-banner-spec.ts b/packages/files-ui/cypress/tests/survey-banner-spec.ts index fb66f27708..eb9c08a074 100644 --- a/packages/files-ui/cypress/tests/survey-banner-spec.ts +++ b/packages/files-ui/cypress/tests/survey-banner-spec.ts @@ -20,7 +20,7 @@ describe("Survey Banner", () => { body: { [dismissedSurveyKey]: "false" } }) - cy.web3Login() + cy.web3Login({ withNewUser: false }) homePage.surveyBanner().should("be.visible") // set up a spy for the POST response @@ -42,7 +42,7 @@ describe("Survey Banner", () => { body: { [dismissedSurveyKey]: "true" } }) - cy.web3Login() + cy.web3Login({ withNewUser: false }) homePage.surveyBanner().should("not.exist") }) @@ -51,7 +51,7 @@ describe("Survey Banner", () => { body: {} }) - cy.web3Login() + cy.web3Login({ withNewUser: false }) homePage.surveyBanner().should("be.visible") }) @@ -67,7 +67,12 @@ describe("Survey Banner", () => { body: {} }) - cy.web3Login() + cy.web3Login({ withNewUser: false }) + homePage.surveyBanner().should("not.exist") + }) + + it("A new user should not see the banner", () => { + cy.web3Login({ withNewUser: true }) homePage.surveyBanner().should("not.exist") }) }) diff --git a/packages/files-ui/package.json b/packages/files-ui/package.json index e658ecb5a2..0cd6d2460b 100644 --- a/packages/files-ui/package.json +++ b/packages/files-ui/package.json @@ -77,7 +77,7 @@ "@types/yup": "^0.29.9", "@types/zxcvbn": "^4.4.0", "babel-plugin-macros": "^2.8.0", - "cypress": "^9.0", + "cypress": "^9.1.0", "cypress-file-upload": "^5.0.8", "cypress-pipe": "^2.0.0" }, diff --git a/packages/files-ui/src/Components/Elements/MnemonicForm.tsx b/packages/files-ui/src/Components/Elements/MnemonicForm.tsx index 067befa0da..c1352d7159 100644 --- a/packages/files-ui/src/Components/Elements/MnemonicForm.tsx +++ b/packages/files-ui/src/Components/Elements/MnemonicForm.tsx @@ -137,7 +137,7 @@ const MnemonicForm = ({ buttonLabel, onComplete }: Props) => { className={classes.loader} > diff --git a/packages/files-ui/src/Components/Elements/PasswordForm.tsx b/packages/files-ui/src/Components/Elements/PasswordForm.tsx index e99eeea19a..8652444779 100644 --- a/packages/files-ui/src/Components/Elements/PasswordForm.tsx +++ b/packages/files-ui/src/Components/Elements/PasswordForm.tsx @@ -104,6 +104,7 @@ const PasswordForm = ({ buttonLabel, setPassword }: Props) => { label={t`Password:`} labelClassName={classes.inputLabel} captionMessage={} + data-cy="input-sign-in-password" /> { name="confirmPassword" label={t`Confirm Password:`} labelClassName={classes.inputLabel} + data-cy="input-sign-in-password-verification" /> diff --git a/packages/files-ui/src/Components/Elements/ShareTransferRequestModal.tsx b/packages/files-ui/src/Components/Elements/ShareTransferRequestModal.tsx index d988592972..321d3d6d81 100644 --- a/packages/files-ui/src/Components/Elements/ShareTransferRequestModal.tsx +++ b/packages/files-ui/src/Components/Elements/ShareTransferRequestModal.tsx @@ -123,7 +123,7 @@ const ShareTransferRequestModal = ({ requests }: Props) => { requests.length > 1 && (isClearing ? : {
diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/LinkList.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/LinkList.tsx index 40c13a1822..bbcd450db9 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/LinkList.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/LinkList.tsx @@ -226,7 +226,7 @@ const LinkList = ({ bucketId, bucketEncryptionKey }: Props) => { className={classes.loader} > @@ -269,6 +269,7 @@ const LinkList = ({ bucketId, bucketEncryptionKey }: Props) => { variant="secondary" disabled={isLoadingCreation} loading={isLoadingCreation} + data-cy="button-create-link" > Create link diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx index adc8cca9f3..12fbdfa5fb 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx @@ -212,7 +212,7 @@ const SharingLink = ({ nonce, bucketEncryptionKey, refreshNonces }: Props) => { className={classes.loader} > @@ -232,12 +232,16 @@ const SharingLink = ({ nonce, bucketEncryptionKey, refreshNonces }: Props) => {
{link}
-
+
{translatedPermission(nonce.permission)} @@ -245,18 +249,19 @@ const SharingLink = ({ nonce, bucketEncryptionKey, refreshNonces }: Props) => {
} options={[{ contents: ( <> - + Delete diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/ReportFileModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/ReportFileModal.tsx index 86548de9c0..a0d8001258 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/ReportFileModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/ReportFileModal.tsx @@ -276,7 +276,7 @@ const ReportFileModal = ({ filePath, close }: IReportFileModalProps) => {
diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx index e1faa549b4..5e75ae9bad 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx @@ -409,4 +409,4 @@ const ShareModal = ({ onClose, fileSystemItems }: IShareFileProps) => { ) } -export default ShareModal \ No newline at end of file +export default ShareModal diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFileBrowser.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFileBrowser.tsx index bc45edc992..356c4e0781 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFileBrowser.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFileBrowser.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useMemo, useState } from "react" -import { useToasts, useHistory, useLocation, Crumb } from "@chainsafe/common-components" +import { useToasts, useHistory, useLocation, Crumb, Typography, ExclamationCircleIcon, Loading } from "@chainsafe/common-components" import { getArrayOfPaths, getURISafePathFromArray, @@ -11,31 +11,60 @@ import { } from "../../../Utils/pathUtils" import { IBulkOperations, IFilesTableBrowserProps } from "./types" import { CONTENT_TYPES } from "../../../Utils/Constants" -import { t } from "@lingui/macro" +import { t, Trans } from "@lingui/macro" import { ROUTE_LINKS } from "../../FilesRoutes" import { FileBrowserContext } from "../../../Contexts/FileBrowserContext" import { parseFileContentResponse } from "../../../Utils/Helpers" -import { BucketPermission, FileSystemItem, useFiles } from "../../../Contexts/FilesContext" +import { BucketKeyPermission, BucketPermission, FileSystemItem, useFiles } from "../../../Contexts/FilesContext" import { useFilesApi } from "../../../Contexts/FilesApiContext" import { useUser } from "../../../Contexts/UserContext" import DragAndDrop from "../../../Contexts/DnDContext" import FilesList from "./views/FilesList" import getFilesFromDataTransferItems from "../../../Utils/getFilesFromDataTransferItems" +import { createStyles, makeStyles } from "@chainsafe/common-theme" +import { CSFTheme } from "../../../Themes/types" + +const useStyles = makeStyles(({ constants, palette }: CSFTheme) => + createStyles({ + messageWrapper: { + display: "flex", + flexDirection: "column", + justifyContent: "center", + alignItems: "center" + }, + icon : { + display: "flex", + alignItems: "center", + fontSize: constants.generalUnit * 6, + "& svg": { + fill: palette.additional["gray"][7] + } + } + })) const SharedFileBrowser = () => { const { downloadFile, uploadFiles, buckets, getStorageSummary, refreshBuckets } = useFiles() const { filesApiClient, accountRestricted } = useFilesApi() + const classes = useStyles() const { addToast } = useToasts() const [loadingCurrentPath, setLoadingCurrentPath] = useState(false) const [pathContents, setPathContents] = useState([]) const { redirect } = useHistory() const { pathname } = useLocation() + const [bucket, setBucket] = useState() + const [isBucketLoaded, setIsBucketLoaded] = useState(false) const bucketId = useMemo(() => pathname.split("/")[2] , [pathname]) - const bucket = useMemo(() => buckets.find(b => b.id === bucketId), [buckets, bucketId]) + useEffect(() => { + if (!buckets.length || !bucketId) return + + const newBuck = buckets.find(b => b.id === bucketId) + setBucket(newBuck) + setIsBucketLoaded(true) + }, [bucketId, buckets]) const currentPath = useMemo(() => { return extractSharedFileBrowserPathFromURL(pathname, ROUTE_LINKS.SharedFolderExplorer(bucketId, "")) @@ -240,6 +269,32 @@ const SharedFileBrowser = () => { } }, [access]) + if (!isBucketLoaded) { + return ( +
+ +
+ ) + } + + // The bucket is loaded, and it is still undefined + if (!bucket) { + return ( +
+ + + You do not have access to this shared folder. + +
+ ) + } + return ( { > - Create a Shared Folder + Create
diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx index 8cdec63e6c..223b9f5eed 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx @@ -21,7 +21,9 @@ import { GridIcon, TableIcon, UploadSvg, - PlusCircleSvg + PlusCircleSvg, + SortIcon, + CheckIcon } from "@chainsafe/common-components" import { useState } from "react" import { useMemo } from "react" @@ -53,11 +55,12 @@ import { useFilesApi } from "../../../../Contexts/FilesApiContext" import RestrictedModeBanner from "../../../Elements/RestrictedModeBanner" import clsx from "clsx" import EmptySvg from "../../../../Media/Empty.svg" +import { ListItemIcon, ListItemText } from "@material-ui/core" -const baseOperations: FileOperation[] = ["download", "info", "preview", "share"] +const baseOperations: FileOperation[] = ["download", "info", "preview", "share"] const readerOperations: FileOperation[] = [...baseOperations, "report"] const ownerOperations: FileOperation[] = [...baseOperations, "delete", "move", "rename", "recover"] -const csfOperations: FileOperation[] = [...ownerOperations, "share"] +const csfOperations: FileOperation[] = [...ownerOperations, "share"] const writerOperations: FileOperation[] = [...ownerOperations, "report"] interface IStyleProps { @@ -291,7 +294,7 @@ const useStyles = makeStyles( display: "flex", justifyContent: "flex-end" }, - focusVisible:{ + focusVisible: { backgroundColor: "transparent !important" }, menuIcon: { @@ -372,7 +375,7 @@ const FilesList = ({ isShared = false }: Props) => { let temp = [] switch (column) { - // defaults to name sorting + // defaults to name sorting default: { temp = sourceFiles.sort((a, b) => { return a.name.localeCompare(b.name, selectedLocale, { @@ -424,6 +427,14 @@ const FilesList = ({ isShared = false }: Props) => { } } + const toggleSortDirection = () => { + if (direction === "ascend") { + setDirection("descend") + } else { + setDirection("ascend") + } + } + // Previews const setNextPreview = () => { if ( @@ -517,7 +528,7 @@ const FilesList = ({ isShared = false }: Props) => { if (!!permission && isShared) { - switch(permission) { + switch (permission) { case "owner": fileOperations = ownerOperations break @@ -716,12 +727,13 @@ const FilesList = ({ isShared = false }: Props) => { variant="h1" component="h1" data-cy="files-app-header" + className={classes.fileNameHeader} > {heading} {isShared && bucket && (
- +
)}
@@ -745,10 +757,9 @@ const FilesList = ({ isShared = false }: Props) => { onClick={() => setCreateFolderModalOpen(true)} variant="outline" size="large" - disabled={accountRestricted} > - + New folder @@ -760,7 +771,7 @@ const FilesList = ({ isShared = false }: Props) => { disabled={accountRestricted} > - + Upload @@ -783,7 +794,7 @@ const FilesList = ({ isShared = false }: Props) => { } + icon={} options={mobileMenuItems} style={{ focusVisible: classes.focusVisible }} /> @@ -792,8 +803,8 @@ const FilesList = ({ isShared = false }: Props) => { )}
- { withSurvey && !isShared && isSurveyBannerVisible - ? + {withSurvey && !isShared && isSurveyBannerVisible + ? : } @@ -899,7 +910,7 @@ const FilesList = ({ isShared = false }: Props) => { className={clsx(loadingCurrentPath && classes.fadeOutLoading)} testId="home" > - {desktop && ( + {desktop ? ( @@ -945,6 +956,69 @@ const FilesList = ({ isShared = false }: Props) => { {/* Menu */} + ) : ( + + + + {/* Checkbox */} + + + {t`Name`} + + + } + options={[{ + contents: ( + + Sort By: + + ) + }, { + contents: ( + <> + {column === "name" && + + } + + Name + + + ), + onClick: () => setColumn("name") + }, { + contents: ( + <> + {column === "date_uploaded" && } + + Date Uploaded + + + ), + onClick: () => setColumn("date_uploaded") + }, { + contents: ( + <> + {column === "size" && } + + Size + + + ), + onClick: () => setColumn("size") + }]} + style={{ focusVisible: classes.focusVisible }} + /> + + + )} {items.map((file, index) => ( @@ -981,7 +1055,8 @@ const FilesList = ({ isShared = false }: Props) => { browserView='table' reportFile={(fileInfoPath: string) => { setFilePath(fileInfoPath) - setIsReportFileModalOpen(true)} + setIsReportFileModalOpen(true) + } } showFileInfo={(fileInfoPath: string) => { setFilePath(fileInfoPath) @@ -1038,7 +1113,8 @@ const FilesList = ({ isShared = false }: Props) => { browserView="grid" reportFile={(fileInfoPath: string) => { setFilePath(fileInfoPath) - setIsReportFileModalOpen(true)} + setIsReportFileModalOpen(true) + } } showFileInfo={(fileInfoPath: string) => { setFilePath(fileInfoPath) @@ -1064,8 +1140,8 @@ const FilesList = ({ isShared = false }: Props) => { other: `You are about to delete ${selectedCids.length} items.` }) } - rejectText = {t`Cancel`} - acceptText = {t`Confirm`} + rejectText={t`Cancel`} + acceptText={t`Confirm`} acceptButtonProps={{ loading: isDeletingFiles, disabled: isDeletingFiles, testId: "confirm-deletion" }} rejectButtonProps={{ disabled: isDeletingFiles, testId: "cancel-deletion" }} injectedClass={{ inner: classes.confirmDeletionDialog }} @@ -1113,39 +1189,39 @@ const FilesList = ({ isShared = false }: Props) => { filePath={isSearch && getPath ? getPath(files[fileIndex].cid) : currentPath} /> )} - { filePath && isReportFileModalOpen && - { - setIsReportFileModalOpen(false) - setFilePath(undefined) - }} - /> + {filePath && isReportFileModalOpen && + { + setIsReportFileModalOpen(false) + setFilePath(undefined) + }} + /> } - { filePath && isFileInfoModalOpen && - { - setIsFileInfoModalOpen(false) - setFilePath(undefined) - }} - /> + {filePath && isFileInfoModalOpen && + { + setIsFileInfoModalOpen(false) + setFilePath(undefined) + }} + /> } - { !showExplainerBeforeShare && isShareModalOpen && selectedItems.length && - { - setIsShareModalOpen(false) - setFilePath(undefined) - }} - fileSystemItems={selectedItems} - /> + {!showExplainerBeforeShare && isShareModalOpen && selectedItems.length && + { + setIsShareModalOpen(false) + setFilePath(undefined) + }} + fileSystemItems={selectedItems} + /> } {accountRestricted && - + } { {!error && !newBucket && isValidNonce !== false && ( <> diff --git a/packages/files-ui/src/Components/Modules/LoginModule/ConciseExplainer.tsx b/packages/files-ui/src/Components/Modules/LoginModule/ConciseExplainer.tsx index 9ada6ef109..d18dec3849 100644 --- a/packages/files-ui/src/Components/Modules/LoginModule/ConciseExplainer.tsx +++ b/packages/files-ui/src/Components/Modules/LoginModule/ConciseExplainer.tsx @@ -178,6 +178,7 @@ const ConciseExplainer: React.FC = ({ className, onConti variant="primary" onClick={onContinue} className={classes.continue} + data-cy="button-sign-in-explainer-continue" > Continue diff --git a/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx b/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx index d8f8a5747b..9cff2adaf7 100644 --- a/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx +++ b/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx @@ -360,7 +360,7 @@ const InitialScreen = ({ className }: IInitialScreen) => { } diff --git a/packages/files-ui/src/Components/Modules/PreviewRenderers/ImagePreview.tsx b/packages/files-ui/src/Components/Modules/PreviewRenderers/ImagePreview.tsx index a2217961b1..ddba1879cd 100644 --- a/packages/files-ui/src/Components/Modules/PreviewRenderers/ImagePreview.tsx +++ b/packages/files-ui/src/Components/Modules/PreviewRenderers/ImagePreview.tsx @@ -48,7 +48,7 @@ const ImagePreview: React.FC = ({ contents, contentType } const [imageUrl, setImageUrl] = useState() const [loading, setLoading] = useState(false) useEffect(() => { - if (contentType !== "image/heic") { + if (contentType !== "image/heic" && contentType !== "image/heif") { setImageUrl(URL.createObjectURL(contents)) } else { setLoading(true) @@ -72,7 +72,7 @@ const ImagePreview: React.FC = ({ contents, contentType } {loading ? : = ({ No search results for {` ${searchResults.query}`} )} - {searchResultsFiles && searchResultsFiles.length && ( + {!!searchResultsFiles?.length && (
= ({ ))}
)} - {searchResultsFolders && searchResultsFolders.length && ( + {!!searchResultsFolders?.length && (
= ({ isRefreshing }) => { > Saved Browsers {isRefreshing && } {browserShares diff --git a/packages/files-ui/src/Components/Pages/BillingHistory.tsx b/packages/files-ui/src/Components/Pages/BillingHistory.tsx index 467e38c368..116966c28b 100644 --- a/packages/files-ui/src/Components/Pages/BillingHistory.tsx +++ b/packages/files-ui/src/Components/Pages/BillingHistory.tsx @@ -71,7 +71,7 @@ const BillingHistory = () => {
diff --git a/packages/files-ui/src/Contexts/FilesContext.tsx b/packages/files-ui/src/Contexts/FilesContext.tsx index 8dc9da4714..b0b339cdcd 100644 --- a/packages/files-ui/src/Contexts/FilesContext.tsx +++ b/packages/files-ui/src/Contexts/FilesContext.tsx @@ -482,7 +482,9 @@ const FilesProvider = ({ children }: FilesContextProps) => { } } catch (error) { if (axios.isCancel(error)) { - return Promise.reject(error) + // Do not propogate cancellation up the stack to ensure that the next + // download starts correctly + return Promise.reject() } else { console.error(error) return Promise.reject(error) diff --git a/packages/files-ui/src/UI-components/Menu.tsx b/packages/files-ui/src/UI-components/Menu.tsx index c5f99c988f..ee82472fad 100644 --- a/packages/files-ui/src/UI-components/Menu.tsx +++ b/packages/files-ui/src/UI-components/Menu.tsx @@ -1,5 +1,5 @@ import React, { useState, ReactNode, useMemo } from "react" -import { Menu as MaterialMenu, MenuItem } from "@material-ui/core" +import { Menu as MaterialMenu, MenuItem, PopoverOrigin } from "@material-ui/core" import { makeStyles, createStyles } from "@chainsafe/common-theme" import clsx from "clsx" import { useCallback } from "react" @@ -7,6 +7,8 @@ import { CSFTheme } from "../Themes/types" interface Option { contents: ReactNode + inset?: boolean + testId?: string onClick?: () => void disabled?: boolean } @@ -23,6 +25,8 @@ interface Props { options: Option[] style?: CustomClasses testId?: string + anchorOrigin?: PopoverOrigin + transformOrigin?: PopoverOrigin } const useStyles = makeStyles(({ constants }: CSFTheme) => { @@ -41,7 +45,7 @@ const useStyles = makeStyles(({ constants }: CSFTheme) => { } })}) -export default function Menu({ icon, options, style, testId }: Props) { +export default function Menu({ icon, options, style, testId, anchorOrigin, transformOrigin }: Props) { const [anchorEl, setAnchorEl] = useState(null) const open = useMemo(() => Boolean(anchorEl), [anchorEl]) const classes = useStyles() @@ -69,12 +73,14 @@ export default function Menu({ icon, options, style, testId }: Props) { open={open} onClose={handleClose} PopoverClasses={{ paper: classes.paper, root: style?.root }} + anchorOrigin={anchorOrigin} + transformOrigin={transformOrigin} > {options.map((option, index) => ( { - handleClose() + option.onClick && handleClose() option.onClick && option.onClick() }} focusVisibleClassName={clsx(style?.focusVisible)} diff --git a/packages/files-ui/src/locales/de/messages.po b/packages/files-ui/src/locales/de/messages.po index 471472f20c..636d6b989e 100644 --- a/packages/files-ui/src/locales/de/messages.po +++ b/packages/files-ui/src/locales/de/messages.po @@ -118,9 +118,15 @@ msgstr "IID (Inhaltsidentifikator)" msgid "Cancel" msgstr "Abbrechen" +msgid "Card added" +msgstr "" + msgid "Card inputs invalid" msgstr "" +msgid "Card updated" +msgstr "" + msgid "Change Password" msgstr "Passwort ändern" @@ -193,9 +199,6 @@ msgstr "Erstellen" msgid "Create Shared Folder" msgstr "" -msgid "Create a Shared Folder" -msgstr "" - msgid "Create a sharing link" msgstr "" @@ -235,6 +238,9 @@ msgstr "" msgid "Date" msgstr "" +msgid "Date Uploaded" +msgstr "" + msgid "Date uploaded" msgstr "Hochgeladen am" @@ -787,6 +793,9 @@ msgstr "Etwas ist schief gelaufen!" msgid "Something went wrong. We couldn't upload your file" msgstr "Es ist etwas schief gelaufen. Wir konnten Ihre Datei nicht hochladen" +msgid "Sort By:" +msgstr "" + msgid "Standard plan" msgstr "" @@ -796,6 +805,9 @@ msgstr "Hochladen starten" msgid "Start a team" msgstr "" +#~ msgid "Storage Plan" +#~ msgstr "Speicherplan" + msgid "Stored by miner" msgstr "" @@ -898,6 +910,12 @@ msgstr "" msgid "Update Shared Folder" msgstr "" +msgid "Update card" +msgstr "" + +msgid "Update your credit card" +msgstr "" + msgid "Upgrade your plan" msgstr "" @@ -988,6 +1006,9 @@ msgstr "Sie können nun geteilte Ordner erstellen, um eine Datei zu teilen." msgid "You can't move folders to this path" msgstr "Sie können keine Ordner in diesen Pfad verschieben" +msgid "You do not have access to this shared folder." +msgstr "" + msgid "You haven't set a username yet." msgstr "Sie haben noch keinen Benutzernamen festgelegt." @@ -1004,7 +1025,7 @@ msgid "Your plan" msgstr "" msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." -msgstr "Ihr Wiederherstellungsschlüssel kann zur Wiederherstellung Ihres Kontos anstelle Ihres Sicherungsgeheimsatz verwendet werden." +msgstr "" msgid "can-edit" msgstr "" diff --git a/packages/files-ui/src/locales/en/messages.po b/packages/files-ui/src/locales/en/messages.po index dfeaf3d75e..5fa2fac4d0 100644 --- a/packages/files-ui/src/locales/en/messages.po +++ b/packages/files-ui/src/locales/en/messages.po @@ -118,9 +118,15 @@ msgstr "CID (Content Identifier)" msgid "Cancel" msgstr "Cancel" +msgid "Card added" +msgstr "Card added" + msgid "Card inputs invalid" msgstr "Card inputs invalid" +msgid "Card updated" +msgstr "Card updated" + msgid "Change Password" msgstr "Change Password" @@ -193,9 +199,6 @@ msgstr "Create" msgid "Create Shared Folder" msgstr "Create Shared Folder" -msgid "Create a Shared Folder" -msgstr "Create a Shared Folder" - msgid "Create a sharing link" msgstr "Create a sharing link" @@ -235,6 +238,9 @@ msgstr "Data restored successfully" msgid "Date" msgstr "Date" +msgid "Date Uploaded" +msgstr "Date Uploaded" + msgid "Date uploaded" msgstr "Date uploaded" @@ -790,6 +796,9 @@ msgstr "Something went wrong!" msgid "Something went wrong. We couldn't upload your file" msgstr "Something went wrong. We couldn't upload your file" +msgid "Sort By:" +msgstr "Sort By:" + msgid "Standard plan" msgstr "Standard plan" @@ -799,6 +808,9 @@ msgstr "Start Upload" msgid "Start a team" msgstr "Start a team" +#~ msgid "Storage Plan" +#~ msgstr "Storage Plan" + msgid "Stored by miner" msgstr "Stored by miner" @@ -901,6 +913,12 @@ msgstr "Update Card" msgid "Update Shared Folder" msgstr "Update Shared Folder" +msgid "Update card" +msgstr "Update card" + +msgid "Update your credit card" +msgstr "Update your credit card" + msgid "Upgrade your plan" msgstr "Upgrade your plan" @@ -991,6 +1009,9 @@ msgstr "You can now create shared folders to share a file." msgid "You can't move folders to this path" msgstr "You can't move folders to this path" +msgid "You do not have access to this shared folder." +msgstr "You do not have access to this shared folder." + msgid "You haven't set a username yet." msgstr "You haven't set a username yet." diff --git a/packages/files-ui/src/locales/es/messages.po b/packages/files-ui/src/locales/es/messages.po index 6fe89ddda9..3598060523 100644 --- a/packages/files-ui/src/locales/es/messages.po +++ b/packages/files-ui/src/locales/es/messages.po @@ -119,9 +119,15 @@ msgstr "CID (Identificador de contenido)" msgid "Cancel" msgstr "Cancelar" +msgid "Card added" +msgstr "" + msgid "Card inputs invalid" msgstr "" +msgid "Card updated" +msgstr "" + msgid "Change Password" msgstr "Cambiar la contraseña" @@ -194,9 +200,6 @@ msgstr "Crear" msgid "Create Shared Folder" msgstr "" -msgid "Create a Shared Folder" -msgstr "" - msgid "Create a sharing link" msgstr "" @@ -236,6 +239,9 @@ msgstr "" msgid "Date" msgstr "" +msgid "Date Uploaded" +msgstr "" + msgid "Date uploaded" msgstr "Fecha de subida" @@ -791,6 +797,9 @@ msgstr "" msgid "Something went wrong. We couldn't upload your file" msgstr "Algo salió mal. No pudimos subir tu archivo" +msgid "Sort By:" +msgstr "" + msgid "Standard plan" msgstr "" @@ -800,6 +809,9 @@ msgstr "Iniciar la subida" msgid "Start a team" msgstr "" +#~ msgid "Storage Plan" +#~ msgstr "Plan de almacenamiento" + msgid "Stored by miner" msgstr "Almacenado por el minero" @@ -902,6 +914,12 @@ msgstr "" msgid "Update Shared Folder" msgstr "" +msgid "Update card" +msgstr "" + +msgid "Update your credit card" +msgstr "" + msgid "Upgrade your plan" msgstr "" @@ -992,6 +1010,9 @@ msgstr "" msgid "You can't move folders to this path" msgstr "" +msgid "You do not have access to this shared folder." +msgstr "" + msgid "You haven't set a username yet." msgstr "" diff --git a/packages/files-ui/src/locales/fr/messages.po b/packages/files-ui/src/locales/fr/messages.po index 936d849039..43d3f2d09d 100644 --- a/packages/files-ui/src/locales/fr/messages.po +++ b/packages/files-ui/src/locales/fr/messages.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-04-23 11:05+0200\n" -"PO-Revision-Date: 2021-11-21 00:53+0000\n" +"PO-Revision-Date: 2021-11-27 00:52+0000\n" "Last-Translator: J. Lavoie \n" "Language-Team: French \n" "Language: fr\n" @@ -11,7 +11,7 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.9.1\n" +"X-Generator: Weblate 4.10-dev\n" "Mime-Version: 1.0\n" msgid "A backup secret phrase will be generated and used for your account.<0/>We do not store it and <1>it can only be displayed once. Save it somewhere safe!" @@ -119,9 +119,15 @@ msgstr "CID (Identifiant de contenu)" msgid "Cancel" msgstr "Annuler" +msgid "Card added" +msgstr "" + msgid "Card inputs invalid" msgstr "" +msgid "Card updated" +msgstr "" + msgid "Change Password" msgstr "Changer le mot de passe" @@ -194,9 +200,6 @@ msgstr "Créer" msgid "Create Shared Folder" msgstr "Créer un dossier partagé" -msgid "Create a Shared Folder" -msgstr "Créer un dossier partagé" - msgid "Create a sharing link" msgstr "Créer un lien de partage" @@ -236,6 +239,9 @@ msgstr "Données restaurées avec succès" msgid "Date" msgstr "" +msgid "Date Uploaded" +msgstr "" + msgid "Date uploaded" msgstr "Téléversé le" @@ -651,7 +657,7 @@ msgid "Rename folder" msgstr "Renommer le dossier" msgid "Rename shared folder" -msgstr "" +msgstr "Renommer le dossier partagé" msgid "Report" msgstr "Signaler" @@ -791,6 +797,9 @@ msgstr "Quelque chose a mal tourné !" msgid "Something went wrong. We couldn't upload your file" msgstr "Un problème est survenu. Nous n’avons pas pu téléverser votre fichier" +msgid "Sort By:" +msgstr "" + msgid "Standard plan" msgstr "" @@ -800,6 +809,9 @@ msgstr "Démarrer le téléversement" msgid "Start a team" msgstr "Créer une équipe" +#~ msgid "Storage Plan" +#~ msgstr "Plan de stockage" + msgid "Stored by miner" msgstr "Sauvegardé par le mineur" @@ -902,6 +914,12 @@ msgstr "" msgid "Update Shared Folder" msgstr "Mettre à jour le dossier partagé" +msgid "Update card" +msgstr "" + +msgid "Update your credit card" +msgstr "" + msgid "Upgrade your plan" msgstr "" @@ -992,6 +1010,9 @@ msgstr "Vous pouvez maintenant créer des dossiers partagés pour partager un fi msgid "You can't move folders to this path" msgstr "Vous ne pouvez pas déplacer les dossiers vers ce chemin" +msgid "You do not have access to this shared folder." +msgstr "Vous n'avez pas accès à ce dossier partagé." + msgid "You haven't set a username yet." msgstr "Vous n’avez pas encore défini de nom d’utilisateur." diff --git a/packages/files-ui/src/locales/no/messages.po b/packages/files-ui/src/locales/no/messages.po index 421ffb8d44..984f8f9850 100644 --- a/packages/files-ui/src/locales/no/messages.po +++ b/packages/files-ui/src/locales/no/messages.po @@ -118,9 +118,15 @@ msgstr "" msgid "Cancel" msgstr "Avbryt" +msgid "Card added" +msgstr "" + msgid "Card inputs invalid" msgstr "" +msgid "Card updated" +msgstr "" + msgid "Change Password" msgstr "Endre passord" @@ -193,9 +199,6 @@ msgstr "Opprett" msgid "Create Shared Folder" msgstr "" -msgid "Create a Shared Folder" -msgstr "" - msgid "Create a sharing link" msgstr "" @@ -235,6 +238,9 @@ msgstr "" msgid "Date" msgstr "" +msgid "Date Uploaded" +msgstr "" + msgid "Date uploaded" msgstr "Dato opplastet" @@ -787,6 +793,9 @@ msgstr "Noe gikk galt." msgid "Something went wrong. We couldn't upload your file" msgstr "" +msgid "Sort By:" +msgstr "" + msgid "Standard plan" msgstr "" @@ -796,6 +805,9 @@ msgstr "" msgid "Start a team" msgstr "" +#~ msgid "Storage Plan" +#~ msgstr "" + msgid "Stored by miner" msgstr "" @@ -898,6 +910,12 @@ msgstr "" msgid "Update Shared Folder" msgstr "" +msgid "Update card" +msgstr "" + +msgid "Update your credit card" +msgstr "" + msgid "Upgrade your plan" msgstr "" @@ -988,6 +1006,9 @@ msgstr "" msgid "You can't move folders to this path" msgstr "" +msgid "You do not have access to this shared folder." +msgstr "" + msgid "You haven't set a username yet." msgstr "Du har ikke satt noe brukernavn enda." diff --git a/packages/gaming-ui/.env.example b/packages/gaming-ui/.env.example deleted file mode 100644 index f1c140f7b7..0000000000 --- a/packages/gaming-ui/.env.example +++ /dev/null @@ -1,8 +0,0 @@ -PORT=3000 -HTTPS=false - -REACT_APP_API_URL=https://stage.imploy.site/api/v1 -REACT_APP_BLOCKNATIVE_ID= -REACT_APP_GOOGLE_CLIENT_ID= -REACT_APP_AUTH0_DOMAIN= -REACT_APP_AUTH0_CLIENT_ID= \ No newline at end of file diff --git a/packages/gaming-ui/.gitignore b/packages/gaming-ui/.gitignore deleted file mode 100644 index 9532771241..0000000000 --- a/packages/gaming-ui/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -.env - -src/locales/*/messages.js -src/locales/_build - diff --git a/packages/gaming-ui/.linguirc b/packages/gaming-ui/.linguirc deleted file mode 100644 index 1b7ae61f54..0000000000 --- a/packages/gaming-ui/.linguirc +++ /dev/null @@ -1,14 +0,0 @@ -{ - "catalogs": [{ - "path": "/src/locales/{locale}/messages", - "include": ["/src/**"], - "exclude": ["**/node_modules/**", "/src/locales/**"] - }], - "compileNamespace": "cjs", - "format": "po", - "formatOptions": { - "origins": false - }, - "locales": ["en"], - "sourceLocale": "en" -} \ No newline at end of file diff --git a/packages/gaming-ui/.sentryclirc b/packages/gaming-ui/.sentryclirc deleted file mode 100644 index b50913bad5..0000000000 --- a/packages/gaming-ui/.sentryclirc +++ /dev/null @@ -1,3 +0,0 @@ -[defaults] -org=chainsafe -project=gaming-ui diff --git a/packages/gaming-ui/README.md b/packages/gaming-ui/README.md deleted file mode 100644 index cba766f6f8..0000000000 --- a/packages/gaming-ui/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# ChainSafe Gaming UI Repo - -![Dev](https://github.com/imploy/files-ui/workflows/Dev/badge.svg?branch=dev) -[![Netlify Status](https://api.netlify.com/api/v1/badges/cb6afc46-ec5d-4cac-91c2-dbd0d866b89a/deploy-status)](https://app.netlify.com/sites/angry-lewin-719dd6/deploys) -[![Maintainability](https://api.codeclimate.com/v1/badges/6a9b1984bc9622792d3e/maintainability)](https://codeclimate.com/repos/5f0224802dfa0b018f0021b0/maintainability) -[![Test Coverage](https://api.codeclimate.com/v1/badges/6a9b1984bc9622792d3e/test_coverage)](https://codeclimate.com/repos/5f0224802dfa0b018f0021b0/test_coverage) - -## Run development (.env) - -``` -yarn install -yarn start -``` - -## Build production (.env) - -``` -yarn build -``` - -## Run test and test coverage - -``` -yarn test -yarn coverage -``` - -**Visit**: `http://localhost:3000` diff --git a/packages/gaming-ui/craco.config.js b/packages/gaming-ui/craco.config.js deleted file mode 100644 index 16c3b8144d..0000000000 --- a/packages/gaming-ui/craco.config.js +++ /dev/null @@ -1,48 +0,0 @@ -const TerserPlugin = require("terser-webpack-plugin") - -module.exports = { - babel: { - presets: [], - plugins: ["macros"], - loaderOptions: (babelLoaderOptions, { env, paths }) => { - return babelLoaderOptions - } - }, - webpack: { - configure: (webpackConfig) => ({ - ...webpackConfig, - optimization: { - ...webpackConfig.optimization, - minimizer: [ - new TerserPlugin({ - terserOptions: { - parse: { - ecma: 8 - }, - compress: { - ecma: 5, - warnings: false, - comparisons: false, - inline: 2, - drop_console: true - }, - mangle: { - safari10: true - }, - output: { - ecma: 5, - comments: false, - ascii_only: true - } - }, - parallel: 2, - cache: true, - sourceMap: true, - extractComments: false - }) - ] - }, - devtool: "source-map" - }) - } -} diff --git a/packages/gaming-ui/cypress.json b/packages/gaming-ui/cypress.json deleted file mode 100644 index fb59b54133..0000000000 --- a/packages/gaming-ui/cypress.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "integrationFolder": "cypress/tests", - "video": false -} diff --git a/packages/gaming-ui/cypress/fixtures/loginData.ts b/packages/gaming-ui/cypress/fixtures/loginData.ts deleted file mode 100644 index 9852d7c4c4..0000000000 --- a/packages/gaming-ui/cypress/fixtures/loginData.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const testPrivateKey = "0x4fd9a44c051834e28a919096f154e3f805f58d8f2d90a1ab9a29b0b46a6ac363" -export const testAddress = "0xDa1f70D176E0F7F16f2a3bB509cD37Bd36aFD902" -export const localHost = "http://localhost:3000" \ No newline at end of file diff --git a/packages/gaming-ui/cypress/plugins/index.ts b/packages/gaming-ui/cypress/plugins/index.ts deleted file mode 100644 index 77ca4f8215..0000000000 --- a/packages/gaming-ui/cypress/plugins/index.ts +++ /dev/null @@ -1,57 +0,0 @@ -/// -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** -import { existsSync, readFileSync } from "fs" - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -/** - * @type {Cypress.PluginConfig} - */ - -export default (on: any) => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config - - on("task", { - readFileMaybe(filename: string) { - if (existsSync(filename)) { - return readFileSync(filename, "utf8") - } - - return null - } - }) - - on("before:browser:launch", (browser: Cypress.Browser, launchOptions: Cypress.BrowserLaunchOptions) => { - if (browser.name === "chrome" && browser.isHeadless) { - // fullPage screenshot size is 1280x720 on non-retina screens - launchOptions.args.push("--window-size=1280,720") - - // force screen to be non-retina (1280x720 size) - launchOptions.args.push("--force-device-scale-factor=1") - } - - if (browser.name === "electron" && browser.isHeadless) { - // fullPage screenshot size is 12807200 - launchOptions.preferences.width = 1280 - launchOptions.preferences.height = 720 - } - - if (browser.name === "firefox" && browser.isHeadless) { - // menubars take up height on the screen - launchOptions.args.push("--width=1280") - launchOptions.args.push("--height=720") - } - - return launchOptions - }) -} diff --git a/packages/gaming-ui/cypress/support/commands.ts b/packages/gaming-ui/cypress/support/commands.ts deleted file mode 100644 index 134cb8f541..0000000000 --- a/packages/gaming-ui/cypress/support/commands.ts +++ /dev/null @@ -1,171 +0,0 @@ -/* eslint-disable @typescript-eslint/no-namespace */ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add("login", (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) - -import { authenticationPage } from "./page-objects/authenticationPage" -import { ethers, Wallet } from "ethers" -import { testPrivateKey, localHost } from "../fixtures/loginData" -import { CustomizedBridge } from "./utils/CustomBridge" -import "cypress-file-upload" -import { cidsPage } from "./page-objects/cidsPage" - -export type Storage = Record[]; - -export interface Web3LoginOptions { - url?: string - apiUrlBase?: string - saveBrowser?: boolean - useLocalAndSessionStorage?: boolean - clearCSFBucket?: boolean - clearTrashBucket?: boolean -} - -const SESSION_FILE = "cypress/fixtures/storage/sessionStorage.json" -const LOCAL_FILE = "cypress/fixtures/storage/localStorage.json" - -Cypress.Commands.add("saveLocalAndSession", () => { - // save local and session storage in files - cy.window().then((win) => { - const newLocal: Storage = [] - const newSession: Storage = [] - - Object.keys(win.localStorage).forEach((key) => { - newLocal.push({ key, value: win.localStorage.getItem(key) || "" }) - }) - - Object.keys(win.sessionStorage).forEach((key) => { - newSession.push({ key, value: win.sessionStorage.getItem(key) || "" }) - }) - - const newLocalString = JSON.stringify(newLocal) - const newSessionString = JSON.stringify(newSession) - - cy.writeFile(SESSION_FILE, newSessionString) - cy.writeFile(LOCAL_FILE, newLocalString) - }) -}) - -Cypress.Commands.add( - "web3Login", - ({ - url = localHost, - // apiUrlBase = "https://stage.imploy.site/api/v1", - useLocalAndSessionStorage = true - }: Web3LoginOptions = {}) => { - let session: Storage = [] - let local: Storage = [] - - cy.task("readFileMaybe", SESSION_FILE).then( - (unparsedSession) => { - session = (unparsedSession && JSON.parse(unparsedSession)) || [] - } - ) - - cy.task("readFileMaybe", LOCAL_FILE).then( - (unparsedLocal) => { - local = (unparsedLocal && JSON.parse(unparsedLocal)) || [] - } - ) - - cy.on("window:before:load", (win) => { - const provider = new ethers.providers.JsonRpcProvider( - "https://rinkeby.infura.io/v3/4bf032f2d38a4ed6bb975b80d6340847", - 4 - ) - const signer = new Wallet(testPrivateKey, provider) - // inject ethereum object in the global window - Object.defineProperty(win, "ethereum", { - get: () => new CustomizedBridge(signer as any, provider as any) - }) - - // clear session storage in any case, if previous session storage should be - // kept will be decided after. - // Note that Cypress keep the session storage between test but clears localStorage - win.sessionStorage.clear() - win.localStorage.clear() - - if (useLocalAndSessionStorage) { - session.forEach(({ key, value }) => { - win.sessionStorage.setItem(key, value) - }) - - local.forEach(({ key, value }) => { - win.localStorage.setItem(key, value) - }) - } - }) - - cy.visit(url) - - // with nothing in localstorage (and in session storage) - // the whole login flow should kick in - cy.then(() => { - cy.log( - "Logging in", - local.length > 0 && - "there is something in session storage ---> direct login" - ) - - if (local.length === 0) { - cy.log("nothing in session storage, --> click on web3 button") - authenticationPage.web3Button().click() - authenticationPage.metaMaskButton().click() - authenticationPage.web3SignInButton().click() - } - }) - - cidsPage.cidsHeaderLabel().should("be.visible") - - cy.saveLocalAndSession() - - } -) - -// Must be declared global to be detected by typescript (allows import/export) -// eslint-disable @typescript/interface-name -declare global { - namespace Cypress { - interface Chainable { - /** - * Login using Metamask to an instance of Files. - * @param {String} options.url - (default: "http://localhost:3000") - what url to visit. - * @param {String} apiUrlBase - (default: "https://stage.imploy.site/api/v1") - what url to call for the api. - * @param {Boolean} options.useLocalAndSessionStorage - (default: true) - use what could have been stored before to speedup login - * @example cy.web3Login({saveBrowser: true, url: 'http://localhost:8080'}) - */ - web3Login: (options?: Web3LoginOptions) => Chainable - - /** - * Save local and session storage to local files - * @example cy.saveLocalAndSession() - */ - saveLocalAndSession: () => Chainable - } - } -} - -// Convert this to a module instead of script (allows import/export) -export {} diff --git a/packages/gaming-ui/cypress/support/index.ts b/packages/gaming-ui/cypress/support/index.ts deleted file mode 100644 index cb8233c617..0000000000 --- a/packages/gaming-ui/cypress/support/index.ts +++ /dev/null @@ -1,32 +0,0 @@ -/// -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** -// Import commands.js using ES2015 syntax: -import "./commands" - -// the following gets rid of the exception "ResizeObserver loop limit exceeded" -// which someone on the internet says we can safely ignore -// source https://stackoverflow.com/questions/49384120/resizeobserver-loop-limit-exceeded -Cypress.on("uncaught:exception", (err) => { - /* returning false here prevents Cypress from failing the test */ - if (err.message.includes("ResizeObserver loop limit exceeded")) { - // returning false here prevents Cypress from - // failing the test - return false - } -}) - -// Alternatively you can use CommonJS syntax: -// require('./commands') diff --git a/packages/gaming-ui/cypress/support/page-objects/authenticationPage.ts b/packages/gaming-ui/cypress/support/page-objects/authenticationPage.ts deleted file mode 100644 index ccd7a616d2..0000000000 --- a/packages/gaming-ui/cypress/support/page-objects/authenticationPage.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { basePage } from "./basePage" - -export const authenticationPage = { - ...basePage, - - // get started section elements - web3Button: () => cy.get("[data-cy=web3]", { timeout: 120000 }), - metaMaskButton: () => cy.get(".bn-onboard-modal-select-wallets > :nth-child(1) > .bn-onboard-custom"), - web3SignInButton: () => cy.get("[data-cy=sign-in-with-web3-button]") -} diff --git a/packages/gaming-ui/cypress/support/page-objects/basePage.ts b/packages/gaming-ui/cypress/support/page-objects/basePage.ts deleted file mode 100644 index bcf8f88e52..0000000000 --- a/packages/gaming-ui/cypress/support/page-objects/basePage.ts +++ /dev/null @@ -1,6 +0,0 @@ -// Only add things here that could be applicable to all / most pages - -export const basePage = { - // Mobile view only element - hamburgerMenuButton: () => cy.get("[data-testId=hamburger-menu]") -} diff --git a/packages/gaming-ui/cypress/support/page-objects/homePage.ts b/packages/gaming-ui/cypress/support/page-objects/homePage.ts deleted file mode 100644 index b2a30da731..0000000000 --- a/packages/gaming-ui/cypress/support/page-objects/homePage.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { basePage } from "./basePage" - -export const click = ($el: JQuery) => $el.trigger("click") - -export const homePage = { - ...basePage - - // // main file browser elements - // uploadButton: () => cy.get("[data-cy=upload-modal-button]"), - // uploadFileForm: () => cy.get("[data-cy=upload-file-form] input", { timeout: 20000 }), - // moveSelectedButton: () => cy.get("[data-testId=button-move-selected-file]"), - // deleteSelectedButton: () => cy.get("[data-testId=button-delete-selected-file]"), - // deleteFileDialog: () => cy.get("[data-testid=modal-container-file-deletion]"), - // deleteFileCancelButton: () => cy.get("[data-testid=button-cancel-deletion]"), - // deleteFileConfirmButton: () => cy.get("[data-testid=button-confirm-deletion]"), - // uploadStatusToast: () => cy.get("[data-cy=upload-status-toast-message]", { timeout: 10000 }), - - // // file browser row elements - // fileItemRow: () => cy.get("[data-cy=file-item-row]", { timeout: 20000 }), - // fileItemName: () => cy.get("[data-cy=file-item-name]"), - // fileRenameInput: () => cy.get("[data-cy=rename-form] input"), - // fileRenameSubmitButton: () => cy.get("[data-cy=rename-submit-button]"), - // fileRenameErrorLabel: () => cy.get("[data-cy=rename-form] span.minimal.error"), - // fileItemKebabButton: () => cy.get("[data-testid=dropdown-title-fileDropdown]"), - - // // upload modal elements - // startUploadButton: () => cy.get("[data-testId=button-start-upload]"), - // uploadCancelButton: () => cy.get("[data-testId=button-cancel-upload]"), - // fileListRemoveButton: () => cy.get("[data-testid=button-remove-from-file-list]"), - // fileUploadList: () => cy.get("[data-testid=file-list-fileUpload] li"), - // fileUploadDropzone : () => cy.get("[data-testid=file-input-dropzone-fileUpload]"), - - // // menu elements - // previewMenuOption: () => cy.get("[data-cy=menu-preview]"), - // downloadMenuOption: () => cy.get("[data-cy=menu-download]"), - // infoMenuOption: () => cy.get("[data-cy=menu-info]"), - // renameMenuOption: () => cy.get("[data-cy=menu-rename]"), - // moveMenuOption: () => cy.get("[data-cy=menu-move]"), - // deleteMenuOption: () => cy.get("[data-cy=menu-delete]"), - - // clickUploadButton: () => homePage.startUploadButton() - // .should("not.be.disabled") - // // this pipe is needed to prevent https://github.com/ChainSafe/ui-monorepo/issues/1146 - // // as described https://www.cypress.io/blog/2019/01/22/when-can-the-test-click/ - // .pipe(click) - // .should(($el: JQuery) => { - // expect($el).to.not.be.visible - // }), - - // // helpers and convenience functions - // uploadFile(filePath: string) { - // this.uploadButton().click() - // this.uploadFileForm().attachFile(filePath) - // this.fileUploadList().should("have.length", 1) - // this.fileListRemoveButton().should("be.visible") - // this.clickUploadButton() - - // // ensure upload is complete before proceeding - // this.uploadFileForm().should("not.exist") - // this.uploadStatusToast().should("not.exist") - // } - -} - diff --git a/packages/gaming-ui/cypress/support/page-objects/navigationMenu.ts b/packages/gaming-ui/cypress/support/page-objects/navigationMenu.ts deleted file mode 100644 index a8fab10caf..0000000000 --- a/packages/gaming-ui/cypress/support/page-objects/navigationMenu.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { basePage } from "./basePage" - -export const navigationMenu = { - ...basePage, - homeNavButton: () => cy.get("[data-cy=home-nav]"), - settingsNavButton: () => cy.get("[data-cy=settings-nav]") - // spaceUsedLabel: () => cy.get("[data-cy=space-used-label]"), - // spaceUsedProgressBar: () => cy.get("[data-cy=space-used-progress-bar]"), - // sendFeedbackNavButton: () => cy.get("[data-cy=send-feedback-nav]"), - // signOutButton: () => cy.get("[data-cy=signout-nav]") -} diff --git a/packages/gaming-ui/cypress/support/page-objects/settingsPage.ts b/packages/gaming-ui/cypress/support/page-objects/settingsPage.ts deleted file mode 100644 index 40f6cf9bfe..0000000000 --- a/packages/gaming-ui/cypress/support/page-objects/settingsPage.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { basePage } from "./basePage" - -export const settingsPage = { - ...basePage - -} diff --git a/packages/gaming-ui/cypress/support/utils/CustomBridge.ts b/packages/gaming-ui/cypress/support/utils/CustomBridge.ts deleted file mode 100644 index 4924ecbbff..0000000000 --- a/packages/gaming-ui/cypress/support/utils/CustomBridge.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { Eip1193Bridge } from "@ethersproject/experimental/lib/eip1193-bridge" -import { toUtf8String } from "ethers/lib/utils" -import { testAddress } from "../../fixtures/loginData" - -export class CustomizedBridge extends Eip1193Bridge { - async sendAsync(...args: Array) { - return this.send(...args) - } - - async isMetaMask() { - return true - } - - async send(...args: Array) { - const isCallbackForm = typeof args[0] === "object" && typeof args[1] === "function" - let callback - let method - let params - if (isCallbackForm) { - callback = args[1] - method = args[0].method - params = args[0].params - } else { - method = args[0] - params = args[1] - } - - if (method === "personal_sign") { - const addr = params[1] - const message = params[0] - - if ( - (addr as string).toLowerCase() !== testAddress.toLowerCase() - ) { - return Promise.reject( - `Wrong address, expected ${testAddress}, but got ${addr}` - ) - } - - try { - const sig = await this.signer.signMessage(toUtf8String(message)) - return sig - } catch (e) { - return Promise.reject( - `Error in CustomizedBridge for personal_sign: ${e.message}` - ) - } - } - - if (method === "eth_requestAccounts" || method === "eth_accounts") { - if (isCallbackForm) { - callback({ result: [testAddress] }) - } else { - return Promise.resolve([testAddress]) - } - } - - if (method === "eth_chainId") { - if (isCallbackForm) { - callback(null, { result: "0x4" }) - } else { - return Promise.resolve("0x4") - } - } - - try { - const result = await super.send(method, params) - - if (isCallbackForm) { - callback(null, { result }) - } else { - return result - } - } catch (error) { - if (isCallbackForm) { - callback(error, null) - } else { - throw error - } - } - } -} \ No newline at end of file diff --git a/packages/gaming-ui/cypress/support/utils/apiTestHelper.ts b/packages/gaming-ui/cypress/support/utils/apiTestHelper.ts deleted file mode 100644 index 7f34ea2f37..0000000000 --- a/packages/gaming-ui/cypress/support/utils/apiTestHelper.ts +++ /dev/null @@ -1,9 +0,0 @@ -// import axios from "axios" -// import { FilesApiClient } from "@chainsafe/files-api-client" -// import { BucketType } from "@chainsafe/files-api-client" - -// const REFRESH_TOKEN_KEY = "csf.refreshToken" - -// export const apiTestHelper = { - -// } diff --git a/packages/gaming-ui/cypress/tests/main-navigation-spec.ts b/packages/gaming-ui/cypress/tests/main-navigation-spec.ts deleted file mode 100644 index b9a998cf33..0000000000 --- a/packages/gaming-ui/cypress/tests/main-navigation-spec.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { navigationMenu } from "../support/page-objects/navigationMenu" -import { homePage } from "../support/page-objects/homePage" - -describe("Main Navigation", () => { - - context("desktop", () => { - before(() => { - cy.web3Login() - }) - - it("can navigate to the cids page", () => { - navigationMenu.settingsNavButton().click() - cy.url().should("include", "/cids") - }) - }) - - context("mobile", () => { - before(() => { - cy.web3Login() - }) - - beforeEach(() => { - cy.viewport("iphone-6") - homePage.hamburgerMenuButton().click() - }) - - it("can navigate to the cids page", () => { - navigationMenu.settingsNavButton().click() - cy.url().should("include", "/cids") - }) - }) -}) diff --git a/packages/gaming-ui/cypress/tsconfig.json b/packages/gaming-ui/cypress/tsconfig.json deleted file mode 100644 index c58896952f..0000000000 --- a/packages/gaming-ui/cypress/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "compilerOptions": { - "strict": true, - "target": "es5", - "jsx": "react", - "lib": ["es5", "dom"], - "types": ["cypress", "cypress-file-upload"] - }, - "include": ["**/*.ts"] - } \ No newline at end of file diff --git a/packages/gaming-ui/package.json b/packages/gaming-ui/package.json deleted file mode 100644 index 22f8021c47..0000000000 --- a/packages/gaming-ui/package.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "name": "gaming-ui", - "version": "1.0.0", - "private": true, - "dependencies": { - "@babel/core": "^7.12.10", - "@babel/runtime": "^7.0.0", - "@chainsafe/browser-storage-hooks": "^1.0.1", - "@chainsafe/files-api-client": "^1.18.20", - "@chainsafe/web3-context": "1.1.4", - "@lingui/core": "^3.7.2", - "@lingui/react": "^3.7.2", - "@sentry/react": "^5.28.0", - "@toruslabs/torus-direct-web-sdk": "4.15.1", - "axios": "0.21.4", - "babel-loader": "8.1.0", - "babel-plugin-macros": "^2.8.0", - "babel-preset-env": "^1.7.0", - "babel-preset-react": "^6.24.1", - "bnc-onboard": "1.32.0", - "clsx": "^1.1.1", - "dayjs": "^1.9.7", - "eth-crypto": "^1.8.0", - "ethers": "^5.4.3", - "formik": "^2.2.5", - "mime-matcher": "^1.0.5", - "react": "^16.14.0", - "react-dom": "^16.14.0", - "react-hotkeys-hook": "^2.4.0", - "react-scripts": "3.4.4", - "react-swipeable": "^6.0.1", - "react-toast-notifications": "^2.4.0", - "react-use-hotjar": "1.0.8", - "react-zoom-pan-pinch": "^1.6.1", - "remark-gfm": "^1.0.0", - "typescript": "~4.0.5", - "yup": "^0.32.8", - "zxcvbn": "^4.4.2" - }, - "devDependencies": { - "@craco/craco": "^5.9.0", - "@ethersproject/experimental": "^5.1.2", - "@lingui/babel-preset-react": "^2.9.2", - "@lingui/cli": "^3.7.2", - "@lingui/macro": "3.7.2", - "@testing-library/jest-dom": "^5.11.6", - "@testing-library/react": "^11.2.2", - "@testing-library/user-event": "^12.5.0", - "@types/jest": "^26.0.16", - "@types/node": "^14.14.10", - "@types/react": "^17.0.0", - "@types/react-beforeunload": "^2.1.0", - "@types/react-dom": "^16.9.10", - "@types/react-pdf": "^5.0.0", - "@types/react-toast-notifications": "^2.4.0", - "@types/yup": "^0.29.9", - "@types/zxcvbn": "^4.4.0", - "babel-plugin-macros": "^2.8.0", - "cypress": "^9.0", - "cypress-file-upload": "^5.0.8", - "cypress-pipe": "^2.0.0" - }, - "scripts": { - "postinstall": "yarn compile", - "start": "yarn compile && craco --max_old_space_size=4096 start", - "build": "craco --max_old_space_size=4096 --openssl-legacy-provider build ", - "sentry": "(export REACT_APP_SENTRY_RELEASE=$(sentry-cli releases propose-version); node scripts/sentry.js)", - "release": "(export REACT_APP_SENTRY_RELEASE=$(sentry-cli releases propose-version); yarn compile && yarn build && node scripts/sentry.js)", - "test": "cypress open", - "test:ci": "cypress run --browser chrome --headless", - "analyze": "source-map-explorer 'build/static/js/*.js'", - "extract": "lingui extract", - "compile": "lingui compile", - "lingui-version": "lingui --version", - "lint": "eslint './{src, cypress}/**/*.{js,jsx,ts,tsx}'" - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - } -} diff --git a/packages/gaming-ui/public/ChainSafe-logo.png b/packages/gaming-ui/public/ChainSafe-logo.png deleted file mode 100644 index cfffdc4a82..0000000000 Binary files a/packages/gaming-ui/public/ChainSafe-logo.png and /dev/null differ diff --git a/packages/gaming-ui/public/_redirects b/packages/gaming-ui/public/_redirects deleted file mode 100644 index 50a463356b..0000000000 --- a/packages/gaming-ui/public/_redirects +++ /dev/null @@ -1 +0,0 @@ -/* /index.html 200 \ No newline at end of file diff --git a/packages/gaming-ui/public/android-chrome-192x192.png b/packages/gaming-ui/public/android-chrome-192x192.png deleted file mode 100644 index cfffdc4a82..0000000000 Binary files a/packages/gaming-ui/public/android-chrome-192x192.png and /dev/null differ diff --git a/packages/gaming-ui/public/android-chrome-512x512.png b/packages/gaming-ui/public/android-chrome-512x512.png deleted file mode 100644 index 300ed95cd2..0000000000 Binary files a/packages/gaming-ui/public/android-chrome-512x512.png and /dev/null differ diff --git a/packages/gaming-ui/public/apple-touch-icon.png b/packages/gaming-ui/public/apple-touch-icon.png deleted file mode 100644 index cfffdc4a82..0000000000 Binary files a/packages/gaming-ui/public/apple-touch-icon.png and /dev/null differ diff --git a/packages/gaming-ui/public/favicon-16x16.png b/packages/gaming-ui/public/favicon-16x16.png deleted file mode 100644 index c515dca67e..0000000000 Binary files a/packages/gaming-ui/public/favicon-16x16.png and /dev/null differ diff --git a/packages/gaming-ui/public/favicon-32x32.png b/packages/gaming-ui/public/favicon-32x32.png deleted file mode 100644 index ee6522854f..0000000000 Binary files a/packages/gaming-ui/public/favicon-32x32.png and /dev/null differ diff --git a/packages/gaming-ui/public/favicon.ico b/packages/gaming-ui/public/favicon.ico deleted file mode 100644 index 6333263689..0000000000 Binary files a/packages/gaming-ui/public/favicon.ico and /dev/null differ diff --git a/packages/gaming-ui/public/index.html b/packages/gaming-ui/public/index.html deleted file mode 100644 index a955172684..0000000000 --- a/packages/gaming-ui/public/index.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - ChainSafe Gaming - - - -
- - - diff --git a/packages/gaming-ui/public/manifest.json b/packages/gaming-ui/public/manifest.json deleted file mode 100644 index 5bb42011c2..0000000000 --- a/packages/gaming-ui/public/manifest.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "short_name": "Chainsafe Gaming", - "name": "Chainsafe Gaming", - "icons": [ - { - "src": "ChainSafe-logo.png", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/packages/gaming-ui/public/robots.txt b/packages/gaming-ui/public/robots.txt deleted file mode 100644 index e9e57dc4d4..0000000000 --- a/packages/gaming-ui/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/packages/gaming-ui/public/serviceworker/redirect.html b/packages/gaming-ui/public/serviceworker/redirect.html deleted file mode 100644 index 3ed34e79f7..0000000000 --- a/packages/gaming-ui/public/serviceworker/redirect.html +++ /dev/null @@ -1,316 +0,0 @@ - - - - - - - Redirect - - - - -
-
-
-
-
-
-

- You can close this window now -

-
- - - - diff --git a/packages/gaming-ui/public/serviceworker/sw.js b/packages/gaming-ui/public/serviceworker/sw.js deleted file mode 100644 index e49ffdfb2b..0000000000 --- a/packages/gaming-ui/public/serviceworker/sw.js +++ /dev/null @@ -1,312 +0,0 @@ -// This service worker handles all OAuth redirects and calls, as well as parsing -// tokens returned, parsing said tokens and communication with the DirectAuth SDK. -// For more information see https://github.com/torusresearch/torus-direct-web-sdk/blob/master/README.md -// and https://docs.tor.us/direct-auth/integrating-directauth - -/* eslint-disable */ -function getScope() { - return self.registration.scope; -} - -self.addEventListener("message", function (event) { - if (event.data && event.data.type === "SKIP_WAITING") { - self.skipWaiting(); - } -}); - -self.addEventListener("fetch", function (event) { - try { - const url = new URL(event.request.url); - if (url.pathname.includes("redirect") && url.href.includes(getScope())) { - event.respondWith( - new Response( - new Blob( - [ - ` - - - - - - - Redirect - - - -
-
-
-
-
-
-

You can close this window now

-
- - - - - -${""} - `, - ], - { type: "text/html" } - ) - ) - ); - } - } catch (error) { - console.error(error); - } -}); diff --git a/packages/gaming-ui/public/site.webmanifest b/packages/gaming-ui/public/site.webmanifest deleted file mode 100644 index d3f31c43ac..0000000000 --- a/packages/gaming-ui/public/site.webmanifest +++ /dev/null @@ -1,19 +0,0 @@ -{ - "short_name": "Chainsafe Gaming", - "name": "Chainsafe Gaming", - "icons": [ - { - "src": "/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "theme_color": "#ffffff", - "background_color": "#ffffff", - "display": "standalone" -} diff --git a/packages/gaming-ui/scripts/sentry.js b/packages/gaming-ui/scripts/sentry.js deleted file mode 100644 index efa38ef60a..0000000000 --- a/packages/gaming-ui/scripts/sentry.js +++ /dev/null @@ -1,37 +0,0 @@ -const SentryCli = require("@sentry/cli") -const dotenv = require("dotenv") -dotenv.config() - -async function createReleaseAndUpload() { - const release = process.env.REACT_APP_SENTRY_RELEASE - const environment = process.env.REACT_APP_SENTRY_ENV - - if (!release || !environment) { - console.warn("REACT_APP_SENTRY_RELEASE or REACT_APP_SENTRY_ENV is not set") - return - } - - const cli = new SentryCli() - - try { - console.log("Creating sentry release " + release) - await cli.releases.new(release) - - console.log("Uploading source maps") - await cli.releases.uploadSourceMaps(release, { - include: ["build/static/js"], - rewrite: true, - validate: true, - }) - - console.log("Finalizing release") - // await cli.releases.setCommits(release, {auto: true}) - await cli.releases.newDeploy(release, { env: environment }) - - await cli.releases.finalize(release) - } catch (e) { - console.error("Creating a release on Sentry failed.", e) - } -} - -createReleaseAndUpload() diff --git a/packages/gaming-ui/src/App.tsx b/packages/gaming-ui/src/App.tsx deleted file mode 100644 index ea78e7f068..0000000000 --- a/packages/gaming-ui/src/App.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import React, { useCallback } from "react" -import { init as initSentry, ErrorBoundary, showReportDialog } from "@sentry/react" -import { Web3Provider } from "@chainsafe/web3-context" -import { ThemeSwitcher } from "@chainsafe/common-theme" -import "@chainsafe/common-theme/dist/font-faces.css" -import { Button, CssBaseline, Modal, Router, ToastProvider, Typography } from "@chainsafe/common-components" -import StorageRoutes from "./Components/GamingRoutes" -import AppWrapper from "./Components/Layouts/AppWrapper" -import { LanguageProvider } from "./Contexts/LanguageContext" -import { lightTheme } from "./Themes/LightTheme" -import { darkTheme } from "./Themes/DarkTheme" -import { useLocalStorage } from "@chainsafe/browser-storage-hooks" -import { GamingApiProvider } from "./Contexts/GamingApiContext" -import { UserProvider } from "./Contexts/UserContext" - -if ( - process.env.NODE_ENV === "production" && - process.env.REACT_APP_SENTRY_DSN_URL -) { - initSentry({ - dsn: process.env.REACT_APP_SENTRY_DSN_URL, - release: process.env.REACT_APP_SENTRY_RELEASE, - environment: process.env.REACT_APP_SENTRY_ENV - }) -} - -const availableLanguages = [ - { id: "en", label: "English" } -] - -const onboardConfig = { - dappId: process.env.REACT_APP_BLOCKNATIVE_ID || "", - walletSelect: { - wallets: [ - { walletName: "coinbase" }, - { - walletName: "trust", - rpcUrl: - "https://mainnet.infura.io/v3/a7e16429d2254d488d396710084e2cd3" - }, - { walletName: "metamask", preferred: true }, - { walletName: "authereum" }, - { walletName: "opera" }, - { walletName: "operaTouch" }, - { walletName: "torus" }, - { walletName: "status" }, - { - walletName: "walletConnect", - infuraKey: "a7e16429d2254d488d396710084e2cd3", - preferred: true - } - ] - } -} - -const App = () => { - const { canUseLocalStorage } = useLocalStorage() - const apiUrl = process.env.REACT_APP_API_URL || "https://stage.imploy.site/api/v1" - // This will default to testnet unless mainnet is specifically set in the ENV - - const fallBack = useCallback(({ error, componentStack, eventId, resetError }) => ( - - - An error occurred and has been logged. If you would like to - provide additional info to help us debug and resolve the issue, - click the `"`Provide Additional Details`"` button - - {error?.message.toString()} - {componentStack} - {eventId} - - - - ), []) - - return ( - - window.location.reload()} - > - - - - - - - - - - - - - - - - - - - ) -} - -export default App diff --git a/packages/gaming-ui/src/Components/Elements/ApiKeyCard.tsx b/packages/gaming-ui/src/Components/Elements/ApiKeyCard.tsx deleted file mode 100644 index db489b7d8b..0000000000 --- a/packages/gaming-ui/src/Components/Elements/ApiKeyCard.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import React from "react" -import { AccessKey } from "@chainsafe/files-api-client" -import { makeStyles, createStyles } from "@chainsafe/common-theme" -import { CSGTheme } from "../../Themes/types" -import { Button, Typography, Paper } from "@chainsafe/common-components" -import { Trans } from "@lingui/macro" -import dayjs from "dayjs" - - -const useStyles = makeStyles(({ constants }: CSGTheme) => - createStyles({ - root: { - position: "relative", - margin: constants.generalUnit, - borderRadius: constants.generalUnit / 2, - maxWidth: 250, - padding: `${constants.generalUnit * 2}px ${constants.generalUnit}px` - }, - button: { - marginTop: constants.generalUnit * 2 - } - }) -) - -interface IApiKeyCard { - apiKey: AccessKey - deleteKey: () => void -} - -const ApiKeyCard = ({ apiKey, deleteKey }: IApiKeyCard) => { - const classes = useStyles() - - return ( - - - - Id: - - - - { apiKey.id } - - - - Status: - - - - { apiKey.status } - - - - Created on: - - - - { dayjs(apiKey.created_at).format("DD MMM YYYY h:mm a") } - - - - ) -} - -export default ApiKeyCard \ No newline at end of file diff --git a/packages/gaming-ui/src/Components/Elements/CustomButton.tsx b/packages/gaming-ui/src/Components/Elements/CustomButton.tsx deleted file mode 100644 index 3d9de50746..0000000000 --- a/packages/gaming-ui/src/Components/Elements/CustomButton.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { Button, IButtonProps } from "@chainsafe/common-components" -import { createStyles, ITheme, makeStyles } from "@chainsafe/common-theme" -import React, { ReactNode } from "react" -import clsx from "clsx" - -const useStyles = makeStyles(({ palette }: ITheme) => - createStyles({ - root: { - "&.gray": { - backgroundColor: palette.additional["gray"][3], - color: palette.additional["gray"][9] - } - } - }) -) - -const CUSTOM_VARIANTS = ["gray"] - -const temp = [...CUSTOM_VARIANTS] -type customVariant = typeof temp[0] - -type buttonVariant = IButtonProps["variant"] | customVariant - -interface ICustomButton extends Omit { - children: ReactNode - variant?: buttonVariant - className?: string -} - -const CustomButton: React.FC = ({ - className, - children, - variant, - ...rest -}: ICustomButton) => { - const classes = useStyles() - - const setVariant = - variant && CUSTOM_VARIANTS.includes(variant) - ? "primary" - : variant || "primary" - - return ( - - ) -} - -export default CustomButton diff --git a/packages/gaming-ui/src/Components/Elements/CustomModal.tsx b/packages/gaming-ui/src/Components/Elements/CustomModal.tsx deleted file mode 100644 index 224b120ab3..0000000000 --- a/packages/gaming-ui/src/Components/Elements/CustomModal.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { IModalProps, Modal } from "@chainsafe/common-components" -import { createStyles, makeStyles } from "@chainsafe/common-theme" -import React, { ReactNode } from "react" -import clsx from "clsx" -import { CSGTheme } from "../../Themes/types" - -const useStyles = makeStyles(({ constants, breakpoints }: CSGTheme) => - createStyles({ - root: { - "&:before": { - backgroundColor: constants.modalDefault.fadeBackground - } - }, - inner: { - [breakpoints.down("md")]: { - backgroundColor: constants.modalDefault.background, - top: "unset", - bottom: 0, - left: 0, - width: "100% !important", - transform: "unset", - borderRadiusLeftTop: `${constants.generalUnit * 1.5}px`, - borderRadiusRightTop: `${constants.generalUnit * 1.5}px`, - borderRadiusLeftBottom: 0, - borderRadiusRightBottom: 0 - } - }, - closeIcon: { - [breakpoints.down("md")]: {} - } - }) -) - -interface ICustomModal extends IModalProps { - children: ReactNode - className?: string -} - -const CustomModal: React.FC = ({ - className, - children, - injectedClass, - ...rest -}: ICustomModal) => { - const classes = useStyles() - - return ( - - {children} - - ) -} - -export default CustomModal diff --git a/packages/gaming-ui/src/Components/Elements/SecretField.tsx b/packages/gaming-ui/src/Components/Elements/SecretField.tsx deleted file mode 100644 index ba059aa666..0000000000 --- a/packages/gaming-ui/src/Components/Elements/SecretField.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React, { useCallback, useState } from "react" -import { EyeOpenIcon, EyeClosedIcon, Typography } from "@chainsafe/common-components" -import { makeStyles, createStyles } from "@chainsafe/common-theme" - -interface Props { - value: string -} - -const useStyles = makeStyles(() => - createStyles({ - root: { - display: "flex", - justifyContent: "space-between" - } - }) -) - -const SecretField = ({ value }: Props) => { - const [showValue, setShowValue] = useState(false) - const classes = useStyles() - - const toggleShowValue = useCallback(() => { - setShowValue(!showValue) - }, [showValue]) - - return ( -
- {showValue ? value : "⚫⚫⚫⚫⚫⚫⚫⚫⚫" } - {showValue ? : } -
- ) -} - -export default SecretField \ No newline at end of file diff --git a/packages/gaming-ui/src/Components/GamingRoutes.tsx b/packages/gaming-ui/src/Components/GamingRoutes.tsx deleted file mode 100644 index c8fb48f479..0000000000 --- a/packages/gaming-ui/src/Components/GamingRoutes.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import React from "react" -import { Switch, ConditionalRoute } from "@chainsafe/common-components" -import LoginPage from "./Pages/LoginPage" -import { useGamingApi } from "../Contexts/GamingApiContext" -import SettingsPage from "./Pages/SettingsPage" -import DashboardPage from "./Pages/DashboardPage" - -export const SETTINGS_PATHS = ["apiKeys", "billing"] as const -export type SettingsPath = typeof SETTINGS_PATHS[number] - -export const ROUTE_LINKS = { - Landing: "/", - Dashboard: "/dashboard", - SettingsRoot: "/settings", - Settings: (path: SettingsPath) => `/settings/${path}`, - PrivacyPolicy: "https://files.chainsafe.io/privacy-policy", - Terms: "https://files.chainsafe.io/terms-of-service", - ChainSafe: "https://chainsafe.io/", - Billing: "/billing", - Products: "/products" -} - -const GamingRoutes = () => { - const { isLoggedIn } = useGamingApi() - - return ( - - - - - - ) -} - -export default GamingRoutes diff --git a/packages/gaming-ui/src/Components/Layouts/AppHeader.tsx b/packages/gaming-ui/src/Components/Layouts/AppHeader.tsx deleted file mode 100644 index 45ed28b61a..0000000000 --- a/packages/gaming-ui/src/Components/Layouts/AppHeader.tsx +++ /dev/null @@ -1,232 +0,0 @@ -import React, { useCallback } from "react" -import { createStyles, makeStyles, useThemeSwitcher } from "@chainsafe/common-theme" -import clsx from "clsx" -import { - Link, - Typography, - ChainsafeLogo, - HamburgerMenu, - MenuDropdown, - PowerDownSvg, - useHistory -} from "@chainsafe/common-components" -import { ROUTE_LINKS } from "../GamingRoutes" -import { Trans } from "@lingui/macro" -import { CSGTheme } from "../../Themes/types" -import { useGamingApi } from "../../Contexts/GamingApiContext" -import { useUser } from "../../Contexts/UserContext" - -const useStyles = makeStyles( - ({ palette, animation, breakpoints, constants, zIndex }: CSGTheme) => { - return createStyles({ - root: { - position: "fixed", - display: "flex", - flexDirection: "row", - top: 0, - transitionDuration: `${animation.translate}ms`, - visibility: "hidden", - [breakpoints.up("md")]: { - width: `calc(100% - ${constants.navWidth}px)`, - padding: `${0}px ${constants.contentPadding}px ${0}px ${ - constants.contentPadding - }px`, - left: Number(constants.navWidth), - opacity: 0, - - backgroundColor: constants.header.rootBackground, - - "& > *:first-child": { - flex: "1 1 0" - }, - "&.active": { - opacity: 1, - height: "auto", - visibility: "visible", - padding: `${constants.headerTopPadding}px ${ - constants.contentPadding - }px ${0}px ${constants.contentPadding}px`, - zIndex: zIndex?.layer1 - } - }, - [breakpoints.down("md")]: { - left: 0, - width: "100%", - justifyContent: "space-between", - alignItems: "center", - position: "fixed", - backgroundColor: palette.additional["gray"][3], - "&.active": { - opacity: 1, - visibility: "visible", - height: Number(constants.mobileHeaderHeight), - zIndex: Number(zIndex?.layer1) - } - } - }, - hamburgerMenu: { - position: "absolute", - "& span": { - backgroundColor: constants.header.hamburger - } - }, - logo: { - textDecoration: "none", - display: "flex", - flexDirection: "row", - alignItems: "center", - [breakpoints.up("md")]: { - "& img": { - height: constants.generalUnit * 5, - width: "auto" - } - }, - [breakpoints.down("md")]: { - position: "absolute", - left: "50%", - top: "50%", - transform: "translate(-50%,-50%)", - "& img": { - height: constants.generalUnit * 3.25, - width: "auto" - } - } - }, - accountControls: { - display: "flex", - justifyContent: "flex-end", - alignItems: "center", - flexDirection: "row", - [breakpoints.up("md")]: { - marginLeft: constants.accountControlsPadding - }, - "& > *:first-child": { - marginRight: constants.generalUnit * 2 - } - }, - searchModule: { - [breakpoints.down("md")]: { - height: constants.mobileHeaderHeight, - position: "absolute", - width: "100%", - zIndex: zIndex?.background, - "&.active": {} - } - }, - options: { - backgroundColor: constants.header.optionsBackground, - color: constants.header.optionsTextColor, - border: `1px solid ${constants.header.optionsBorder}`, - minWidth: 145 - }, - menuItem: { - width: "100%", - display: "flex", - flexDirection: "row", - alignItems: "center", - color: constants.header.menuItemTextColor, - "& svg": { - width: constants.generalUnit * 2, - height: constants.generalUnit * 2, - marginRight: constants.generalUnit, - fill: palette.additional["gray"][7], - stroke: palette.additional["gray"][7] - } - }, - icon: { - "& svg": { - fill: constants.header.iconColor - } - }, - title : { - marginLeft: constants.generalUnit - } - }) - } -) - -interface IAppHeader { - navOpen: boolean - setNavOpen: (state: boolean) => void -} - -const AppHeader = ({ navOpen, setNavOpen }: IAppHeader) => { - const { desktop } = useThemeSwitcher() - const classes = useStyles() - const { isLoggedIn, logout } = useGamingApi() - const { history } = useHistory() - const { getProfileTitle } = useUser() - - const signOut = useCallback(async () => { - logout() - history.replace("/", {}) - }, [logout, history]) - - return ( -
- {isLoggedIn && ( - <> - {desktop ? ( - <> -
- signOut(), - contents: ( -
- - - Sign Out - -
- ) - } - ]} - /> -
- - ) : ( - <> - setNavOpen(!navOpen)} - variant={navOpen ? "active" : "default"} - className={clsx(classes.hamburgerMenu, "hamburger-menu")} - testId="hamburger-menu" - /> - - - - Dashboard - - - - )} - - )} -
- ) -} - -export default AppHeader diff --git a/packages/gaming-ui/src/Components/Layouts/AppNav.tsx b/packages/gaming-ui/src/Components/Layouts/AppNav.tsx deleted file mode 100644 index 7746860bf1..0000000000 --- a/packages/gaming-ui/src/Components/Layouts/AppNav.tsx +++ /dev/null @@ -1,272 +0,0 @@ -import { - createStyles, - makeStyles, - useThemeSwitcher -} from "@chainsafe/common-theme" -import React, { useCallback } from "react" -import clsx from "clsx" -import { - Link, - Typography, - PowerDownSvg, - ChainsafeLogo -} from "@chainsafe/common-components" -import { ROUTE_LINKS } from "../GamingRoutes" -import { Trans } from "@lingui/macro" -import { CSGTheme } from "../../Themes/types" -import { useGamingApi } from "../../Contexts/GamingApiContext" - -const useStyles = makeStyles( - ({ palette, animation, breakpoints, constants, zIndex }: CSGTheme) => { - return createStyles({ - root: { - width: 0, - overflow: "hidden", - transitionDuration: `${animation.translate}ms`, - display: "flex", - flexDirection: "column", - position: "fixed", - left: 0, - opacity: 0, - "&.active": { - opacity: 1 - }, - [breakpoints.up("md")]: { - padding: `${constants.topPadding}px ${ - constants.generalUnit * 4.5 - }px`, - top: 0, - height: "100%", - backgroundColor: constants.nav.backgroundColor, - "&.active": { - width: `${constants.navWidth}px` - } - }, - [breakpoints.down("md")]: { - height: `calc(100% - ${constants.mobileHeaderHeight}px)`, - top: `${constants.mobileHeaderHeight}px`, - backgroundColor: constants.nav.mobileBackgroundColor, - zIndex: zIndex?.layer1, - padding: `0 ${constants.generalUnit * 4}px`, - maxWidth: "100vw", - visibility: "hidden", - "&.active": { - visibility: "visible", - width: `${constants.mobileNavWidth}px` - } - } - }, - blocker: { - display: "block", - backgroundColor: constants.nav.blocker, - position: "fixed", - top: Number(constants.mobileHeaderHeight), - left: 0, - height: `calc(100% - ${constants.mobileHeaderHeight}px)`, - width: "100%", - transitionDuration: `${animation.translate}ms`, - zIndex: zIndex?.background, - opacity: 0, - visibility: "hidden", - "&.active": { - visibility: "visible", - [breakpoints.down("md")]: { - opacity: 0.5 - } - } - }, - logo: { - textDecoration: "none", - display: "flex", - flexDirection: "row", - alignItems: "center", - - [breakpoints.up("md")]: { - "& img": { - height: constants.generalUnit * 5, - width: "auto" - }, - "& > *:first-child": { - marginRight: constants.generalUnit - } - }, - [breakpoints.down("md")]: { - position: "absolute", - left: "50%", - top: "50%", - transform: "translate(-50%,-50%)", - "& img": { - height: constants.generalUnit * 3.25, - width: "auto" - } - } - }, - navMenu: { - display: "flex", - flexDirection: "column", - marginBottom: constants.generalUnit * 8.5, - transitionDuration: `${animation.translate}ms` - }, - linksArea: { - display: "flex", - flexDirection: "column", - flex: "1 1 0", - justifyContent: "center", - transitionDuration: `${animation.translate}ms`, - "& > span": { - marginBottom: constants.generalUnit * 2 - }, - [breakpoints.up("md")]: { - height: 0 - }, - [breakpoints.down("md")]: { - transitionDuration: `${animation.translate}ms`, - color: palette.additional["gray"][3], - "&.active": {} - } - }, - navItem: { - textDecoration: "none", - display: "flex", - flexDirection: "row", - alignItems: "center", - cursor: "pointer", - padding: `${constants.generalUnit * 1.5}px 0`, - transitionDuration: `${animation.transform}ms`, - "& span": { - transitionDuration: `${animation.transform}ms`, - [breakpoints.up("md")]: { - color: constants.nav.itemColor - }, - [breakpoints.down("md")]: { - color: constants.nav.itemColorHover - } - }, - "& svg": { - transitionDuration: `${animation.transform}ms`, - width: Number(constants.svgWidth), - marginRight: constants.generalUnit * 2, - [breakpoints.up("md")]: { - fill: constants.nav.itemIconColor - }, - [breakpoints.down("md")]: { - fill: constants.nav.itemIconColorHover - } - }, - "&:hover": { - "& span": { - color: constants.nav.itemColorHover - }, - "& svg": { - fill: constants.nav.itemIconColorHover - } - }, - [breakpoints.down("md")]: { - minWidth: Number(constants.mobileNavWidth) - } - }, - navItemText: { - [breakpoints.down("md")]: { - color: palette.additional["gray"][3] - } - }, - menuItem: { - width: 100, - display: "flex", - flexDirection: "row", - alignItems: "center", - "& svg": { - width: constants.generalUnit * 2, - height: constants.generalUnit * 2, - marginRight: constants.generalUnit - } - }, - spaceUsedMargin: { - marginBottom: constants.generalUnit - }, - betaCaption: { - marginBottom: constants.generalUnit * 0.5 - } - }) - } -) - -interface IAppNav { - navOpen: boolean - setNavOpen: (state: boolean) => void -} - -const AppNav: React.FC = ({ navOpen, setNavOpen }: IAppNav) => { - const { desktop } = useThemeSwitcher() - const classes = useStyles() - - const { isLoggedIn, logout } = useGamingApi() - - const signOut = useCallback(() => { - logout() - }, [logout]) - - const handleOnClick = useCallback(() => { - if (!desktop && navOpen) { - setNavOpen(false) - } - }, [desktop, navOpen, setNavOpen]) - - return ( -
- {isLoggedIn && ( - <> - {desktop && ( -
- - - - Gaming - - -
- )} -
- -
-
- {!desktop && ( -
{ - handleOnClick() - signOut() - }} - > - - - Sign Out - -
- )} -
- {!desktop && ( -
setNavOpen(false)} - className={clsx(classes.blocker, { - active: navOpen - })} - >
- )} - - )} -
- ) -} - -export default AppNav \ No newline at end of file diff --git a/packages/gaming-ui/src/Components/Layouts/AppWrapper.tsx b/packages/gaming-ui/src/Components/Layouts/AppWrapper.tsx deleted file mode 100644 index e09654b091..0000000000 --- a/packages/gaming-ui/src/Components/Layouts/AppWrapper.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { createStyles, ITheme, makeStyles } from "@chainsafe/common-theme" -import React, { useState } from "react" -import { ReactNode } from "react" -import clsx from "clsx" -import { useGamingApi } from "../../Contexts/GamingApiContext" -import { CssBaseline } from "@chainsafe/common-components" -import AppHeader from "./AppHeader" -import AppNav from "./AppNav" - -interface IAppWrapper { - children: ReactNode | ReactNode[] -} - -const useStyles = makeStyles( - ({ animation, breakpoints, constants }: ITheme) => { - return createStyles({ - root: { - minHeight: "100vh" - }, - bodyWrapper: { - transitionDuration: `${animation.translate}ms`, - [breakpoints.up("md")]: { - padding: "0", - "&.active": { - // This moves the content areas based on the size of the nav bar - - padding: `${0}px ${constants.contentPadding}px ${0}px ${ - Number(constants.navWidth) + - Number(constants.contentPadding) - }px` - } - }, - [breakpoints.down("md")]: {} - }, - content: { - minHeight: "100vh", - [breakpoints.up("md")]: { - height: "100%", - transitionDuration: `${animation.translate}ms`, - padding: 0, - "&.active": { - height: "initial", - padding: `${constants.contentTopPadding}px 0 0` - } - }, - [breakpoints.down("md")]: { - "&.active": { - height: "initial", - padding: `${constants.mobileHeaderHeight}px 0 0` - } - } - } - }) - } -) - -const AppWrapper: React.FC = ({ children }: IAppWrapper) => { - const classes = useStyles() - const [navOpen, setNavOpen] = useState(false) - const { isLoggedIn } = useGamingApi() - - return ( -
- - -
- -
- {children} -
-
-
- ) -} - -export default AppWrapper diff --git a/packages/gaming-ui/src/Components/Modules/DashboardModule.tsx b/packages/gaming-ui/src/Components/Modules/DashboardModule.tsx deleted file mode 100644 index 7d75feb1b8..0000000000 --- a/packages/gaming-ui/src/Components/Modules/DashboardModule.tsx +++ /dev/null @@ -1,263 +0,0 @@ -import { Button, CopyIcon, Modal, PlusIcon, Typography } from "@chainsafe/common-components" -import { createStyles, debounce, makeStyles } from "@chainsafe/common-theme" -import { AccessKey } from "@chainsafe/files-api-client" -import { Trans } from "@lingui/macro" -import React, { useCallback, useEffect, useState } from "react" -import { useGamingApi } from "../../Contexts/GamingApiContext" -import { CSGTheme } from "../../Themes/types" -import ApiKeyCard from "../Elements/ApiKeyCard" - -const useStyles = makeStyles(({ breakpoints, constants, palette, zIndex }: CSGTheme) => - createStyles({ - root: { - position: "relative", - margin: constants.generalUnit - }, - header: { - display: "flex", - flexDirection: "row", - justifyContent: "space-between", - alignItems: "center", - [breakpoints.down("md")]: { - marginTop: constants.generalUnit - } - }, - controls: { - display: "flex", - flexDirection: "row", - justifyContent: "space-between", - alignItems: "center", - "& > button": { - marginLeft: constants.generalUnit - } - }, - dataArea: { - marginTop: constants.generalUnit * 2, - display: "flex", - flexDirection: "row", - justifyContent: "space-between", - flexWrap: "wrap", - "& > *": { - margin: constants.generalUnit, - width:"100%", - [breakpoints.up("xs")]: { - maxWidth: `calc(100% - ${constants.generalUnit * 2}px)` - }, - [breakpoints.up("sm")]: { - maxWidth: `calc(50% - ${constants.generalUnit * 2}px)` - }, - [breakpoints.up("md")]: { - maxWidth: `calc(33% - ${constants.generalUnit * 2}px)` - }, - [breakpoints.up("lg")]: { - maxWidth: `calc(25% - ${constants.generalUnit * 2}px)` - }, - [breakpoints.up("xl")]: { - maxWidth: `calc(20% - ${constants.generalUnit * 2}px)` - } - } - }, - modalRoot: { - zIndex: zIndex?.blocker, - [breakpoints.down("md")]: {} - }, - modalInner: { - [breakpoints.down("md")]: { - bottom: - Number(constants?.mobileButtonHeight) + constants.generalUnit, - borderTopLeftRadius: `${constants.generalUnit * 1.5}px`, - borderTopRightRadius: `${constants.generalUnit * 1.5}px`, - maxWidth: `${breakpoints.width("md")}px !important` - } - }, - modalHeading: { - textAlign: "center", - marginBottom: constants.generalUnit * 4 - }, - modalContent: { - display: "flex", - flexDirection: "column", - padding: constants.generalUnit * 4 - }, - secretContainer: { - display: "flex", - justifyContent: "space-between", - marginBottom: constants.generalUnit * 0.5 - }, - copyBox: { - display: "flex", - justifyContent: "space-between", - alignItems: "center", - cursor: "pointer", - color: palette.text.secondary - }, - copyIcon: { - fontSize: "14px", - fill: constants.profile.icon, - [breakpoints.down("md")]: { - fontSize: "18px", - fill: palette.additional["gray"][9] - } - }, - secret: { - maxWidth: "95%", - overflowWrap: "anywhere" - }, - field: { - marginBottom: constants.generalUnit * 4 - } - }) -) - -const DashboardModule = () => { - const classes = useStyles() - const { gamingApiClient } = useGamingApi() - const [keys, setKeys] = useState([]) - const [newKey, setNewKey] = useState() - const [isNewKeyModalOpen, setIsNewKeyModalOpen] = useState(false) - const [copiedSecret, setCopiedSecret] = useState(false) - const debouncedCopiedSecret = - debounce(() => setCopiedSecret(false), 3000) - - const copySecret = async () => { - if (newKey?.secret) { - try { - await navigator.clipboard.writeText(newKey.secret) - setCopiedSecret(true) - debouncedCopiedSecret() - } catch (err) { - console.error(err) - } - } - } - - const fetchAccessKeys = useCallback(() => { - gamingApiClient.listAccessKeys() - .then(keys => setKeys(keys.filter(key => key.type === "gaming"))) - .catch(console.error) - }, [gamingApiClient]) - - const createGamingAccessKey = useCallback(() => { - gamingApiClient.createAccessKey({ type: "gaming" }) - .then((key) => { - setNewKey(key) - fetchAccessKeys() - setIsNewKeyModalOpen(true) - }) - .catch(console.error) - }, [fetchAccessKeys, gamingApiClient]) - - const deleteAccessKey = useCallback((id: string) => { - gamingApiClient.deleteAccessKey(id) - .then(fetchAccessKeys) - .catch(console.error) - }, [gamingApiClient, fetchAccessKeys]) - - useEffect(() => { - fetchAccessKeys() - }, [fetchAccessKeys]) - - return ( - <> -
-
- - - Dashboard - - -
- -
-
-
- { - keys.map((key: AccessKey, index: number) => ( - deleteAccessKey(key.id)} - apiKey={key} />)) - } -
-
- -
- - New Key - - - Key ID - - {newKey?.id} - - Secret - -
-
- - Make sure to save the secret, as it can only be displayed once. - - {copiedSecret && ( - - Copied! - - )} -
-
- - {newKey?.secret} - - -
-
- -
-
- - ) -} - -export default DashboardModule \ No newline at end of file diff --git a/packages/gaming-ui/src/Components/Modules/Login/PasswordlessEmail.tsx b/packages/gaming-ui/src/Components/Modules/Login/PasswordlessEmail.tsx deleted file mode 100644 index 1324dd781f..0000000000 --- a/packages/gaming-ui/src/Components/Modules/Login/PasswordlessEmail.tsx +++ /dev/null @@ -1,296 +0,0 @@ -import React, { useState, useCallback, useMemo } from "react" -import { createStyles, makeStyles } from "@chainsafe/common-theme" -import { CSGTheme } from "../../../Themes/types" -import { Button, Emoji, FormikTextInput, Typography } from "@chainsafe/common-components" -import { Trans, t } from "@lingui/macro" -import clsx from "clsx" -import { Form, Formik } from "formik" -import * as yup from "yup" -import { useGamingApi } from "../../../Contexts/GamingApiContext" - -const useStyles = makeStyles(({ palette, breakpoints, constants }: CSGTheme) => - createStyles({ - root: { - width: "100vw", - [breakpoints.up("md")]: { - padding: `${constants.generalUnit * 4}px ${constants.generalUnit * 15}px`, - maxWidth: 580 - }, - [breakpoints.down("md")]: { - padding: `${constants.generalUnit * 2}px ${constants.generalUnit * 3}px` - } - }, - headerText: { - textAlign: "center", - [breakpoints.up("md")]: { - paddingBottom: constants.generalUnit * 4 - }, - [breakpoints.down("md")]: { - paddingBottom: constants.generalUnit * 3 - } - }, - input: { - margin: 0, - width: "100%", - marginBottom: constants.generalUnit - }, - inputLabel: { - fontSize: "16px", - lineHeight: "24px", - marginBottom: constants.generalUnit - }, - button: { - [breakpoints.up("md")]: { - marginTop: constants.generalUnit - }, - [breakpoints.down("md")]: { - marginTop: constants.generalUnit - } - }, - buttonLink: { - color: palette.additional["gray"][10], - outline: "none", - textDecoration: "underline", - cursor: "pointer", - textAlign: "center", - marginTop: constants.generalUnit * 2, - "&.disabled": { - color: palette.additional["gray"][7] - }, - "&.spaceLeft": { - marginLeft: constants.generalUnit * 0.5 - } - }, - title: { - textAlign: "center" - }, - subtitle: { - textAlign: "center", - paddingTop: constants.generalUnit * 4, - paddingBottom: constants.generalUnit * 4 - }, - resendText: { - textAlign: "center", - marginTop: constants.generalUnit * 4 - }, - errorText: { - textAlign: "center", - color: palette.error.main - } - }) -) - -interface IPasswordlessEmail { - resetLogin: () => void -} - -const PasswordlessEmail = ({ resetLogin }: IPasswordlessEmail) => { - const classes = useStyles() - const [isSubmitEmailLoading, setIsSubmitEmailLoading] = useState(false) - const [isSubmitResendEmailLoading, setIsSubmitResendEmailLoading] = useState(false) - const [isSubmitNonceLoading, setIsSubmitNonceLoading] = useState(false) - const [page, setPage] = useState<"confirmEmail" | "confirmVerificationCode">("confirmEmail") - const [email, setEmail] = useState() - const { gamingApiClient, login } = useGamingApi() - const [hasEmailResent, setHasEmailResent] = useState(false) - const [error, setError] = useState() - - const emailValidation = useMemo(() => yup.object().shape({ - email: yup - .string() - .email(t`Please enter a valid email`) - .required(t`Email is required`) - }) - , []) - - const nonceValidation = useMemo(() => yup.object().shape({ - nonce: yup - .string() - .required(t`Verification code is required`) - }) - , []) - - const onSubmitEmail = useCallback((values) => { - setIsSubmitEmailLoading(true) - setError(undefined) - gamingApiClient.getIdentityEmailToken({ email: values.email }) - .then(() => { - setEmail(values.email) - setPage("confirmVerificationCode") - }).catch ((e) => { - setError(t`Something went wrong! Please try again.`) - console.error(e) - }).finally (() => setIsSubmitEmailLoading(false)) - }, [gamingApiClient]) - - const onSubmitNonce = useCallback((values) => { - if (!email) return - setIsSubmitNonceLoading(true) - setError(undefined) - gamingApiClient.postIdentityEmailToken({ - email: email, - nonce: values.nonce - }).then(async (data) => { - await login("email", { token: data || "", email }) - }).catch ((e) => { - if (e && e[0] && e[0].type === "nonce") { - setError(t`Verification code not correct!`) - } else { - setError(t`Something went wrong!`) - } - console.error(e) - }).finally(() => setIsSubmitNonceLoading(false)) - }, [gamingApiClient, email, login]) - - const onResendEmail = useCallback(() => { - if (!email) return - setIsSubmitResendEmailLoading(true) - gamingApiClient.getIdentityEmailToken({ email }) - .then(() => setHasEmailResent(true)) - .catch(console.error) - .finally(() => setIsSubmitResendEmailLoading(false)) - }, [gamingApiClient, email]) - - return ( -
- - - Sign in - - - {page === "confirmEmail" - ? -
- - {error && ( - - {error} - - )} - - -
- : <> - -
- - Verification code sent! - - - We’ve sent an email to {email}. It contains a verification code that’ll sign you in super quickly! - - - {error && ( - - {error} - - )} - - -
- - {!hasEmailResent - ? - - - Didn't receive the email ? - - - - - Send another email - - - - : - - - Check your inbox! We've sent another email. - - - - } - - } -
- Go back -
-
- ) -} - -export default PasswordlessEmail diff --git a/packages/gaming-ui/src/Components/Modules/Login/index.tsx b/packages/gaming-ui/src/Components/Modules/Login/index.tsx deleted file mode 100644 index c614f1780c..0000000000 --- a/packages/gaming-ui/src/Components/Modules/Login/index.tsx +++ /dev/null @@ -1,436 +0,0 @@ -import React, { useState } from "react" -import { Button, GithubLogoIcon, GoogleLogoIcon, Loading, MailIcon, Typography } from "@chainsafe/common-components" -import { createStyles, makeStyles, useThemeSwitcher } from "@chainsafe/common-theme" -import { CSGTheme } from "../../../Themes/types" -import { t, Trans } from "@lingui/macro" -import { useGamingApi } from "../../../Contexts/GamingApiContext" -import { useWeb3 } from "@chainsafe/web3-context" -import { ROUTE_LINKS } from "../../GamingRoutes" -import clsx from "clsx" -import { IdentityProvider } from "@chainsafe/files-api-client" -import PasswordlessEmail from "./PasswordlessEmail" - -const useStyles = makeStyles( - ({ constants, palette, breakpoints, typography }: CSGTheme) => - createStyles({ - root: { - backgroundColor: constants.loginModule.background, - border: `1px solid ${constants.landing.border}`, - boxShadow: constants.landing.boxShadow, - alignItems: "center", - borderRadius: 6, - [breakpoints.up("md")]:{ - minHeight: "64vh", - justifyContent: "space-between", - width: 440 - }, - [breakpoints.down("md")]: { - padding: `${constants.generalUnit * 4}px ${constants.generalUnit * 2}px`, - justifyContent: "center", - width: `calc(100vw - ${constants.generalUnit * 2}px)` - } - }, - buttonSection: { - [breakpoints.up("md")]: { - position: "absolute", - top: "50%", - left: "50%", - transform: "translate(-50%, -50%)" - }, - [breakpoints.down("md")]: { - display: "flex", - flexDirection: "column", - justifyContent: "space-evenly" - } - }, - connectingWallet: { - textAlign: "center", - alignItems: "center", - display: "flex", - flexDirection: "column", - "& > *": { - fontWeight: 400 - }, - [breakpoints.up("md")]: { - padding: `${constants.generalUnit * 30}px ${constants.generalUnit * 8}px`, - "& > *": { - paddingBottom: `${constants.generalUnit * 5}px` - } - }, - [breakpoints.down("md")]: { - justifyContent: "space-evenly" - } - }, - button: { - width: 240, - fontWeight: typography.fontWeight.medium, - marginBottom: constants.generalUnit * 2, - "& .icon" : { - fontSize: 25 - }, - "&:last-child": { - marginBottom: 0 - } - }, - error: { - color: palette.error.main, - paddingBottom: constants.generalUnit * 2, - maxWidth: 240 - }, - headerText: { - [breakpoints.up("md")]: { - paddingTop: constants.generalUnit * 4, - paddingBottom: constants.generalUnit * 8 - }, - [breakpoints.down("md")]: { - paddingTop: constants.generalUnit * 3, - paddingBottom: constants.generalUnit * 3, - textAlign: "center" - } - }, - footer: { - backgroundColor: constants.landing.footerBg, - color: constants.landing.footerText, - padding: `${constants.generalUnit * 2.5}px ${constants.generalUnit * 1.5}px`, - width: "100%", - "& > *": { - marginRight: constants.generalUnit * 3.5 - }, - [breakpoints.down("md")]: { - display: "none" - } - }, - connectWalletFooter: { - backgroundColor: constants.landing.background, - color: constants.landing.footerText, - padding: `${constants.generalUnit * 4.375}px ${constants.generalUnit * 7}px`, - width: "100%", - textAlign: "center", - "& > *": { - fontWeight: 400 - }, - [breakpoints.down("md")]: { - display: "none" - } - }, - loader: { - marginTop: constants.generalUnit, - padding: 0 - }, - buttonLink: { - color: palette.additional["gray"][10], - outline: "none", - textDecoration: "underline", - cursor: "pointer", - textAlign: "center" - }, - web3Button: { - minHeight: 41 - } - }) -) - -interface IInitialScreen { - className?: string -} - -const LoginModule = ({ className }: IInitialScreen) => { - const { selectWallet, resetAndSelectWallet, login, resetStatus, status } = useGamingApi() - const { desktop } = useThemeSwitcher() - const { wallet } = useWeb3() - const classes = useStyles() - const [loginMode, setLoginMode] = useState() - const [error, setError] = useState() - const maintenanceMode = process.env.REACT_APP_MAINTENANCE_MODE === "true" - const [isConnecting, setIsConnecting] = useState(false) - - const handleSelectWalletAndConnect = async () => { - setError(undefined) - try { - await selectWallet() - } catch (error) { - setError(t`There was an error connecting your wallet`) - } - } - - const handleResetAndSelectWallet = async () => { - setError(undefined) - try { - await resetAndSelectWallet() - } catch (error) { - setError(t`There was an error connecting your wallet`) - } - } - - const resetLogin = async () => { - setError(undefined) - setLoginMode(undefined) - resetStatus() - } - - const handleLogin = async (loginType: IdentityProvider) => { - setError("") - setIsConnecting(true) - setLoginMode(loginType) - try { - await login(loginType) - } catch (error) { - let errorMessage = t`There was an error authenticating` - console.log(error) - if (Array.isArray(error) && error[0]) { - if ( - error[0].type === "signature" && - error[0].message === "Invalid signature" - ) { - errorMessage = t`Failed to validate signature. - If you are using a contract wallet, please make - sure you have activated your wallet.` - } - } - // WalletConnect be sassy - if (error?.message === "Just nope" || error?.code === 4001) { - errorMessage = t`Failed to get signature` - } - if (error?.message === "user closed popup") { - errorMessage = t`The authentication popup was closed` - } - setError(errorMessage) - } - setIsConnecting(false) - } - - const ConnectWallet = () => { - if (!wallet) { - console.error("No wallet found") - return null - } - - return ( -
-
- - -
- - Go back - -
-
-
-
- )} - - const WalletConnection = () => { - return ( -
- Connect Wallet to Gaming - {status === "awaiting confirmation" && - - You will need to sign a message in your wallet to complete sign in. - } - {status === "logging in" && <> - - Hold on, we are logging you in… - - - } -
- ) - } - - const WalletSelection = () => { - return ( - <> -
- - -
-