From fec2c97dbfd203aa7892b86edafe1547d4ef7713 Mon Sep 17 00:00:00 2001 From: hubert-deriv <80688204+hubert-deriv@users.noreply.github.com> Date: Thu, 17 Nov 2022 10:55:15 +0100 Subject: [PATCH] hubert / Running husky prettier (#271) --- .eslintignore | 3 + .eslintrc.js | 209 +++--- .husky/pre-commit | 4 + .prettierignore | 13 +- README.md | 7 +- cypress/e2e/api.deriv.com.cy.js | 30 +- cypress/fixtures/example.json | 6 +- package.json | 3 +- .../api-guide/ApiGuide/ApiGuide.jsx | 196 +++-- .../ApiGuide/ApiGuideTable/ApiGuideTable.jsx | 354 ++++----- .../DerivGuideContent/DerivGuideContent.tsx | 697 ++++++++---------- .../AppManagement/AppManagement.jsx | 284 ++++--- .../AppManagementEmpty/AppManagementEmpty.jsx | 33 +- .../AppManagementEmptyLazy.jsx | 33 +- .../AppManagement/AppManagementLazy.jsx | 30 +- .../AppRegistrationForm.tsx | 16 +- .../DeleteAppDialog/DeleteAppDialog.jsx | 56 +- .../RegisterAppDialogError.tsx | 62 +- .../AppRegistrationLogin.tsx | 29 +- .../RegisterAppDialogSuccess.tsx | 71 +- .../RegisterAppTabs/RegisteredAppTabs.tsx | 30 +- src/components/bounty/Bounty/Bounty.jsx | 68 +- .../BuildYourApp/BuildYourApp.tsx | 50 +- src/components/docs/Docs/Docs.jsx | 30 +- src/components/docs/Docs/Sidebar/Sidebar.jsx | 8 +- src/components/faq/Faq/Faq.jsx | 312 ++++---- src/components/global/Accordion/Accordion.jsx | 6 +- .../global/Accordion/AccordionItem.jsx | 46 +- src/components/global/Button/Button.tsx | 36 +- src/components/global/CodeBlock/CodeBlock.jsx | 52 +- .../CodeBlock/CodeBlockSingleLanguage.jsx | 18 +- .../global/CodeBlock/CodeContent.jsx | 92 +-- .../global/CodeBlock/CopyButton.jsx | 30 +- src/components/global/CodeBlock/prism.css | 16 +- .../DelayedFallback/DelayedFallback.jsx | 40 +- src/components/global/DerivLogo/DerivLogo.tsx | 6 +- src/components/global/Dialog/Dialog.jsx | 89 +-- .../global/Dialog/useDialogPolyfill.js | 28 +- .../global/GeneralButton/GeneralButton.jsx | 6 +- .../global/Header/HamburgerLink.tsx | 53 +- .../global/Header/HamburgerNavigation.tsx | 33 +- src/components/global/Header/Header.tsx | 74 +- src/components/global/Header/Navigation.tsx | 2 +- .../NavigationLinks/NavigationLinks.tsx | 25 +- src/components/global/Header/TopNav.tsx | 12 +- .../global/LogoutButton/LogoutButton.jsx | 42 +- src/components/global/Modal/Modal.tsx | 88 ++- .../ResetSendButtonsBlock.jsx | 76 +- .../global/SandboxPage/SandboxPage.tsx | 18 +- .../global/SkeletonText/SkeletonText.jsx | 4 +- src/components/global/Spinner/Spinner.jsx | 4 +- src/components/homepage/Benefits/Benefits.tsx | 28 +- .../ClientLibraries/ClientLibraries.tsx | 29 +- .../DelayedFallbackHomepage.jsx | 14 +- .../DerivApiFeatures/DerivApiFeatures.tsx | 15 +- .../homepage/GetStarted/GetStarted.tsx | 59 +- .../homepage/HeroHeader/HeroHeader.tsx | 9 +- src/components/homepage/Homepage/Homepage.jsx | 46 +- .../HomepageFooter/HomepageFooter.tsx | 26 +- .../HomepageSlider/HomepageSlider.tsx | 12 +- .../homepage/HomepageSlider/Slide.tsx | 18 +- .../homepage/WaysToEarn/WaysToEarn.tsx | 20 +- src/components/json-schemas/JsonSchemas.jsx | 122 +-- .../playground/ApiExplorer/ApiExplorer.jsx | 30 +- .../PlaygroundComponent.jsx | 493 ++++++------- .../RequestJSONBox/ConsoleMessage.jsx | 18 +- .../RequestJSONBox/RequestJSONBox.jsx | 196 +++-- .../SelectRequestInput/SelectRequestInput.jsx | 6 +- .../TokenInputField/TokenInputField.jsx | 90 +-- .../playground/Schema/RecursiveProperties.tsx | 64 +- .../playground/Schema/SchemaBody.tsx | 82 +-- .../playground/Schema/SchemaDescription.tsx | 40 +- .../playground/Schema/SchemaHeader.tsx | 80 +- .../playground/Schema/SchemaObjectContent.tsx | 351 ++++----- .../playground/Schema/SchemaTitle.jsx | 14 +- .../playground/Schema/SchemaWrapper.tsx | 30 +- .../quickstart/Quickstart/Quickstart.jsx | 26 +- .../utility/FeatureFlag/FeatureFlag.jsx | 16 +- src/components/utility/FeatureFlag/README.md | 17 +- .../RenderOfficialDomainContents.tsx | 10 +- .../utility/SandboxIframe/SandboxIframe.jsx | 33 +- src/custom-hooks/useApps.jsx | 57 +- src/custom-hooks/useClickOutsideElement.jsx | 24 +- src/custom-hooks/useDeleteApp.jsx | 54 +- src/custom-hooks/useOnWindowResize.jsx | 50 +- src/custom-hooks/useRegisterOrUpdate.jsx | 172 +++-- src/custom-hooks/useUrlParams.jsx | 8 +- src/data-stores/data-app-registration.jsx | 130 ++-- src/data-stores/devices.js | 14 +- src/data-stores/domains.js | 26 +- src/global-functions/ScrollToTop.js | 14 +- src/global-functions/appid.jsx | 16 +- src/global-functions/resizeEffect.js | 72 +- src/global-functions/ticksSubject.js | 4 +- index.d.ts => src/index.d.ts | 0 src/index.scss | 9 +- src/main.jsx | 34 +- src/routes-data/sandbox-routes.jsx | 125 ++-- src/routes-data/sidebar-routes.jsx | 31 +- src/state/selectors.js | 43 +- src/state/state.js | 546 +++++++------- src/state/stateSignal.js | 32 +- tsconfig.json | 40 +- tsconfig.node.json | 12 +- 104 files changed, 3394 insertions(+), 3643 deletions(-) create mode 100755 .husky/pre-commit rename index.d.ts => src/index.d.ts (100%) diff --git a/.eslintignore b/.eslintignore index 9f7d543b..debfa501 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,4 @@ public/demos/demos/* +tsconfig.json +tsconfig.node.json +state/state.js diff --git a/.eslintrc.js b/.eslintrc.js index 02fa07c8..9c58aef5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,116 +1,111 @@ /* eslint-disable */ module.exports = { - env: { - browser: true, - es6: true, - es2021: true, - node: true, - cypress: true, - }, - extends: [ - "eslint:recommended", - "plugin:react/recommended", - "plugin:@typescript-eslint/recommended", - "plugin:import/recommended", - "plugin:import/errors", - "plugin:import/warnings", - "plugin:import/typescript", - ], - parser: "@typescript-eslint/parser", - parserOptions: { - ecmaFeatures: { - jsx: true, + env: { + browser: true, + es6: true, + es2021: true, + node: true, }, - ecmaVersion: "latest", - sourceType: "module", - }, - plugins: ["react", "@typescript-eslint"], - rules: { - "react/react-in-jsx-scope": "off", - camelcase: 0, - // semi : ["error", "always"], - "array-callback-return": 0, - "arrow-body-style": 0, - "brace-style": ["error", "1tbs", { allowSingleLine: true }], - curly: 0, - // "comma-dangle" : ["error", "always-multiline"], - "eol-last": ["error", "always"], - "func-names": ["error", "never"], - "key-spacing": 0, - "max-classes-per-file": ["warn", 2], - // "keyword-spacing" : ["error", { after: true }], - "lines-between-class-members": 0, - indent: 0, - // "max-len": ["error", { code: 120, "ignoreComments": true }], - "no-extra-semi": "error", - "no-console": "error", - "no-else-return": ["error", { allowElseIf: true }], - "no-multi-assign": 0, - "no-multi-spaces": [ - 2, - { - exceptions: { - BinaryExpression: true, - VariableDeclarator: true, - ImportDeclaration: true, - }, - }, - ], - "no-param-reassign": ["error", { props: false }], - "no-restricted-globals": 0, - "no-script-url": 0, - // "no-trailing-spaces" : ["error", { skipBlankLines: true }], - "object-curly-spacing": [ - "error", - "always", - { arraysInObjects: true, objectsInObjects: true }, + extends: [ + 'eslint:recommended', + 'plugin:react/recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:import/recommended', + 'plugin:import/errors', + 'plugin:import/warnings', + 'plugin:import/typescript', ], - "one-var": ["error", { initialized: "never", uninitialized: "always" }], - "prefer-destructuring": 0, - quotes: 0, - // "space-in-parens" : ["error", "never"], - "space-infix-ops": "error", - // "space-unary-ops" : "error", - "no-multiple-empty-lines": ["error", { max: 1, maxEOF: 1 }], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + ecmaVersion: 'latest', + sourceType: 'module', + }, + plugins: ['react', '@typescript-eslint'], + rules: { + 'react/react-in-jsx-scope': 'off', + camelcase: 0, + // semi : ["error", "always"], + 'array-callback-return': 0, + 'arrow-body-style': 0, + 'brace-style': ['error', '1tbs', { allowSingleLine: true }], + curly: 0, + // "comma-dangle" : ["error", "always-multiline"], + 'eol-last': ['error', 'always'], + 'func-names': ['error', 'never'], + 'key-spacing': 0, + 'max-classes-per-file': ['warn', 2], + // "keyword-spacing" : ["error", { after: true }], + 'lines-between-class-members': 0, + indent: 0, + // "max-len": ["error", { code: 120, "ignoreComments": true }], + 'no-extra-semi': 'error', + 'no-console': 'error', + 'no-else-return': ['error', { allowElseIf: true }], + 'no-multi-assign': 0, + 'no-multi-spaces': [ + 2, + { + exceptions: { + BinaryExpression: true, + VariableDeclarator: true, + ImportDeclaration: true, + }, + }, + ], + 'no-param-reassign': ['error', { props: false }], + 'no-restricted-globals': 0, + 'no-script-url': 0, + // "no-trailing-spaces" : ["error", { skipBlankLines: true }], + 'object-curly-spacing': ['error', 'always', { arraysInObjects: true, objectsInObjects: true }], + 'one-var': ['error', { initialized: 'never', uninitialized: 'always' }], + 'prefer-destructuring': 0, + quotes: 0, + // "space-in-parens" : ["error", "never"], + 'space-infix-ops': 'error', + // "space-unary-ops" : "error", + 'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 1 }], - // import rules - "import/no-extraneous-dependencies": [ - "error", - { - devDependencies: [ - "**/__tests__/**/*.js", - "**/test*.js", - "**/*.test.js*", - "**/*.spec.js", - "**/*.spec.jsx", + // import rules + 'import/no-extraneous-dependencies': [ + 'error', + { + devDependencies: [ + '**/__tests__/**/*.js', + '**/test*.js', + '**/*.test.js*', + '**/*.spec.js', + '**/*.spec.jsx', + ], + }, ], - }, - ], - "import/no-useless-path-segments": "error", - "import/order": [ - 0, // TODO: we should turn this to error after we sorted our import orders. - { - groups: [["builtin", "external"], "internal", "sibling", "parent"], - "newlines-between": "ignore", - }, - ], - "import/prefer-default-export": 0, - "import/extensions": ["warn", "never", { jsx: "never", json: "always" }], - "no-sequences": ["warn"], + 'import/no-useless-path-segments': 'error', + 'import/order': [ + 0, // TODO: we should turn this to error after we sorted our import orders. + { + groups: [['builtin', 'external'], 'internal', 'sibling', 'parent'], + 'newlines-between': 'ignore', + }, + ], + 'import/prefer-default-export': 0, + 'import/extensions': ['warn', 'never', { jsx: 'never', json: 'always' }], + 'no-sequences': ['warn'], - // react rules - // "jsx-quotes" : ["error", "prefer-single"], - // "react/jsx-closing-bracket-location": ["error", { selfClosing: "line-aligned", nonEmpty: "line-aligned" }], - // "react/jsx-closing-tag-location" : "error", - // "react/jsx-first-prop-new-line" : ["error", "multiline-multiprop"], - // "react/jsx-indent" : ["error", 4], - // "react/jsx-indent-props" : ["error", 4], - // "react/jsx-max-props-per-line" : ["error", { when: "multiline" }], - // "react/jsx-tag-spacing" : ["error", { closingSlash: "never", beforeSelfClosing: "always" }], - "react/prop-types": 0, - "react/self-closing-comp": "error", - "react/no-unescaped-entities": 0, - // "react/sort-prop-types" : ["error", { ignoreCase: true, sortShapeProp: true }], - }, + // react rules + // "jsx-quotes" : ["error", "prefer-single"], + // "react/jsx-closing-bracket-location": ["error", { selfClosing: "line-aligned", nonEmpty: "line-aligned" }], + // "react/jsx-closing-tag-location" : "error", + // "react/jsx-first-prop-new-line" : ["error", "multiline-multiprop"], + // "react/jsx-indent" : ["error", 4], + // "react/jsx-indent-props" : ["error", 4], + // "react/jsx-max-props-per-line" : ["error", { when: "multiline" }], + // "react/jsx-tag-spacing" : ["error", { closingSlash: "never", beforeSelfClosing: "always" }], + 'react/prop-types': 0, + 'react/self-closing-comp': 'error', + 'react/no-unescaped-entities': 0, + // "react/sort-prop-types" : ["error", { ignoreCase: true, sortShapeProp: true }], + }, }; diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 00000000..1bda9c17 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +npm run format diff --git a/.prettierignore b/.prettierignore index 74afd891..8d3aba9b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,4 +4,15 @@ _site/ _data/ config/ examples/ -public/ \ No newline at end of file +public/ +api-data/ +state.js +*.d.ts +*.config.ts +*.config.js +*.config.tsx +*.config.json +*.tsconfig.json +*.tsconfig.node.json +README.md +vercel.json diff --git a/README.md b/README.md index 4c9ebe4f..4560c089 100644 --- a/README.md +++ b/README.md @@ -48,14 +48,13 @@ Moreover, having these extensions will help you to speed up the development proc npm install ``` - 5. **To start developing:** ```sh npm run dev ``` -1. Release to staging: +1. Release to staging: Merging to master (squash and merge) will automatically release the last commit to the staging server https://staging-api.deriv.com/ @@ -67,7 +66,7 @@ Releasing to production requires a tag using the following format: ## How to contribute -PRs are based on the master branch +PRs are based on the master branch 1. Create branch from the latest master branch @@ -89,4 +88,4 @@ PRs are based on the master branch ## Test link deployment -Upon creating PR, [Vercel](https://vercel.com/) will auto-generate a test link inside the PR. you can use that to preview the test link for the changes you have made. \ No newline at end of file +Upon creating PR, [Vercel](https://vercel.com/) will auto-generate a test link inside the PR. you can use that to preview the test link for the changes you have made. diff --git a/cypress/e2e/api.deriv.com.cy.js b/cypress/e2e/api.deriv.com.cy.js index a84a2de9..5d5b421a 100644 --- a/cypress/e2e/api.deriv.com.cy.js +++ b/cypress/e2e/api.deriv.com.cy.js @@ -161,7 +161,7 @@ const derivAPIEvents = { }, CLICK_LOGO: function () { cy.get('[data-testid="home_logo"]').click(); - } + }, }; const derivAPIStates = { @@ -171,7 +171,9 @@ const derivAPIStates = { cy.contains(/ways to earn with deriv api/i).should('be.visible'); cy.contains(/register your app with deriv/i).should('be.visible'); cy.contains(/sign up as an affiliate, build your app/i).should('be.visible'); - cy.contains(/sign up as a payment agent/i).should('be.visible').scrollIntoView(); + cy.contains(/sign up as a payment agent/i) + .should('be.visible') + .scrollIntoView(); }, playground: () => { // checkScroll(); TODO children states cause scroll to not be at top @@ -183,8 +185,12 @@ const derivAPIStates = { }, documetnation: () => { isScrollOnTop(); - cy.contains(/Quickstart to Deriv API/i).should('be.visible').scrollIntoView(); - cy.contains(/Keep alive/i).should('be.visible').scrollIntoView(); + cy.contains(/Quickstart to Deriv API/i) + .should('be.visible') + .scrollIntoView(); + cy.contains(/Keep alive/i) + .should('be.visible') + .scrollIntoView(); }, faq: () => { isScrollOnTop(); @@ -218,25 +224,25 @@ const derivAPIStates = { cy.get('[data-testid="apiTokenInput"]').should('have.value', Cypress.env('DERIV_API_TOKEN')); }, displayAuthDoc: () => { - cy.get('[data-testid=apiDropdown]') - .contains(/authorize/i) + cy.get('[data-testid=apiDropdown]').contains(/authorize/i); cy.get('[data-testid=playgroundDocs]') .should('be.visible') .contains(/authorize/i); }, displaySelectedDoc: () => { cy.get('[data-testid=apiDropdown]') - .contains(/authorize/i) - .should('not.exist'); + .contains(/authorize/i) + .should('not.exist'); cy.get('[data-testid=playgroundDocs]') - .should('be.visible') - // should not contain authorize - .contains(/authorize/i).should('not.exist'); + .should('be.visible') + // should not contain authorize + .contains(/authorize/i) + .should('not.exist'); }, selecting_api: () => { // data-testid searchInput should be in focus cy.get('[data-testid="searchInput"]').should('have.focus'); - } + }, }; // cypress check if the scroll is at the top of the page diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json index 02e42543..519902d7 100644 --- a/cypress/fixtures/example.json +++ b/cypress/fixtures/example.json @@ -1,5 +1,5 @@ { - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" } diff --git a/package.json b/package.json index 337e2901..e86b1ff4 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "lint": "eslint .", "lint:fix": "eslint --fix", "format": "prettier --write './**/*.{js,jsx,ts,tsx,css,md,json}' --config ./.prettierrc", - "e2e": "cypress open" + "e2e": "cypress open", + "prepare": "husky install" }, "dependencies": { "@cypress/code-coverage": "^3.10.0", diff --git a/src/components/api-guide/ApiGuide/ApiGuide.jsx b/src/components/api-guide/ApiGuide/ApiGuide.jsx index c2c771f6..79c29adf 100644 --- a/src/components/api-guide/ApiGuide/ApiGuide.jsx +++ b/src/components/api-guide/ApiGuide/ApiGuide.jsx @@ -1,106 +1,102 @@ -import { useSelector } from "@xstate/react"; -import styles from "./ApiGuide.module.scss"; -import Navigator from "./Navigator/Navigator"; -import { DerivGuideContent } from "./DerivGuideContent/DerivGuideContent" -import { RenderOfficialDomainContents } from "../../utility/RenderOfficialDomainContents/RenderOfficialDomainContents"; +import { useSelector } from '@xstate/react'; +import styles from './ApiGuide.module.scss'; +import Navigator from './Navigator/Navigator'; +import { DerivGuideContent } from './DerivGuideContent/DerivGuideContent'; +import { RenderOfficialDomainContents } from '../../utility/RenderOfficialDomainContents/RenderOfficialDomainContents'; -import { isMobileSelector } from "../../../state/selectors"; -import { stateService } from "../../../state/stateSignal"; +import { isMobileSelector } from '../../../state/selectors'; +import { stateService } from '../../../state/stateSignal'; -import howAPIWorksUrl from "../../../../img/how-api-works.png"; +import howAPIWorksUrl from '../../../../img/how-api-works.png'; export default function ApiGuide() { - const isMobile = useSelector(stateService, isMobileSelector); - return ( -
- {!isMobile && } -
-

API guide

- {isMobile && } -
-

What is API?

-

- API stands for Application Programming Interface - a software that - allows 2 or more computer programs to communicate with each other. - These 2 programs are usually referred to as server and client. -

-
    -
  • - Server -

    - A server contains information required by a client, can grant - access to this information, and performs actions with it. -

    -

    - {" "} - The server defines how it should be spoken to, what actions it - will perform, what information it will give, and its format.{" "} -

    -

    - {" "} - All these details are usually determined in an API - specification. For example, here is the{" "} - - API specification for Twitter - - . -

    -
  • -
  • - Client -

    - {" "} - A client is a software program that talks to the server to - either obtain information or ask the server to perform certain - actions.{" "} -

    -

    - {" "} - Clients can be written in any programming language as long as - that language can implement the communication standards - specified by the server.{" "} -

    -

    - {" "} - The communication between a server and a client happens with the - help of API requests, also known as API calls. The API calls are - sent from a client to a server and back. The client and server - can be written in different programming languages.{" "} -

    -
  • -
-

Here is a representation of how an API works:

-
- How API works -
-

Client libraries

-

- {" "} - Client libraries are pre-written pieces of code that can be used to - send API calls instead of writing codes from scratch.{" "} -

-

- {" "} - Using a client library is optional but highly recommended, as it - makes it much easier and efficient to start working with the API.{" "} -

-

- {" "} - For example, configuring the correct protocol to talk to the server - may require several steps without the client library, but using a - ready-made code can shorten the process to just one step.{" "} -

-

- {" "} - A client library also makes it easier to adapt to API updates. In - many cases, if the API has a significant update, the client library - is updated too. The developer of the client that uses API won’t need - to make any changes to their code and will just need to update the - version of the client library.{" "} -

+ const isMobile = useSelector(stateService, isMobileSelector); + return ( +
+ {!isMobile && } +
+

API guide

+ {isMobile && } +
+

What is API?

+

+ API stands for Application Programming Interface - a software that allows 2 or more computer + programs to communicate with each other. These 2 programs are usually referred to as server and + client. +

+
    +
  • + Server +

    + A server contains information required by a client, can grant access to this + information, and performs actions with it. +

    +

    + {' '} + The server defines how it should be spoken to, what actions it will perform, what + information it will give, and its format.{' '} +

    +

    + {' '} + All these details are usually determined in an API specification. For example, here is + the{' '} + + API specification for Twitter + + . +

    +
  • +
  • + Client +

    + {' '} + A client is a software program that talks to the server to either obtain information or + ask the server to perform certain actions.{' '} +

    +

    + {' '} + Clients can be written in any programming language as long as that language can + implement the communication standards specified by the server.{' '} +

    +

    + {' '} + The communication between a server and a client happens with the help of API requests, + also known as API calls. The API calls are sent from a client to a server and back. The + client and server can be written in different programming languages.{' '} +

    +
  • +
+

Here is a representation of how an API works:

+
+ How API works +
+

Client libraries

+

+ {' '} + Client libraries are pre-written pieces of code that can be used to send API calls instead of + writing codes from scratch.{' '} +

+

+ {' '} + Using a client library is optional but highly recommended, as it makes it much easier and + efficient to start working with the API.{' '} +

+

+ {' '} + For example, configuring the correct protocol to talk to the server may require several steps + without the client library, but using a ready-made code can shorten the process to just one + step.{' '} +

+

+ {' '} + A client library also makes it easier to adapt to API updates. In many cases, if the API has a + significant update, the client library is updated too. The developer of the client that uses API + won’t need to make any changes to their code and will just need to update the version of the + client library.{' '} +

+
+ +
- -
-
- ); + ); } diff --git a/src/components/api-guide/ApiGuide/ApiGuideTable/ApiGuideTable.jsx b/src/components/api-guide/ApiGuide/ApiGuideTable/ApiGuideTable.jsx index 1ee1c251..1a8d6160 100644 --- a/src/components/api-guide/ApiGuide/ApiGuideTable/ApiGuideTable.jsx +++ b/src/components/api-guide/ApiGuide/ApiGuideTable/ApiGuideTable.jsx @@ -1,180 +1,180 @@ -import styles from "./ApiGuideTable.module.scss"; +import styles from './ApiGuideTable.module.scss'; export default function ApiGuideTable() { - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
API contract nameCategory on websiteName on website
MULTUPMultiply Up/Multiply DownMultiply Up
MULTDOWNMultiply Up/Multiply DownMultiply Down
UPORDOWNStays Between/Goes OutsideGoes Outside
EXPIRYRANGEEnds Between/Ends OutsideEnds Between
ONETOUCHTouch/No TouchTouches
CALLERise/Fall EqualHigher
LBHIGHLOWLookbacksHigh-Low
ASIANDAsiansAsian Down
EXPIRYRANGEE - -
DIGITDIFFDigitsDigit Differs
DIGITMATCHDigitsDigit Matches
DIGITOVERDigitsDigit Over
PUTERise/Fall EqualLower
DIGITUNDERDigitsDigit Under
NOTOUCHTouch/No TouchDoes Not touch
CALLUp/DownHigher
RANGEStays Between/Goes OutsideStays Between
LBFLOATPUTLookbacksHigh-Close
DIGITODDDigitsDigit Odd
PUTUp/DownLower
ASIANUAsiansAsian Up
LBFLOATCALLLookbacksClose-Low
EXPIRYMISSE - -
EXPIRYMISSEnds Between/Ends OutsideEnds Outside
DIGITEVENDigitsDigit Even
TICKHIGHhighlowticksHigh Tick
TICKLOWhighlowticksLow Tick
RESETCALLReset Call/Reset PutReset Call
RESETPUTReset Call/Reset PutReset Put
CALLSPREADCall Spread/Put SpreadCall Spread
PUTSPREADCall Spread/Put SpreadPut Spread
RUNHIGHOnly Ups/Only DownsOnly Ups
RUNLOWOnly Ups/Only DownsOnly Downs
- ); + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
API contract nameCategory on websiteName on website
MULTUPMultiply Up/Multiply DownMultiply Up
MULTDOWNMultiply Up/Multiply DownMultiply Down
UPORDOWNStays Between/Goes OutsideGoes Outside
EXPIRYRANGEEnds Between/Ends OutsideEnds Between
ONETOUCHTouch/No TouchTouches
CALLERise/Fall EqualHigher
LBHIGHLOWLookbacksHigh-Low
ASIANDAsiansAsian Down
EXPIRYRANGEE + +
DIGITDIFFDigitsDigit Differs
DIGITMATCHDigitsDigit Matches
DIGITOVERDigitsDigit Over
PUTERise/Fall EqualLower
DIGITUNDERDigitsDigit Under
NOTOUCHTouch/No TouchDoes Not touch
CALLUp/DownHigher
RANGEStays Between/Goes OutsideStays Between
LBFLOATPUTLookbacksHigh-Close
DIGITODDDigitsDigit Odd
PUTUp/DownLower
ASIANUAsiansAsian Up
LBFLOATCALLLookbacksClose-Low
EXPIRYMISSE + +
EXPIRYMISSEnds Between/Ends OutsideEnds Outside
DIGITEVENDigitsDigit Even
TICKHIGHhighlowticksHigh Tick
TICKLOWhighlowticksLow Tick
RESETCALLReset Call/Reset PutReset Call
RESETPUTReset Call/Reset PutReset Put
CALLSPREADCall Spread/Put SpreadCall Spread
PUTSPREADCall Spread/Put SpreadPut Spread
RUNHIGHOnly Ups/Only DownsOnly Ups
RUNLOWOnly Ups/Only DownsOnly Downs
+ ); } diff --git a/src/components/api-guide/ApiGuide/DerivGuideContent/DerivGuideContent.tsx b/src/components/api-guide/ApiGuide/DerivGuideContent/DerivGuideContent.tsx index 30f63759..4f624a5f 100644 --- a/src/components/api-guide/ApiGuide/DerivGuideContent/DerivGuideContent.tsx +++ b/src/components/api-guide/ApiGuide/DerivGuideContent/DerivGuideContent.tsx @@ -1,20 +1,20 @@ -import React from "react" -import { Link } from "react-router-dom"; -import ApiGuideTable from "../ApiGuideTable/ApiGuideTable"; -import CodeBlockSingleLanguage from "../../../global/CodeBlock/CodeBlockSingleLanguage"; -import styles from "../ApiGuide.module.scss"; +import React from 'react'; +import { Link } from 'react-router-dom'; +import ApiGuideTable from '../ApiGuideTable/ApiGuideTable'; +import CodeBlockSingleLanguage from '../../../global/CodeBlock/CodeBlockSingleLanguage'; +import styles from '../ApiGuide.module.scss'; -import ticksJSON from "../../../../../public/demos/json/ticks.json"; -import nestedJSON from "../../../../../public/demos/json/nested.json"; -import statusJSON from "../../../../../public/demos/json/status.json"; -import schemaJSON from "../../../../../public/demos/json/schema.json"; +import ticksJSON from '../../../../../public/demos/json/ticks.json'; +import nestedJSON from '../../../../../public/demos/json/nested.json'; +import statusJSON from '../../../../../public/demos/json/status.json'; +import schemaJSON from '../../../../../public/demos/json/schema.json'; -import apiPlaygroundImg from "../../../../../img/api-playground.png"; -import showJSONSchemaImg from "../../../../../img/show-json-schema.png"; -import apiTokenPageImg from "../../../../../img/api-token-page.png"; -import readAccessImg from "../../../../../img/read-access.png"; -import howOauthWorksImg from "../../../../../img/how-oauth-works.png"; -import signupImg from "../../../../../img/signup.png"; +import apiPlaygroundImg from '../../../../../img/api-playground.png'; +import showJSONSchemaImg from '../../../../../img/show-json-schema.png'; +import apiTokenPageImg from '../../../../../img/api-token-page.png'; +import readAccessImg from '../../../../../img/read-access.png'; +import howOauthWorksImg from '../../../../../img/how-oauth-works.png'; +import signupImg from '../../../../../img/signup.png'; export const DerivGuideContent = () => { const tickContent = JSON.stringify(ticksJSON, null, 2); @@ -24,378 +24,309 @@ export const DerivGuideContent = () => { return (
-

The Deriv API

-

- What can you do with the Deriv API? -

-

- The Deriv API allows you to perform nearly all functions of the - Deriv platforms, since they share the same API. For our CFD - platforms (Deriv MT5 and Deriv X), the API functionality is only - available for some account management actions. -

-

Our API users typically perform the following activities:

-
    -
  • -

    - Build websites similar to Deriv but with different features. -

    -
  • -
  • -

    - Create desktop apps to execute trades for themselves and their - clients. -

    -
  • -
  • -

    Explore historical tick information.

    -
  • -
  • -

    Automate services as payment agents.

    -
  • -
-

- How can you earn with Deriv API? -

-
    -
  • -

    - You can earn commission on trades and payments your clients - perform via the websites and apps you create with Deriv API. Get - more details about the commission plans{" "} - - here - - .{" "} -

    -
  • -
  • -

    - You can also earn from markups on every contract purchased via a - trading app you created with Deriv API. The markup is defined by - you and can be up to 5%. -

    -
  • -
-

Here is an example of how the markup is calculated:

-
    +

    The Deriv API

    +

    What can you do with the Deriv API?

    +

    + The Deriv API allows you to perform nearly all functions of the Deriv platforms, since they share + the same API. For our CFD platforms (Deriv MT5 and Deriv X), the API functionality is only available + for some account management actions. +

    +

    Our API users typically perform the following activities:

    +
      +
    • +

      Build websites similar to Deriv but with different features.

      +
    • +
    • +

      Create desktop apps to execute trades for themselves and their clients.

      +
    • +
    • +

      Explore historical tick information.

      +
    • +
    • +

      Automate services as payment agents.

      +
    • +
    +

    How can you earn with Deriv API?

    +
      +
    • +

      + You can earn commission on trades and payments your clients perform via the websites and + apps you create with Deriv API. Get more details about the commission plans{' '} + + here + + .{' '} +

      +
    • +
    • +

      + You can also earn from markups on every contract purchased via a trading app you created + with Deriv API. The markup is defined by you and can be up to 5%. +

      +
    • +
    +

    Here is an example of how the markup is calculated:

    +
      +

      + To get a payout of 2 USD: +

      +
    • + Client stake without markup = 1.07 USD +
    • +

      With the markup (e.g. 2%), a client pays:

      +
    • Client's stake with the markup = Stake + (payout x markup)
    • +
    • + Client's stake with the markup = 1.07 USD + (2 USD x 2%) = 1.11 USD +
    • +
    +

    Conditions of using the Deriv API

    +

    + The Deriv API is free of charge and is subject to our{' '} + terms and conditions and{' '} + copyright. +

    +

    + Should you run into any difficulties using it or if you need assistance, please contact us via one + of our support forums or via email. +

    +
+
+

Technical specifications of the Deriv API

+

+ It is only possible to communicate with the Deriv API using WebSockets; it does not support other + protocols. Any data passed to the Deriv API should be in JSON format, while the comprehensive + all-in-one client library is available in JavaScript and Python. +

+

WebSockets

+

+ The WebSockets protocol is an advanced version of the communication channel that is available in all + popular programming languages. It allows the server to send information to the client and maintain + the connection without the client requesting it every time. +

+

+ In comparison, APIs using REST over HTTP don't maintain a connection to the client once the server + has replied to it. +

+

+ The WebSockets protocol provides clients with a faster and more efficient way to receive updated + information as soon as it becomes available. For example, you can subscribe to account balance + updates and the Deriv servers will send the new balance to your client in real time. +

+

+ A client can also subscribe and receive several types of different information simultaneously over a + single connection. +

+

+ For more information on how to write a client using WebSockets, visit this{' '} + guide. +

+

JSON

+

+ JavaScript Object Notation (JSON) is a data format based on JavaScript. However, it is completely + language-independent, and can be used by any modern programming language. JSON has a good balance + between being readable by humans and by machines, making it both user-friendly and + computer-efficient. +

+

+ Here is an example of the JSON formatted code, where “ticks” is the name of the attribute and + “R_100” is the value of that attribute. +

+
+
+ +
+

+ Data in JSON can also be nested, so if you wanted to send user information with an address, it could + look like: +

+
+ +
+

+ When you are writing an API client, you will write something like{' '} + print address.street_number + (depending on the programming language) to print the street number. +

+

This nesting can have as many levels as required to convey the information.

+

+ For example, when we send information about account status, it requires several levels to print + information (print authentication.identity.services.manual) about + the manual Identity service status: +

+
+ +
+

JSON Schemas

+

+ JSON Schema is a defined format for the JSON messages used to describe their structure to Deriv API + users. In a nutshell, it’s a standardised way of explaining what a JSON request should look like using + JSON itself. +

+

+ Here is an example of the part of the JSON Schema that is used to tell developers what to send when they + request the balance of an account: +

+
+ +
+

+ You can see that the balance is a required attribute, the value must equal 1, and the account is an + optional attribute. But if you choose to send it, it must be a string (word) and has to match the + described pattern. +

+

+ JSON Schemas on Deriv are divided into schemas we accept (request) and schemas we send (response). You + can find the detailed JSON schemas for each API call on our API Explorer. +

+
+ API Guide +
+

To see the raw JSON schemas, click on the braces within each call.

+
+ API Guide +
+

The JSON Schema also forms the documentation for the API Explorer.

+

Authorisation

+

+ Third-party developers can authorise calls to the API in two different ways: via API token or via + OAuth2. +

+

API token

+

+ An API token is a unique identifier of a client that requests access from a server. It's the simplest + way of authorisation. +

+

+ The Deriv API token has to be generated by a client{' '} + here, along with setting the appropriate access + level. +

+
+ API Guide +
+

+ The access level for each API token has to match the required access level of each API call, which can + be found in the API Explorer as well. +

+

+ For example, on the screenshot below, you can see that to be able to use the Account Status, a token + with read access level must be used. +

+
+ API Guide +
+

+ Following the authorisation of a WebSocket connection, subsequent calls on that connection will be + considered user actions. +

+

+ Please bear in mind that the API token can be used with any app, so both your app and your clients need + to keep it secure. +

+

OAuth2

+

+ OAuth stands for Open Authorisation - a protocol that allows a client access resources hosted on a + server on behalf of the user without revealing the credentials. +

+

+ This type of authorisation allows clients to log in to third-party apps using their Deriv accounts + without creating an API token. In this case, the third-party app does not see the user's password or + permanent API token, which makes it safer. +

+

+ The OAuth2 authentication requires more steps to set up, but it is the safest way for developers to + share access to their app with their clients. +

+

+ For more information on OAuth2, visit{' '} + this guide. +

+

Here is the visual representation of how the OAuth authorisation connection works:

+
+ API Guide +
+

What do you need to do to use OAuth authorisation for Deriv API?

+
    +
  • +

    + Specify the URL that will be used as the OAuth Redirect URL on the{' '} + API registration page in the 'Website + URL' field. +

    +
  • +
  • +

    + Add a login button on your website or app and direct users to{' '} + https://oauth.binary.com/oauth2/authorize?app_id=your_app_id where your_app_id is the ID + of your app. +

    +
  • +
+
+ API Guide +
+

+ Once a user signs up, they will be redirected to the URL that you entered as the Redirect URL. This URL + will have arguments added to it with the user's session tokens, and will look similar to this: +

+

+ + https://mywebsite.com/redirect/?acct1=cr799393& token1=a1-f7pnteezo4jzhpxclctizt27hyeot&cur1=usd& + acct2=vrtc1859315& token2=a1clwe3vfuuus5kraceykdsoqm4snfq& cur2=usd&state= + +

+

In the parameters of the URL you will see all the accounts and the session token for each account.

+
    +
  • + Pass these tokens to the Authorize API call in order to perform actions on behalf of the account. +
  • +
+

Performing trades via Deriv API

+

+ You can perform a simple contract purchase with a code from our list of examples on the{' '} + quick start page. +

- To get a payout of 2 USD: + However, while the simple example will work for most cases, it does not perform any checks to see if the + asset is available for purchase or show the potential payout if they proceed with the purchase.

-
  • - Client stake without markup = 1.07 USD -
  • -

    With the markup (e.g. 2%), a client pays:

    -
  • Client's stake with the markup = Stake + (payout x markup)
  • -
  • - Client's stake with the markup = 1.07 USD + (2 USD x 2%) ={" "} - 1.11 USD -
  • - -

    Conditions of using the Deriv API

    -

    - The Deriv API is free of charge and is subject to our{" "} - - terms and conditions - {" "} - and{" "} - - copyright - - . -

    -

    - Should you run into any difficulties using it or if you need - assistance, please contact us via one of our support forums or via{" "} - email. -

    -
    -
    -

    - Technical specifications of the Deriv API -

    -

    - It is only possible to communicate with the Deriv API using - WebSockets; it does not support other protocols. Any data passed to - the Deriv API should be in JSON format, while the comprehensive - all-in-one client library is available in JavaScript and Python. -

    -

    WebSockets

    -

    - The WebSockets protocol is an advanced version of the communication - channel that is available in all popular programming languages. It - allows the server to send information to the client and maintain the - connection without the client requesting it every time. -

    -

    - In comparison, APIs using REST over HTTP don't maintain a connection - to the client once the server has replied to it. -

    -

    - The WebSockets protocol provides clients with a faster and more - efficient way to receive updated information as soon as it becomes - available. For example, you can subscribe to account balance updates - and the Deriv servers will send the new balance to your client in - real time. -

    -

    - A client can also subscribe and receive several types of different - information simultaneously over a single connection. -

    -

    - For more information on how to write a client using WebSockets, - visit this guide. -

    -

    JSON

    -

    - JavaScript Object Notation (JSON) is a data format based on - JavaScript. However, it is completely language-independent, and can - be used by any modern programming language. JSON has a good balance - between being readable by humans and by machines, making it both - user-friendly and computer-efficient. -

    -

    - Here is an example of the JSON formatted code, where “ticks” is the - name of the attribute and “R_100” is the value of that attribute. -

    -
    -
    - -
    -

    - Data in JSON can also be nested, so if you wanted to send user - information with an address, it could look like: -

    -
    - -
    -

    - When you are writing an API client, you will write something like{" "} - print address.street_number - (depending on the programming language) to print the street number. -

    -

    - This nesting can have as many levels as required to convey the - information. -

    -

    - For example, when we send information about account status, it - requires several levels to print information ( - - print authentication.identity.services.manual - - ) about the manual Identity service status: -

    -
    - -
    -

    JSON Schemas

    -

    - JSON Schema is a defined format for the JSON messages used to describe - their structure to Deriv API users. In a nutshell, it’s a standardised - way of explaining what a JSON request should look like using JSON - itself. -

    -

    - Here is an example of the part of the JSON Schema that is used to tell - developers what to send when they request the balance of an account: -

    -
    - -
    -

    - You can see that the balance is a required attribute, the value must - equal 1, and the account is an optional attribute. But if you choose - to send it, it must be a string (word) and has to match the described - pattern. -

    -

    - JSON Schemas on Deriv are divided into schemas we accept (request) and - schemas we send (response). You can find the detailed JSON schemas for - each API call on our API Explorer. -

    -
    - API Guide -
    -

    - To see the raw JSON schemas, click on the braces within each call. -

    -
    - API Guide -
    -

    - The JSON Schema also forms the documentation for the API Explorer. -

    -

    Authorisation

    -

    - Third-party developers can authorise calls to the API in two different - ways: via API token or via OAuth2. -

    -

    API token

    -

    - An API token is a unique identifier of a client that requests access - from a server. It's the simplest way of authorisation. -

    -

    - The Deriv API token has to be generated by a client{" "} - here, along with - setting the appropriate access level. -

    -
    - API Guide -
    -

    - The access level for each API token has to match the required access - level of each API call, which can be found in the{" "} - API Explorer as well. -

    -

    - For example, on the screenshot below, you can see that to be able to - use the Account Status, a token with read access level must be used. -

    -
    - API Guide -
    -

    - Following the authorisation of a WebSocket connection, subsequent - calls on that connection will be considered user actions. -

    -

    - Please bear in mind that the API token can be used with any app, so - both your app and your clients need to keep it secure. -

    -

    OAuth2

    -

    - OAuth stands for Open Authorisation - a protocol that allows a client - access resources hosted on a server on behalf of the user without - revealing the credentials. -

    -

    - This type of authorisation allows clients to log in to third-party - apps using their Deriv accounts without creating an API token. In this - case, the third-party app does not see the user's password or - permanent API token, which makes it safer. -

    -

    - The OAuth2 authentication requires more steps to set up, but it is the - safest way for developers to share access to their app with their - clients. -

    -

    - For more information on OAuth2, visit{" "} - this guide. -

    -

    - Here is the visual representation of how the OAuth authorisation - connection works: -

    -
    - API Guide -
    -

    - What do you need to do to use OAuth authorisation for Deriv API? -

    - -
    - API Guide -
    -

    - Once a user signs up, they will be redirected to the URL that you - entered as the Redirect URL. This URL will have arguments added to it - with the user's session tokens, and will look similar to this: -

    -

    - - https://mywebsite.com/redirect/?acct1=cr799393& - token1=a1-f7pnteezo4jzhpxclctizt27hyeot&cur1=usd& acct2=vrtc1859315& - token2=a1clwe3vfuuus5kraceykdsoqm4snfq& cur2=usd&state= - -

    -

    - In the parameters of the URL you will see all the accounts and the - session token for each account. -

    - -

    - Performing trades via Deriv API -

    -

    - You can perform a simple contract purchase with a code from our list - of examples on the quick start page. -

    -

    - However, while the simple example will work for most cases, it does - not perform any checks to see if the asset is available for purchase - or show the potential payout if they proceed with the purchase. -

    -

    - To receive this additional information, you can perform several steps - once you are authorised and before purchasing the contract. -

    - -

    Table mapping

    -

    Deriv website contract types to API parameter names

    -

    - If you would like to copy certain contract types from our websites, - the following table will describe how the contract type is referred to - using the API. -

    -
    - -
    +
    + +
    - ) -} \ No newline at end of file + ); +}; diff --git a/src/components/app-registration/AppManagement/AppManagement.jsx b/src/components/app-registration/AppManagement/AppManagement.jsx index c1fe0cfd..574612fb 100644 --- a/src/components/app-registration/AppManagement/AppManagement.jsx +++ b/src/components/app-registration/AppManagement/AppManagement.jsx @@ -1,159 +1,149 @@ /* eslint-disable react/jsx-key */ -import React from "react"; -import { useMemo, useState } from "react"; -import { useTable, useSortBy } from "react-table"; -import "../AppRegistration/AppRegistration.scss" -import styles from "./AppManagement.module.scss"; -import { useApps } from "../../../custom-hooks/useApps"; -import SkeletonText from "../../global/SkeletonText/SkeletonText"; -import AppManagementEmptyLazy from "./AppManagementEmpty/AppManagementEmptyLazy"; -import DeleteAppDialog from "../AppRegistration/AppRegistrationForm/DeleteAppDialog/DeleteAppDialog"; -import { useDeleteApp } from "../../../custom-hooks/useDeleteApp"; -import { setUpdatingRow, stateService } from "../../../state/stateSignal"; +import React from 'react'; +import { useMemo, useState } from 'react'; +import { useTable, useSortBy } from 'react-table'; +import '../AppRegistration/AppRegistration.scss'; +import styles from './AppManagement.module.scss'; +import { useApps } from '../../../custom-hooks/useApps'; +import SkeletonText from '../../global/SkeletonText/SkeletonText'; +import AppManagementEmptyLazy from './AppManagementEmpty/AppManagementEmptyLazy'; +import DeleteAppDialog from '../AppRegistration/AppRegistrationForm/DeleteAppDialog/DeleteAppDialog'; +import { useDeleteApp } from '../../../custom-hooks/useDeleteApp'; +import { setUpdatingRow, stateService } from '../../../state/stateSignal'; export default function AppManagement() { - const [app_id, setAppId] = useState(null); - const { deleteApp } = useDeleteApp(app_id); - const { data, isLoading } = useApps(); - const table_data = useMemo(() => data?.app_list || [], [data]); - const columns = useMemo( - () => [ - { - Header: "Application Name", - accessor: "name", - }, - { - Header: "Application ID", - accessor: "app_id", - }, - { - Header: "Scopes", - accessor: "scopes", - Cell: ({ cell: { value } }) => , - }, - { - Header: "Redirect URL", - accessor: "redirect_uri", - }, - { - Header: "", - accessor: "actions", - disableSortBy: true, - Cell: ({ row }) => { - const app_id = row.original.app_id; - const triggerModal = () => { - setAppId(app_id); - stateService.send("DELETE_APP"); - }; - const updateAppTrigger = () => { - stateService.send("GO_UPDATE_MODE"); - setUpdatingRow(row.original); - }; - return ( -
    -
    - - Edit application details - -
    -
    - - Delete application - -
    -
    - ); + const [app_id, setAppId] = useState(null); + const { deleteApp } = useDeleteApp(app_id); + const { data, isLoading } = useApps(); + const table_data = useMemo(() => data?.app_list || [], [data]); + const columns = useMemo( + () => [ + { + Header: 'Application Name', + accessor: 'name', + }, + { + Header: 'Application ID', + accessor: 'app_id', + }, + { + Header: 'Scopes', + accessor: 'scopes', + Cell: ({ cell: { value } }) => , + }, + { + Header: 'Redirect URL', + accessor: 'redirect_uri', + }, + { + Header: '', + accessor: 'actions', + disableSortBy: true, + Cell: ({ row }) => { + const app_id = row.original.app_id; + const triggerModal = () => { + setAppId(app_id); + stateService.send('DELETE_APP'); + }; + const updateAppTrigger = () => { + stateService.send('GO_UPDATE_MODE'); + setUpdatingRow(row.original); + }; + return ( +
    +
    + Edit application details +
    +
    + Delete application +
    +
    + ); + }, + }, + ], + [] + ); + + const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable( + { + columns, + data: table_data, }, - }, - ], - [] - ); + useSortBy + ); - const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = - useTable( - { - columns, - data: table_data, - }, - useSortBy + return ( + +
    + + + {headerGroups.map(headerGroup => ( + + {headerGroup.headers.map(column => ( + + ))} + + ))} + + + {isLoading && } + {rows.map(row => { + prepareRow(row); + return ( + + {row.cells.map(cell => { + return ; + })} + + ); + })} + +
    + {column.render('Header')} + {column.isSorted ? (column.isSortedDesc ? '↓' : '↑') : ''} +
    {cell.render('Cell')}
    +
    + + +
    ); +} - return ( - -
    - - - {headerGroups.map((headerGroup) => ( - - {headerGroup.headers.map((column) => ( - - ))} - - ))} - - - {isLoading && } - {rows.map((row) => { - prepareRow(row); - return ( - - {row.cells.map((cell) => { - return ( - - ); - })} - - ); + ); })} - -
    - {column.render("Header")} - - {column.isSorted ? (column.isSortedDesc ? "↓" : "↑") : ""} +const Scopes = ({ values, idx }) => { + return ( + + {values.map(scopes => { + return ( + + {scopes.charAt(0).toUpperCase() + scopes.slice(1).replace('_', ' ')} -
    {cell.render("Cell")}
    -
    - - -
    - ); -} - -const Scopes = ({ values,idx }) => { - return ( - - {values.map((scopes) => { - return ( - - {scopes.charAt(0).toUpperCase() + scopes.slice(1).replace("_"," ")} - - ); - })} - - )} + + ); +}; const SkeletonRows = () => { - const Skeleton = () => ( - - - - - - - - - - - - - - - - - - ); - // return 5 skeletons - return [...Array(5)].map((_, i) => ); + const Skeleton = () => ( + + + + + + + + + + + + + + + + + + ); + // return 5 skeletons + return [...Array(5)].map((_, i) => ); }; diff --git a/src/components/app-registration/AppManagement/AppManagementEmpty/AppManagementEmpty.jsx b/src/components/app-registration/AppManagement/AppManagementEmpty/AppManagementEmpty.jsx index 275003d4..aa798b5d 100644 --- a/src/components/app-registration/AppManagement/AppManagementEmpty/AppManagementEmpty.jsx +++ b/src/components/app-registration/AppManagement/AppManagementEmpty/AppManagementEmpty.jsx @@ -1,22 +1,19 @@ -import styles from "./AppManagementEmpty.module.scss"; -import { send } from "../../../../state/stateSignal"; -import Button from "../../..//global/Button/Button"; +import styles from './AppManagementEmpty.module.scss'; +import { send } from '../../../../state/stateSignal'; +import Button from '../../..//global/Button/Button'; export default function AppManagementEmpty() { - return ( -
    -
    -
    -
    -

    - To see your details reflected, please register your app via the - registration form. -

    + return ( +
    +
    +
    +
    +

    To see your details reflected, please register your app via the registration form.

    +
    + +
    - -
    -
    - ); + ); } diff --git a/src/components/app-registration/AppManagement/AppManagementEmpty/AppManagementEmptyLazy.jsx b/src/components/app-registration/AppManagement/AppManagementEmpty/AppManagementEmptyLazy.jsx index abfcb12a..ba97c3b5 100644 --- a/src/components/app-registration/AppManagement/AppManagementEmpty/AppManagementEmptyLazy.jsx +++ b/src/components/app-registration/AppManagement/AppManagementEmpty/AppManagementEmptyLazy.jsx @@ -1,22 +1,19 @@ -import { Suspense, lazy } from "react"; -import { useSelector } from "@xstate/react"; -import { isManageAppsEmptySelector } from "../../../../state/selectors"; -import { stateService } from "../../../../state/stateSignal"; -import DelayedFallback from "../../../global/DelayedFallback/DelayedFallback"; +import { Suspense, lazy } from 'react'; +import { useSelector } from '@xstate/react'; +import { isManageAppsEmptySelector } from '../../../../state/selectors'; +import { stateService } from '../../../../state/stateSignal'; +import DelayedFallback from '../../../global/DelayedFallback/DelayedFallback'; -const LazyAppManagementEmpty = lazy(() => import("./AppManagementEmpty")); +const LazyAppManagementEmpty = lazy(() => import('./AppManagementEmpty')); export default function AppManagementEmptyLazy() { - const isManageAppsEmpty = useSelector( - stateService, - isManageAppsEmptySelector - ); - if (!isManageAppsEmpty) { - return null; - } - return ( - }> - - - ); + const isManageAppsEmpty = useSelector(stateService, isManageAppsEmptySelector); + if (!isManageAppsEmpty) { + return null; + } + return ( + }> + + + ); } diff --git a/src/components/app-registration/AppManagement/AppManagementLazy.jsx b/src/components/app-registration/AppManagement/AppManagementLazy.jsx index 4b8b7403..377d2005 100644 --- a/src/components/app-registration/AppManagement/AppManagementLazy.jsx +++ b/src/components/app-registration/AppManagement/AppManagementLazy.jsx @@ -1,20 +1,20 @@ // load lazy suspendse AppManagement.jsx -import { lazy, Suspense } from "react"; -import { useSelector } from "@xstate/react"; -import { isManageAppsTabSelector } from "../../../state/selectors"; -import { stateService } from "../../../state/stateSignal"; -import DelayedFallback from "../../global/DelayedFallback/DelayedFallback"; +import { lazy, Suspense } from 'react'; +import { useSelector } from '@xstate/react'; +import { isManageAppsTabSelector } from '../../../state/selectors'; +import { stateService } from '../../../state/stateSignal'; +import DelayedFallback from '../../global/DelayedFallback/DelayedFallback'; -const LazyAppManagement = lazy(() => import("./AppManagement")); +const LazyAppManagement = lazy(() => import('./AppManagement')); export default function AppManagementLazy() { - const isManageAppsTab = useSelector(stateService, isManageAppsTabSelector); - if (!isManageAppsTab) { - return null; - } - return ( - }> - - - ); + const isManageAppsTab = useSelector(stateService, isManageAppsTabSelector); + if (!isManageAppsTab) { + return null; + } + return ( + }> + + + ); } diff --git a/src/components/app-registration/AppRegistration/AppRegistrationForm/AppRegistrationForm.tsx b/src/components/app-registration/AppRegistration/AppRegistrationForm/AppRegistrationForm.tsx index 9075ce09..ce3d2fba 100644 --- a/src/components/app-registration/AppRegistration/AppRegistrationForm/AppRegistrationForm.tsx +++ b/src/components/app-registration/AppRegistration/AppRegistrationForm/AppRegistrationForm.tsx @@ -66,9 +66,7 @@ export default function AppRegistrationForm() {

    App information

    - - Paste your API token with the admin scope here. - + Paste your API token with the admin scope here.
    @@ -126,8 +124,8 @@ export default function AppRegistrationForm() {

    Markup

    - You can earn commission by adding a markup to the price of each trade. Enter your - markup percentage here. + You can earn commission by adding a markup to the price of each trade. Enter + your markup percentage here.
    @@ -173,8 +171,8 @@ export default function AppRegistrationForm() {

    OAuth details

    - This allows clients to log in to your app using their Deriv accounts without an API - token. + This allows clients to log in to your app using their Deriv accounts without an + API token.
    @@ -242,9 +240,7 @@ export default function AppRegistrationForm() {

    Scope of authorisation

    - - Select the scope for your app: - + Select the scope for your app:
    diff --git a/src/components/app-registration/AppRegistration/AppRegistrationForm/DeleteAppDialog/DeleteAppDialog.jsx b/src/components/app-registration/AppRegistration/AppRegistrationForm/DeleteAppDialog/DeleteAppDialog.jsx index cdf3da37..14a82ea6 100644 --- a/src/components/app-registration/AppRegistration/AppRegistrationForm/DeleteAppDialog/DeleteAppDialog.jsx +++ b/src/components/app-registration/AppRegistration/AppRegistrationForm/DeleteAppDialog/DeleteAppDialog.jsx @@ -1,32 +1,32 @@ -import { useSelector } from "@xstate/react"; -import { lazy, Suspense } from "react"; -import { isDeletingAppModal } from "../../../../../state/selectors"; -import { stateService } from "../../../../../state/stateSignal"; +import { useSelector } from '@xstate/react'; +import { lazy, Suspense } from 'react'; +import { isDeletingAppModal } from '../../../../../state/selectors'; +import { stateService } from '../../../../../state/stateSignal'; -const Modal = lazy(() => import("../../../../global/Modal/Modal")); +const Modal = lazy(() => import('../../../../global/Modal/Modal')); export default function DeleteAppDialogLazy({ deleteApp }) { - const isModalOpen = useSelector(stateService, isDeletingAppModal); - if (!isModalOpen) { - return null; - } - return ( - }> - stateService.send("CANCEL")} - onPrimaryButtonClick={() => { - deleteApp(); - }} - onSecondaryButtonClick={() => { - stateService.send("CANCEL"); - }} - /> - - ); + const isModalOpen = useSelector(stateService, isDeletingAppModal); + if (!isModalOpen) { + return null; + } + return ( + }> + stateService.send('CANCEL')} + onPrimaryButtonClick={() => { + deleteApp(); + }} + onSecondaryButtonClick={() => { + stateService.send('CANCEL'); + }} + /> + + ); } diff --git a/src/components/app-registration/AppRegistration/AppRegistrationForm/RegisterAppDialogError/RegisterAppDialogError.tsx b/src/components/app-registration/AppRegistration/AppRegistrationForm/RegisterAppDialogError/RegisterAppDialogError.tsx index 7fdd488b..2d9990a4 100644 --- a/src/components/app-registration/AppRegistration/AppRegistrationForm/RegisterAppDialogError/RegisterAppDialogError.tsx +++ b/src/components/app-registration/AppRegistration/AppRegistrationForm/RegisterAppDialogError/RegisterAppDialogError.tsx @@ -1,36 +1,36 @@ -import { useSelector } from "@xstate/react"; -import { lazy, Suspense } from "react"; -import { isRegisterErrorSelector } from "../../../../../state/selectors"; -import { stateService } from "../../../../../state/stateSignal"; -import DelayedFallback from "../../../../global/DelayedFallback/DelayedFallback"; +import { useSelector } from '@xstate/react'; +import { lazy, Suspense } from 'react'; +import { isRegisterErrorSelector } from '../../../../../state/selectors'; +import { stateService } from '../../../../../state/stateSignal'; +import DelayedFallback from '../../../../global/DelayedFallback/DelayedFallback'; -const Modal = lazy(() => import("../../../../global/Modal/Modal")); +const Modal = lazy(() => import('../../../../global/Modal/Modal')); export default function RegisterAppDialogError({ error }) { - const isModalOpen = useSelector(stateService, isRegisterErrorSelector); - if (!isModalOpen) { - return null; - } - const catchError = () => { - if (error && error.error?.code === "InvalidToken") { - return "Enter your API token (with the Admin scope) to register your app."; - } else if (error) { - return error.error?.message; + const isModalOpen = useSelector(stateService, isRegisterErrorSelector); + if (!isModalOpen) { + return null; } - }; - return ( - }> - stateService.send("CLOSE_MODAL")} - onSecondaryButtonClick={() => { - stateService.send("CLOSE_MODAL"); - }} - /> - - ); + const catchError = () => { + if (error && error.error?.code === 'InvalidToken') { + return 'Enter your API token (with the Admin scope) to register your app.'; + } else if (error) { + return error.error?.message; + } + }; + return ( + }> + stateService.send('CLOSE_MODAL')} + onSecondaryButtonClick={() => { + stateService.send('CLOSE_MODAL'); + }} + /> + + ); } diff --git a/src/components/app-registration/AppRegistration/AppRegistrationLogin/AppRegistrationLogin.tsx b/src/components/app-registration/AppRegistration/AppRegistrationLogin/AppRegistrationLogin.tsx index f44db7eb..b1aa91c7 100644 --- a/src/components/app-registration/AppRegistration/AppRegistrationLogin/AppRegistrationLogin.tsx +++ b/src/components/app-registration/AppRegistration/AppRegistrationLogin/AppRegistrationLogin.tsx @@ -1,19 +1,14 @@ -import { oauthUrl } from "../../../../global-functions/appRegistrationEffects"; +import { oauthUrl } from '../../../../global-functions/appRegistrationEffects'; export default function AppRegistrationLogin() { - return ( -
    -
    -
    - Log in to your Deriv account to get the API token and start using our - API. -
    - - Log in to my Deriv account - -
    - ); + return ( +
    +
    +
    + Log in to your Deriv account to get the API token and start using our API. +
    + + Log in to my Deriv account + +
    + ); } diff --git a/src/components/app-registration/AppRegistration/RegisterAppDialogSuccess/RegisterAppDialogSuccess.tsx b/src/components/app-registration/AppRegistration/RegisterAppDialogSuccess/RegisterAppDialogSuccess.tsx index 021cf46a..d7708a46 100644 --- a/src/components/app-registration/AppRegistration/RegisterAppDialogSuccess/RegisterAppDialogSuccess.tsx +++ b/src/components/app-registration/AppRegistration/RegisterAppDialogSuccess/RegisterAppDialogSuccess.tsx @@ -1,41 +1,38 @@ -import { useSelector } from "@xstate/react"; -import { lazy, Suspense } from "react"; -import { - isRegisterSuccessSelector, - isUpdateModeSelector, -} from "../../../../state/selectors"; -import { stateService } from "../../../../state/stateSignal"; +import { useSelector } from '@xstate/react'; +import { lazy, Suspense } from 'react'; +import { isRegisterSuccessSelector, isUpdateModeSelector } from '../../../../state/selectors'; +import { stateService } from '../../../../state/stateSignal'; -const Modal = lazy(() => import("../../../global/Modal/Modal")); +const Modal = lazy(() => import('../../../global/Modal/Modal')); export default function RegisterAppDialogSuccess() { - const isModalOpen = useSelector(stateService, isRegisterSuccessSelector); - const isUpdateMode = useSelector(stateService, isUpdateModeSelector); - const description = isUpdateMode - ? "Your app has been updated successfully." - : "You have successfully registered your application. You can now start using Deriv API."; - const primaryButtonText = isUpdateMode ? null : "Manage application"; - if (!isModalOpen) { - return null; - } - const closeModal = () => { - stateService.send("CLOSE_MODAL"); - }; - return ( - }> - { - stateService.send("MANAGE_TOGGLE_TAB"); - }} - onSecondaryButtonClick={closeModal} - /> - - ); + const isModalOpen = useSelector(stateService, isRegisterSuccessSelector); + const isUpdateMode = useSelector(stateService, isUpdateModeSelector); + const description = isUpdateMode + ? 'Your app has been updated successfully.' + : 'You have successfully registered your application. You can now start using Deriv API.'; + const primaryButtonText = isUpdateMode ? null : 'Manage application'; + if (!isModalOpen) { + return null; + } + const closeModal = () => { + stateService.send('CLOSE_MODAL'); + }; + return ( + }> + { + stateService.send('MANAGE_TOGGLE_TAB'); + }} + onSecondaryButtonClick={closeModal} + /> + + ); } diff --git a/src/components/app-registration/AppRegistration/RegisterAppTabs/RegisteredAppTabs.tsx b/src/components/app-registration/AppRegistration/RegisterAppTabs/RegisteredAppTabs.tsx index 8ef8efe3..0dae9682 100644 --- a/src/components/app-registration/AppRegistration/RegisterAppTabs/RegisteredAppTabs.tsx +++ b/src/components/app-registration/AppRegistration/RegisterAppTabs/RegisteredAppTabs.tsx @@ -1,22 +1,14 @@ -import { send } from "../../../../state/stateSignal"; +import { send } from '../../../../state/stateSignal'; export default function RegisteredAppTabs() { - return ( -
    - - -
    - ); + return ( +
    + + +
    + ); } diff --git a/src/components/bounty/Bounty/Bounty.jsx b/src/components/bounty/Bounty/Bounty.jsx index ed48caa1..34656431 100644 --- a/src/components/bounty/Bounty/Bounty.jsx +++ b/src/components/bounty/Bounty/Bounty.jsx @@ -1,44 +1,32 @@ -import styles from "./Bounty.module.scss"; -import Button from "../../global/Button/Button"; +import styles from './Bounty.module.scss'; +import Button from '../../global/Button/Button'; export default function BugBounty() { - return ( -
    -

    Bug bounty

    -
    -
    - Want to help us enhance our security? + return ( +
    +

    Bug bounty

    +
    +
    Want to help us enhance our security?
    +

    + Test our products and services for security vulnerabilities and earn a monetary reward for any + verifiable issues that you find, courtesy of our bug bounty programme. +

    +
    +
    +
    +
    Explore our bounty programme
    + + + +
    +
    +
    Got questions?
    +

    + Email us at + security@deriv.com for more information. +

    +
    +
    -

    - Test our products and services for security vulnerabilities and earn a - monetary reward for any verifiable issues that you find, courtesy of - our bug bounty programme. -

    -
    -
    -
    -
    - Explore our bounty programme -
    - - - -
    -
    -
    - Got questions? -
    -

    - Email us at - security@deriv.com for more - information. -

    -
    -
    -
    - ); + ); } diff --git a/src/components/build-your-app/BuildYourApp/BuildYourApp.tsx b/src/components/build-your-app/BuildYourApp/BuildYourApp.tsx index c931bb2e..529cbad1 100644 --- a/src/components/build-your-app/BuildYourApp/BuildYourApp.tsx +++ b/src/components/build-your-app/BuildYourApp/BuildYourApp.tsx @@ -1,31 +1,57 @@ -import { oauthUrl } from "../../../global-functions/appRegistrationEffects"; +import { oauthUrl } from '../../../global-functions/appRegistrationEffects'; export default function BuildYourApp() { return (

    Build your app

    1. Open a Deriv account
    -

    Sign up for a Deriv account (either a demo or a real account) at no charge.

    +

    + Sign up for a Deriv account (either a demo or a real account) + at no charge. +

    2. Create an API token
    -

    To gain access to the Deriv API, you'll need an API token with the Admin scope. We'll use this token to tag your application to your Deriv account.

    +

    + To gain access to the Deriv API, you'll need an API token with the Admin scope. We'll use this token + to tag your application to your Deriv account. +

    Follow these steps to create an API token:

    -
      -
    • Log in to your Deriv account and go to Manage account settings > API token.
    • -
    • Select the Admin scope, enter a name for your token, and click Create.
    • -
    • Your API token will appear in the list at the bottom of the screen. You'll need it for the next step.
    • +
        +
      • + Log in to your Deriv account and go to{' '} + Manage account settings > API token. +
      • +
      • + Select the Admin scope, enter a name for your token, and click{' '} + Create. +
      • +
      • + Your API token will appear in the list at the bottom of the screen. You'll need it for the next + step. +
    3. Register your application
    -

    You'll get your app ID when you register your application. With this app ID and the API token from the previous step, your application can talk to the Deriv API. Also, whenever you need support, just quote your app ID when talking to our Customer Support team.

    +

    + You'll get your app ID when you register your application. With this app ID and the API token from + the previous step, your application can talk to the Deriv API. Also, whenever you need support, just + quote your app ID when talking to our Customer Support team. +

    Follow these steps to register your application:

    -
      -
    • Log in to your Deriv account and complete this form. Remember the API token you created during the previous step? You'll need it in this step.
    • -
    • After your application is registered, it will appear in the Manage existing applications tab. You may now delete your API token.
    • +
        +
      • + Log in to your Deriv account and{' '} + complete this form. Remember the API token you created during + the previous step? You'll need it in this step. +
      • +
      • + After your application is registered, it will appear in the{' '} + Manage existing applications tab. You may now delete your API token. +
    - ) + ); } diff --git a/src/components/docs/Docs/Docs.jsx b/src/components/docs/Docs/Docs.jsx index e55f86f5..32c5a573 100644 --- a/src/components/docs/Docs/Docs.jsx +++ b/src/components/docs/Docs/Docs.jsx @@ -1,20 +1,20 @@ -import { Outlet } from "react-router-dom"; -import { Suspense } from "react"; -import Sidebar from "./Sidebar/Sidebar"; -import "../../../index.scss"; -import DelayedFallback from "../../global/DelayedFallback/DelayedFallback"; +import { Outlet } from 'react-router-dom'; +import { Suspense } from 'react'; +import Sidebar from './Sidebar/Sidebar'; +import '../../../index.scss'; +import DelayedFallback from '../../global/DelayedFallback/DelayedFallback'; function Docs() { - return ( -
    - -
    - }> - - -
    -
    - ); + return ( +
    + +
    + }> + + +
    +
    + ); } export default Docs; diff --git a/src/components/docs/Docs/Sidebar/Sidebar.jsx b/src/components/docs/Docs/Sidebar/Sidebar.jsx index d32283a3..6dd5bfc6 100644 --- a/src/components/docs/Docs/Sidebar/Sidebar.jsx +++ b/src/components/docs/Docs/Sidebar/Sidebar.jsx @@ -1,12 +1,8 @@ import styles from './Sidebar.module.scss'; import React from 'react'; -import { - sidebar_routes, - SidebarMenuItems, -} from '../../../../routes-data/sidebar-routes'; +import { sidebar_routes, SidebarMenuItems } from '../../../../routes-data/sidebar-routes'; const Sidebar = () => { - return (

    Documentation

    @@ -14,7 +10,7 @@ const Sidebar = () => {
    - ); + ); }; export default Sidebar; diff --git a/src/components/faq/Faq/Faq.jsx b/src/components/faq/Faq/Faq.jsx index c2014dec..8f3dd6ef 100644 --- a/src/components/faq/Faq/Faq.jsx +++ b/src/components/faq/Faq/Faq.jsx @@ -1,156 +1,136 @@ -import React from "react"; -import Accordion from "../../global/Accordion/Accordion"; -import AccordionItem from "../../global/Accordion/AccordionItem"; -import styles from "./Faq.module.scss"; -import CodeContent from "../../global/CodeBlock/CodeContent"; +import React from 'react'; +import Accordion from '../../global/Accordion/Accordion'; +import AccordionItem from '../../global/Accordion/AccordionItem'; +import styles from './Faq.module.scss'; +import CodeContent from '../../global/CodeBlock/CodeContent'; const FAQ = () => { - return ( -
    -
    -

    FAQ

    - - -

    - View our code samples. - You can use these code snippets in your app to open a connection - to our WebSocket API service. Explore our - API explorer for the method calls - you need for your app. -

    -
    - -

    - Simply copy our open-source code and adapt it for your needs. - Follow these steps to get started: -

    -
      -
    1. - Open a GitHub account. -
    2. -
    3. - Download the{" "} - - GitHub Desktop application - - . -
    4. -
    5. - Fork any of our{" "} - - open-source front-end repositories - - . -
    6. -
    7. Make the code changes in your fork.
    8. -
    9. - Publish your fork using the{" "} - GitHub Pages facility. -
    10. -
    11. - For SSL and website acceleration for your app, open a free - account on - Cloudflare. -
    12. -
    -
    - -

    - Sure! You may hire developers who are familiar with JavaScript and - WebSocket technology to build your app for you. -

    -
    - -

    Yes! Follow these steps:

    -
      -
    1. - Sign up as an{" "} - affiliate - . -
    2. -
    3. - Insert your affiliate token into the{" "} - - new_account_virtual - {" "} - call in your app. -
    4. -
    -
    - -

    Here are some ways:

    -
      -
    1. - Sign up as a{" "} - - payment agent - {" "} - to process local payments for our clients in your country. You - may automate your payment agent facility using the{" "} - - paymentagent_transfer - {" "} - API call. -
    2. -
    3. - If you are prepared to offer higher contract prices than ours, - you may add a markup percentage when you - register your app. This is - a percentage of contract payouts, and it’s added to all contract - prices in your app. The aggregate markup is paid to you around - the 15th of every month. Sign up as our affiliate and contact - your Affiliate Manager to learn more. -
    4. -
    -
    - -

    - This means we will treat the value of this property as confidential, - and will never return it in any API response. It is used for - passwords and tokens. -

    -
    - -

    - Copy trading allows a client (the Copier) to automatically copy - the trades of another client (the Trader). -

    -

    - To allow others to copy your trades, set the ‘allow_copiers’ - setting via the{" "} - set settings call. -

    -

    - The Trader may create a read-only API token and provide it to the - Copier. -

    -

    - Enabling ‘allow_copiers’ will also make the copytrading statistics - call available. The statistics call provides the information about - an account. This is so that potential copiers have an idea about - the trader’s past performance. -

    -

    - To start copying, use the{" "} - copy start call. To stop - copying, use copy stop. -

    -
    - -

    - Use the website status{" "} - call to check whether the website is online or not. -

    -
    - -

    - This JavaScript code opens a WebSocket and makes a subscription - for server status notifications. When a message is received, it - sends the website status message, if available: -

    - +
    +

    FAQ

    + + +

    + View our code samples. You can use these code + snippets in your app to open a connection to our WebSocket API service. Explore our + API explorer for the method calls you need for your app. +

    +
    + +

    + Simply copy our open-source code and adapt it for your needs. Follow these steps to get + started: +

    +
      +
    1. + Open a GitHub account. +
    2. +
    3. + Download the GitHub Desktop application. +
    4. +
    5. + Fork any of our{' '} + + open-source front-end repositories + + . +
    6. +
    7. Make the code changes in your fork.
    8. +
    9. + Publish your fork using the GitHub Pages{' '} + facility. +
    10. +
    11. + For SSL and website acceleration for your app, open a free account on + Cloudflare. +
    12. +
    +
    + +

    + Sure! You may hire developers who are familiar with JavaScript and WebSocket technology to + build your app for you. +

    +
    + +

    Yes! Follow these steps:

    +
      +
    1. + Sign up as an affiliate. +
    2. +
    3. + Insert your affiliate token into the{' '} + + new_account_virtual + {' '} + call in your app. +
    4. +
    +
    + +

    Here are some ways:

    +
      +
    1. + Sign up as a payment agent to + process local payments for our clients in your country. You may automate your payment + agent facility using the{' '} + + paymentagent_transfer + {' '} + API call. +
    2. +
    3. + If you are prepared to offer higher contract prices than ours, you may add a{' '} + markup percentage when you + register your app. This is a percentage of contract + payouts, and it’s added to all contract prices in your app. The aggregate markup is paid + to you around the 15th of every month. Sign up as our affiliate and contact your + Affiliate Manager to learn more. +
    4. +
    +
    + +

    + This means we will treat the value of this property as confidential, and will never return + it in any API response. It is used for passwords and tokens. +

    +
    + +

    + Copy trading allows a client (the Copier) to automatically copy the trades of another client + (the Trader). +

    +

    + To allow others to copy your trades, set the ‘allow_copiers’ setting via the{' '} + set settings call. +

    +

    The Trader may create a read-only API token and provide it to the Copier.

    +

    + Enabling ‘allow_copiers’ will also make the copytrading statistics call available. The + statistics call provides the information about an account. This is so that potential copiers + have an idea about the trader’s past performance. +

    +

    + To start copying, use the copy start call. To stop + copying, use copy stop. +

    +
    + +

    + Use the website status call to check whether the + website is online or not. +

    +
    + +

    + This JavaScript code opens a WebSocket and makes a subscription for server status + notifications. When a message is received, it sends the website status message, if + available: +

    + { } }); `} - /> -
    - -

    - Visit our{" "} - dev forum or - email - - {" "} - api-support@deriv.com - - . -

    -
    -
    -
    -
    - ); + /> + + +

    + Visit our dev forum or email + api-support@deriv.com. +

    +
    + +
    +
    + ); }; export default FAQ; diff --git a/src/components/global/Accordion/Accordion.jsx b/src/components/global/Accordion/Accordion.jsx index 231fac47..170a1b91 100644 --- a/src/components/global/Accordion/Accordion.jsx +++ b/src/components/global/Accordion/Accordion.jsx @@ -1,8 +1,8 @@ -import React from "react"; -import styles from "./Accordion.module.scss"; +import React from 'react'; +import styles from './Accordion.module.scss'; const Accordion = ({ children }) => { - return
    {children}
    ; + return
    {children}
    ; }; export default Accordion; diff --git a/src/components/global/Accordion/AccordionItem.jsx b/src/components/global/Accordion/AccordionItem.jsx index 194e41ae..fcd69f9e 100644 --- a/src/components/global/Accordion/AccordionItem.jsx +++ b/src/components/global/Accordion/AccordionItem.jsx @@ -1,33 +1,23 @@ -import React from "react"; -import styles from "./Accordion.module.scss"; +import React from 'react'; +import styles from './Accordion.module.scss'; const AccordionItem = ({ children, title }) => { - const [is_content_visible, setContentVisible] = React.useState(false); - const togglePanel = () => { - setContentVisible(!is_content_visible); - }; - return ( -
    -
    -
    {title}
    -
    -
    - {is_content_visible && ( -
    {children}
    - )} -
    - ); + const [is_content_visible, setContentVisible] = React.useState(false); + const togglePanel = () => { + setContentVisible(!is_content_visible); + }; + return ( +
    +
    +
    {title}
    +
    +
    + {is_content_visible &&
    {children}
    } +
    + ); }; export default AccordionItem; diff --git a/src/components/global/Button/Button.tsx b/src/components/global/Button/Button.tsx index 9796e8dc..00c366d8 100644 --- a/src/components/global/Button/Button.tsx +++ b/src/components/global/Button/Button.tsx @@ -1,23 +1,23 @@ -import styles from "./Button.module.scss"; +import styles from './Button.module.scss'; export default function Button({ - type = "", - disabled, - onClick, - children, + type = '', + disabled, + onClick, + children, }: { - type?: string; - disabled?: boolean; - onClick?: () => void | undefined; - children: React.ReactNode; + type?: string; + disabled?: boolean; + onClick?: () => void | undefined; + children: React.ReactNode; }) { - let classesNames = `${styles.btn}`; - if (type === "secondary") { - classesNames += ` ${styles.secondary}`; - } - return ( - - ); + let classesNames = `${styles.btn}`; + if (type === 'secondary') { + classesNames += ` ${styles.secondary}`; + } + return ( + + ); } diff --git a/src/components/global/CodeBlock/CodeBlock.jsx b/src/components/global/CodeBlock/CodeBlock.jsx index e0970913..5a0ac3c5 100644 --- a/src/components/global/CodeBlock/CodeBlock.jsx +++ b/src/components/global/CodeBlock/CodeBlock.jsx @@ -1,35 +1,31 @@ -import React, { useState, useEffect } from "react"; -import CodeContent from "./CodeContent"; -import CopyButton from "./CopyButton"; -import styles from "./CodeBlock.module.scss"; +import React, { useState, useEffect } from 'react'; +import CodeContent from './CodeContent'; +import CopyButton from './CopyButton'; +import styles from './CodeBlock.module.scss'; const CodeBlock = ({ id }) => { - const [file_content, setFileContent] = useState(" "); - useEffect(() => { - const file_path = `/demos/demos/${id}-javascript.jscode`; - fetch(file_path) - .then((response) => response.text()) - .then((data) => { - const formatted_code = data - .replaceAll("<", "<") - .replaceAll(">", ">"); - setFileContent(formatted_code); - }); - }, [id]); + const [file_content, setFileContent] = useState(' '); + useEffect(() => { + const file_path = `/demos/demos/${id}-javascript.jscode`; + fetch(file_path) + .then(response => response.text()) + .then(data => { + const formatted_code = data.replaceAll('<', '<').replaceAll('>', '>'); + setFileContent(formatted_code); + }); + }, [id]); - return ( -
    -
    -
    -

    - Javascript -

    - + return ( +
    +
    +
    +

    Javascript

    + +
    + +
    - -
    -
    - ); + ); }; export default CodeBlock; diff --git a/src/components/global/CodeBlock/CodeBlockSingleLanguage.jsx b/src/components/global/CodeBlock/CodeBlockSingleLanguage.jsx index e708bd07..9d9010c3 100644 --- a/src/components/global/CodeBlock/CodeBlockSingleLanguage.jsx +++ b/src/components/global/CodeBlock/CodeBlockSingleLanguage.jsx @@ -1,12 +1,12 @@ -import CodeContent from "./CodeContent"; -import CopyButton from "./CopyButton"; -import styles from "./CodeBlockSingleLanguage.module.scss"; +import CodeContent from './CodeContent'; +import CopyButton from './CopyButton'; +import styles from './CodeBlockSingleLanguage.module.scss'; export default function CodeBlockSingleLanguage({ lang, content }) { - return ( -
    - - -
    - ); + return ( +
    + + +
    + ); } diff --git a/src/components/global/CodeBlock/CodeContent.jsx b/src/components/global/CodeBlock/CodeContent.jsx index 2f92a40e..8d1d47cf 100644 --- a/src/components/global/CodeBlock/CodeContent.jsx +++ b/src/components/global/CodeBlock/CodeContent.jsx @@ -1,56 +1,56 @@ -import React from "react"; -import Prism from "prismjs"; -import "./prism.css"; -import "prismjs/components/prism-markup-templating"; -import "prismjs/components/prism-javascript"; -import "prismjs/components/prism-json"; -import "prismjs/plugins/custom-class/prism-custom-class"; -import styles from "./CodeBlock.module.scss"; +import React from 'react'; +import Prism from 'prismjs'; +import './prism.css'; +import 'prismjs/components/prism-markup-templating'; +import 'prismjs/components/prism-javascript'; +import 'prismjs/components/prism-json'; +import 'prismjs/plugins/custom-class/prism-custom-class'; +import styles from './CodeBlock.module.scss'; const CodeContent = ({ lang, data }) => { - const useIsMounted = () => { - const is_mounted = React.useRef(false); + const useIsMounted = () => { + const is_mounted = React.useRef(false); - React.useEffect(() => { - is_mounted.current = true; + React.useEffect(() => { + is_mounted.current = true; - return () => { - is_mounted.current = false; - }; - }, []); - return () => is_mounted.current; - }; + return () => { + is_mounted.current = false; + }; + }, []); + return () => is_mounted.current; + }; - const [showdata, setshowdata] = React.useState(false); - const isMounted = useIsMounted(); - React.useEffect(() => { - if (isMounted()) { - setshowdata(true); - Prism.highlightAll(); - } - }, [lang, data, isMounted]); + const [showdata, setshowdata] = React.useState(false); + const isMounted = useIsMounted(); + React.useEffect(() => { + if (isMounted()) { + setshowdata(true); + Prism.highlightAll(); + } + }, [lang, data, isMounted]); - Prism.plugins.customClass.add(({ content, language }) => { - if (content === "function") { - return "storage-function"; - } - if (content === "<?php") { - return "operator-php"; - } - if (language === "json") { - return "json"; - } - }); + Prism.plugins.customClass.add(({ content, language }) => { + if (content === 'function') { + return 'storage-function'; + } + if (content === '<?php') { + return 'operator-php'; + } + if (language === 'json') { + return 'json'; + } + }); - return ( - - {showdata && ( -
    -          {data}
    -        
    - )} -
    - ); + return ( + + {showdata && ( +
    +                    {data}
    +                
    + )} +
    + ); }; export default CodeContent; diff --git a/src/components/global/CodeBlock/CopyButton.jsx b/src/components/global/CodeBlock/CopyButton.jsx index 9fe9664c..d012fa0f 100644 --- a/src/components/global/CodeBlock/CopyButton.jsx +++ b/src/components/global/CodeBlock/CopyButton.jsx @@ -1,22 +1,18 @@ -import React from "react"; -import styles from "./CopyButton.module.scss"; +import React from 'react'; +import styles from './CopyButton.module.scss'; const CopyButton = ({ content_to_copy }) => { - const handleCopyButtonClick = () => { - navigator.clipboard.writeText(content_to_copy); - }; - return ( -
    -
    -
    -
    Copy
    -
    -
    - ); + const handleCopyButtonClick = () => { + navigator.clipboard.writeText(content_to_copy); + }; + return ( +
    +
    +
    +
    Copy
    +
    +
    + ); }; export default CopyButton; diff --git a/src/components/global/CodeBlock/prism.css b/src/components/global/CodeBlock/prism.css index 349057a0..b9cd5e2e 100644 --- a/src/components/global/CodeBlock/prism.css +++ b/src/components/global/CodeBlock/prism.css @@ -1,30 +1,30 @@ .token.comment { - color: #75715e; + color: #75715e; } .operator-php { - display: inline-block; + display: inline-block; } .token.keyword, .token.operator, .operator-php::first-letter, .token.property.json { - color: #f92672; + color: #f92672; } .token.operator.json { - color: white; + color: white; } .token.string { - color: #e6db74; + color: #e6db74; } .token.number { - color: #ae81ff; + color: #ae81ff; } .storage-function { - font-style: italic; - color: #66d9ef !important; + font-style: italic; + color: #66d9ef !important; } diff --git a/src/components/global/DelayedFallback/DelayedFallback.jsx b/src/components/global/DelayedFallback/DelayedFallback.jsx index d2b8cfd3..e249bb32 100644 --- a/src/components/global/DelayedFallback/DelayedFallback.jsx +++ b/src/components/global/DelayedFallback/DelayedFallback.jsx @@ -1,24 +1,24 @@ -import React from "react"; -import { useState, useEffect } from "react"; -import Spinner from "../Spinner/Spinner"; -import styles from "./DelayedFallback.module.scss"; +import React from 'react'; +import { useState, useEffect } from 'react'; +import Spinner from '../Spinner/Spinner'; +import styles from './DelayedFallback.module.scss'; export default function DelayedFallback() { - const [show, setShow] = useState(false); - useEffect(() => { - let timeout = setTimeout(() => setShow(true), 300); - return () => { - clearTimeout(timeout); - }; - }, []); + const [show, setShow] = useState(false); + useEffect(() => { + let timeout = setTimeout(() => setShow(true), 300); + return () => { + clearTimeout(timeout); + }; + }, []); - return ( - - {show && ( -
    - -
    - )} -
    - ); + return ( + + {show && ( +
    + +
    + )} +
    + ); } diff --git a/src/components/global/DerivLogo/DerivLogo.tsx b/src/components/global/DerivLogo/DerivLogo.tsx index 15d32415..a6cdd507 100644 --- a/src/components/global/DerivLogo/DerivLogo.tsx +++ b/src/components/global/DerivLogo/DerivLogo.tsx @@ -1,4 +1,4 @@ -import { Link } from "react-router-dom" +import { Link } from 'react-router-dom'; import styles from './DerivLogo.module.scss'; export const DerivLogo = () => { @@ -14,5 +14,5 @@ export const DerivLogo = () => {

    API

    - ) -} + ); +}; diff --git a/src/components/global/Dialog/Dialog.jsx b/src/components/global/Dialog/Dialog.jsx index cd34ab7a..1e9a99b5 100644 --- a/src/components/global/Dialog/Dialog.jsx +++ b/src/components/global/Dialog/Dialog.jsx @@ -1,62 +1,53 @@ -import React, { useEffect, useRef } from "react"; +import React, { useEffect, useRef } from 'react'; -import { useDialogPolyfill } from "./useDialogPolyfill"; -import styles from "./Dialog.module.scss"; +import { useDialogPolyfill } from './useDialogPolyfill'; +import styles from './Dialog.module.scss'; -export default function Dialog({ - closeOnOutsideClick, - onRequestClose, - open, - ...props -}) { - const dialogRef = useRef(); +export default function Dialog({ closeOnOutsideClick, onRequestClose, open, ...props }) { + const dialogRef = useRef(); - useDialogPolyfill(dialogRef); - useDialogOpening(dialogRef, open); - useDialogClosing(dialogRef, onRequestClose); + useDialogPolyfill(dialogRef); + useDialogOpening(dialogRef, open); + useDialogClosing(dialogRef, onRequestClose); - function handleOutsideClick(event) { - const dialogNode = dialogRef.current; - if (closeOnOutsideClick && event.target === dialogNode) { - onRequestClose(); + function handleOutsideClick(event) { + const dialogNode = dialogRef.current; + if (closeOnOutsideClick && event.target === dialogNode) { + onRequestClose(); + } } - } - return ( - -
    -
    - ); + return ( + +
    +
    + ); } const useDialogOpening = (dialogRef, open) => { - const lastActiveElement = useRef(null); - useEffect(() => { - const dialogNode = dialogRef.current; - if (open) { - lastActiveElement.current = document.activeElement; - dialogNode.showModal(); - } else { - dialogNode.close(); - lastActiveElement.current.focus(); - } - }, [open]); + const lastActiveElement = useRef(null); + useEffect(() => { + const dialogNode = dialogRef.current; + if (open) { + lastActiveElement.current = document.activeElement; + dialogNode.showModal(); + } else { + dialogNode.close(); + lastActiveElement.current.focus(); + } + }, [open]); }; const useDialogClosing = (dialogRef, onRequestClose) => { - useEffect(() => { - const dialogNode = dialogRef.current; - const handleCancel = (event) => { - event.preventDefault(); - onRequestClose(); - }; - dialogNode.addEventListener("cancel", handleCancel); - return () => { - dialogNode.removeEventListener("cancel", handleCancel); - }; - }, [onRequestClose]); + useEffect(() => { + const dialogNode = dialogRef.current; + const handleCancel = event => { + event.preventDefault(); + onRequestClose(); + }; + dialogNode.addEventListener('cancel', handleCancel); + return () => { + dialogNode.removeEventListener('cancel', handleCancel); + }; + }, [onRequestClose]); }; diff --git a/src/components/global/Dialog/useDialogPolyfill.js b/src/components/global/Dialog/useDialogPolyfill.js index b3e485ed..3237597d 100644 --- a/src/components/global/Dialog/useDialogPolyfill.js +++ b/src/components/global/Dialog/useDialogPolyfill.js @@ -1,22 +1,22 @@ -import React from "react"; +import React from 'react'; let dialogPolyfill = null; if (window.HTMLDialogElement === undefined) { - import("dialog-polyfill/dialog-polyfill.css"); + import('dialog-polyfill/dialog-polyfill.css'); } export function useDialogPolyfill(ref) { - React.useLayoutEffect(() => { - if (window.HTMLDialogElement === undefined) { - if (dialogPolyfill) { - dialogPolyfill.registerDialog(ref.current); - } else { - import("dialog-polyfill").then((polyfill) => { - polyfill.default.registerDialog(ref.current); - dialogPolyfill = polyfill.default; - }); - } - } - }, [ref]); + React.useLayoutEffect(() => { + if (window.HTMLDialogElement === undefined) { + if (dialogPolyfill) { + dialogPolyfill.registerDialog(ref.current); + } else { + import('dialog-polyfill').then(polyfill => { + polyfill.default.registerDialog(ref.current); + dialogPolyfill = polyfill.default; + }); + } + } + }, [ref]); } diff --git a/src/components/global/GeneralButton/GeneralButton.jsx b/src/components/global/GeneralButton/GeneralButton.jsx index bbbdb486..8e66e388 100644 --- a/src/components/global/GeneralButton/GeneralButton.jsx +++ b/src/components/global/GeneralButton/GeneralButton.jsx @@ -1,7 +1,7 @@ const GeneralButton = ({ type, text, id, clickHandler, className }) => ( - + ); export default GeneralButton; diff --git a/src/components/global/Header/HamburgerLink.tsx b/src/components/global/Header/HamburgerLink.tsx index b5384e00..e96b9abb 100644 --- a/src/components/global/Header/HamburgerLink.tsx +++ b/src/components/global/Header/HamburgerLink.tsx @@ -1,34 +1,33 @@ -import { useEffect, useState } from "react"; -import { Link } from "react-router-dom"; -import { send } from "../../../state/stateSignal"; -import styles from "./Header.module.scss"; +import { useEffect, useState } from 'react'; +import { Link } from 'react-router-dom'; +import { send } from '../../../state/stateSignal'; +import styles from './Header.module.scss'; interface LinkProps { - location: string; - name: string; + location: string; + name: string; } export default function HamburgerLink({ location, name }: LinkProps) { - const [is_on_current_location, setIsOnCurrentLocation] = useState(false); - const location_no_slash = location.substring(0, location.length - 1); - useEffect(() => { - const is_valid_pathname = - window.location.pathname === location || - window.location.pathname === location_no_slash; - if (is_valid_pathname) { - setIsOnCurrentLocation(true); - } else { - setIsOnCurrentLocation(false); - } - }, [window.location.pathname]); + const [is_on_current_location, setIsOnCurrentLocation] = useState(false); + const location_no_slash = location.substring(0, location.length - 1); + useEffect(() => { + const is_valid_pathname = + window.location.pathname === location || window.location.pathname === location_no_slash; + if (is_valid_pathname) { + setIsOnCurrentLocation(true); + } else { + setIsOnCurrentLocation(false); + } + }, [window.location.pathname]); - return ( - send("TOGGLE_HAMBURGER")} - to={location} - > - {name} - - ); + return ( + send('TOGGLE_HAMBURGER')} + to={location} + > + {name} + + ); } diff --git a/src/components/global/Header/HamburgerNavigation.tsx b/src/components/global/Header/HamburgerNavigation.tsx index 09312234..fba1cbb1 100644 --- a/src/components/global/Header/HamburgerNavigation.tsx +++ b/src/components/global/Header/HamburgerNavigation.tsx @@ -1,21 +1,18 @@ -import styles from "./Header.module.scss"; -import HamburgerLink from "./HamburgerLink"; -import { - SidebarMenuItems, - sidebar_routes -} from "../../../routes-data/sidebar-routes" -import NavigationLinks from "./NavigationLinks/NavigationLinks"; +import styles from './Header.module.scss'; +import HamburgerLink from './HamburgerLink'; +import { SidebarMenuItems, sidebar_routes } from '../../../routes-data/sidebar-routes'; +import NavigationLinks from './NavigationLinks/NavigationLinks'; export default function HamburgerNavigation() { - return ( -
    - -
    - ); + return ( +
    + +
    + ); } diff --git a/src/components/global/Header/Header.tsx b/src/components/global/Header/Header.tsx index 4c7d02b4..1e2727fd 100644 --- a/src/components/global/Header/Header.tsx +++ b/src/components/global/Header/Header.tsx @@ -1,46 +1,46 @@ -import { useRef, useEffect } from "react"; -import { stateService } from "../../../state/stateSignal"; +import { useRef, useEffect } from 'react'; +import { stateService } from '../../../state/stateSignal'; import { send } from '../../../state/stateSignal'; -import { domains } from "../../../data-stores/domains" -import { useOutsideClick } from "../../../custom-hooks/useClickOutsideElement"; -import { Navigation } from "./Navigation"; -import { TopNav } from "./TopNav"; -import { RenderOfficialDomainContents } from "../../utility/RenderOfficialDomainContents/RenderOfficialDomainContents"; -import { LogoutButton } from "../LogoutButton/LogoutButton" -import styles from "./Header.module.scss"; +import { domains } from '../../../data-stores/domains'; +import { useOutsideClick } from '../../../custom-hooks/useClickOutsideElement'; +import { Navigation } from './Navigation'; +import { TopNav } from './TopNav'; +import { RenderOfficialDomainContents } from '../../utility/RenderOfficialDomainContents/RenderOfficialDomainContents'; +import { LogoutButton } from '../LogoutButton/LogoutButton'; +import styles from './Header.module.scss'; export default function Header() { - const ref = useRef(null); + const ref = useRef(null); - useOutsideClick(ref, () => { - stateService.send("CLICK_OUTSIDE"); - }); + useOutsideClick(ref, () => { + stateService.send('CLICK_OUTSIDE'); + }); - useEffect(() => { - // remove branding on hosts that are not Deriv - const host = window.location.host; - let is_deriv_host = false; - domains.forEach(domain => { - const host_exists = host.indexOf(domain) === 0; - if (host_exists) { - is_deriv_host = host_exists; - } - }) + useEffect(() => { + // remove branding on hosts that are not Deriv + const host = window.location.host; + let is_deriv_host = false; + domains.forEach(domain => { + const host_exists = host.indexOf(domain) === 0; + if (host_exists) { + is_deriv_host = host_exists; + } + }); - if (!is_deriv_host) { - send("TOGGLE_BRANDING_OFF"); - } - }, []) + if (!is_deriv_host) { + send('TOGGLE_BRANDING_OFF'); + } + }, []); - return ( - - ); + ); } diff --git a/src/components/global/Header/Navigation.tsx b/src/components/global/Header/Navigation.tsx index 883dd221..b8bfa13b 100644 --- a/src/components/global/Header/Navigation.tsx +++ b/src/components/global/Header/Navigation.tsx @@ -17,4 +17,4 @@ export const Navigation = () => { ); -} +}; diff --git a/src/components/global/Header/NavigationLinks/NavigationLinks.tsx b/src/components/global/Header/NavigationLinks/NavigationLinks.tsx index f5bb1355..855775ef 100644 --- a/src/components/global/Header/NavigationLinks/NavigationLinks.tsx +++ b/src/components/global/Header/NavigationLinks/NavigationLinks.tsx @@ -1,8 +1,8 @@ import { Fragment } from 'react'; import { Link, useLocation } from 'react-router-dom'; import { routes } from '../../../../Router'; -import { hidden_menu_items } from '../../../../data-stores/domains.js' -import { RenderOfficialDomainContents } from "../../../utility/RenderOfficialDomainContents/RenderOfficialDomainContents"; +import { hidden_menu_items } from '../../../../data-stores/domains.js'; +import { RenderOfficialDomainContents } from '../../../utility/RenderOfficialDomainContents/RenderOfficialDomainContents'; import styles from '../Header.module.scss'; export default function NavigationLinks() { @@ -14,7 +14,7 @@ export default function NavigationLinks() { {routes.map(route => { // Check if user is on current page location - const trimmed_route = route.path.replace(/\//g, '') + const trimmed_route = route.path.replace(/\//g, ''); const path_is_route = split_path.includes(trimmed_route); const LinkComponent = () => { return ( @@ -23,8 +23,8 @@ export default function NavigationLinks() { {route.label}
    - ) - } + ); + }; // Rendering component here. return ( @@ -32,17 +32,12 @@ export default function NavigationLinks() { {hidden_menu_items.includes(route?.path) ? ( // Hide specific links if website is rendered on non-deriv domain. - ) : - - {route?.label ? ( - - ) : null - } - - } + ) : ( + {route?.label ? : null} + )} ); })} - ) -} \ No newline at end of file + ); +} diff --git a/src/components/global/Header/TopNav.tsx b/src/components/global/Header/TopNav.tsx index 5fce50e1..61218e4d 100644 --- a/src/components/global/Header/TopNav.tsx +++ b/src/components/global/Header/TopNav.tsx @@ -1,12 +1,12 @@ -import styles from "./Header.module.scss"; +import styles from './Header.module.scss'; export const TopNav = () => { return ( - ) -} + ); +}; diff --git a/src/components/global/LogoutButton/LogoutButton.jsx b/src/components/global/LogoutButton/LogoutButton.jsx index f6da2700..bc06b00f 100644 --- a/src/components/global/LogoutButton/LogoutButton.jsx +++ b/src/components/global/LogoutButton/LogoutButton.jsx @@ -1,27 +1,27 @@ -import { useSelector } from "@xstate/react"; -import { Suspense, lazy } from "react"; -import { isLoggedInSelector } from "../../../state/selectors"; -import { stateService } from "../../../state/stateSignal"; -import styles from "./LogoutButton.module.scss"; +import { useSelector } from '@xstate/react'; +import { Suspense, lazy } from 'react'; +import { isLoggedInSelector } from '../../../state/selectors'; +import { stateService } from '../../../state/stateSignal'; +import styles from './LogoutButton.module.scss'; -const LazyButton = lazy(() => import("../Button/Button")); +const LazyButton = lazy(() => import('../Button/Button')); export const LogoutButton = () => { - const isLoggedIn = useSelector(stateService, isLoggedInSelector); - if (!isLoggedIn) { - return null; - } - return ( - }> -
    - Sign out -
    -
    - ); -} + const isLoggedIn = useSelector(stateService, isLoggedInSelector); + if (!isLoggedIn) { + return null; + } + return ( + }> +
    + Sign out +
    +
    + ); +}; const logout = () => { - stateService.send("LOGOUT"); - sessionStorage.removeItem("token1"); - location.replace("/app-registration/"); + stateService.send('LOGOUT'); + sessionStorage.removeItem('token1'); + location.replace('/app-registration/'); }; diff --git a/src/components/global/Modal/Modal.tsx b/src/components/global/Modal/Modal.tsx index 3912727c..b7479e27 100644 --- a/src/components/global/Modal/Modal.tsx +++ b/src/components/global/Modal/Modal.tsx @@ -1,51 +1,47 @@ -import Button from "../Button/Button"; -import Dialog from "../Dialog/Dialog"; -import styles from "./Modal.module.scss"; +import Button from '../Button/Button'; +import Dialog from '../Dialog/Dialog'; +import styles from './Modal.module.scss'; export default function Modal({ - onRequestClose, - open, - type, - title, - description, - primaryButtonText, - secondaryButtonText, - onPrimaryButtonClick, - onSecondaryButtonClick, + onRequestClose, + open, + type, + title, + description, + primaryButtonText, + secondaryButtonText, + onPrimaryButtonClick, + onSecondaryButtonClick, }: { - onRequestClose: () => void; - open: any; - type: "success" | "warning"; - title: string; - description: string; - primaryButtonText?: any; - secondaryButtonText: string; - onPrimaryButtonClick?: () => void; - onSecondaryButtonClick: () => void; + onRequestClose: () => void; + open: any; + type: 'success' | 'warning'; + title: string; + description: string; + primaryButtonText?: any; + secondaryButtonText: string; + onPrimaryButtonClick?: () => void; + onSecondaryButtonClick: () => void; }) { - return ( - -
    -
    -
    -
    - {type === "success" &&
    } - {type === "warning" &&
    } -
    {title}
    -
    - - {description} - -
    -
    -
    - - {primaryButtonText && ( - - )} -
    -
    - ); + return ( + +
    +
    +
    +
    + {type === 'success' &&
    } + {type === 'warning' &&
    } +
    {title}
    +
    + {description} +
    +
    +
    + + {primaryButtonText && } +
    +
    + ); } diff --git a/src/components/global/ResetSendButtonsBlock/ResetSendButtonsBlock.jsx b/src/components/global/ResetSendButtonsBlock/ResetSendButtonsBlock.jsx index 4cefa8ba..d84fab5e 100644 --- a/src/components/global/ResetSendButtonsBlock/ResetSendButtonsBlock.jsx +++ b/src/components/global/ResetSendButtonsBlock/ResetSendButtonsBlock.jsx @@ -1,43 +1,47 @@ -import Button from "../GeneralButton/GeneralButton"; -import React from "react"; -import style from "./ResetSendButtonsBlock.module.scss"; -import { ticksSubject } from "../../../global-functions/ticksSubject"; - -export const ResetSendButtonsBlock = ( - ({ isAppRegistration, sendRequest, resetMessagesInConsole, current_api, setIsScrolling, setScrollDirection }) => { +import Button from '../GeneralButton/GeneralButton'; +import React from 'react'; +import style from './ResetSendButtonsBlock.module.scss'; +import { ticksSubject } from '../../../global-functions/ticksSubject'; +export const ResetSendButtonsBlock = ({ + isAppRegistration, + sendRequest, + resetMessagesInConsole, + current_api, + setIsScrolling, + setScrollDirection, +}) => { const onClick = () => { - setScrollDirection("down"); - current_api.connection.close(); - ticksSubject.complete(); - resetMessagesInConsole?.([]); - setIsScrolling?.(true) - } - return ( -
    -
    -
    -
    -
    +
    +
    -
    ); - } -); +}; -ResetSendButtonsBlock.displayName = "ResetSendButtonsBlock"; +ResetSendButtonsBlock.displayName = 'ResetSendButtonsBlock'; export default ResetSendButtonsBlock; diff --git a/src/components/global/SandboxPage/SandboxPage.tsx b/src/components/global/SandboxPage/SandboxPage.tsx index 7793b139..4bcad4e6 100644 --- a/src/components/global/SandboxPage/SandboxPage.tsx +++ b/src/components/global/SandboxPage/SandboxPage.tsx @@ -1,26 +1,22 @@ -import React from "react"; -import { SandboxIframe } from "../../utility/SandboxIframe/SandboxIframe"; +import React from 'react'; +import { SandboxIframe } from '../../utility/SandboxIframe/SandboxIframe'; interface SandboxPageProps { - title: string, + title: string; description: { before: React.ReactNode; after: React.ReactNode; - }, - sandbox: string + }; + sandbox: string; } export default function SandboxPage({ title, description, sandbox }: SandboxPageProps) { return (

    {title}

    - - {description?.before} - + {description?.before} - - {description?.after} - + {description?.after}
    ); } diff --git a/src/components/global/SkeletonText/SkeletonText.jsx b/src/components/global/SkeletonText/SkeletonText.jsx index 0284d9c0..cc0945aa 100644 --- a/src/components/global/SkeletonText/SkeletonText.jsx +++ b/src/components/global/SkeletonText/SkeletonText.jsx @@ -1,5 +1,5 @@ -import styles from "./SkeletonText.module.scss"; +import styles from './SkeletonText.module.scss'; export default function SkeletonText() { - return
    ; + return
    ; } diff --git a/src/components/global/Spinner/Spinner.jsx b/src/components/global/Spinner/Spinner.jsx index 7b54983f..d8a1c9f6 100644 --- a/src/components/global/Spinner/Spinner.jsx +++ b/src/components/global/Spinner/Spinner.jsx @@ -1,5 +1,5 @@ -import styles from "./Spinner.module.scss"; +import styles from './Spinner.module.scss'; export default function Spinner() { - return
    ; + return
    ; } diff --git a/src/components/homepage/Benefits/Benefits.tsx b/src/components/homepage/Benefits/Benefits.tsx index d9c804ee..3b9c2c7d 100644 --- a/src/components/homepage/Benefits/Benefits.tsx +++ b/src/components/homepage/Benefits/Benefits.tsx @@ -1,19 +1,19 @@ -import styles from "./Benefits.module.scss"; +import styles from './Benefits.module.scss'; export const Benefits = () => { return ( -
    +

    Benefits of using Deriv API

    -
    +

    Automation

    -
    +

    Easy integration

    -
    +

    Fast execution

    @@ -24,10 +24,9 @@ export const Benefits = () => {

    Personalise your trading

    - Personalise your trading apps to match your needs. Create - charts and views the way you like them. Develop your trading - app using any common programming language and extend your - trading opportunities. + Personalise your trading apps to match your needs. Create charts and views the way you + like them. Develop your trading app using any common programming language and extend + your trading opportunities.

    @@ -36,15 +35,14 @@ export const Benefits = () => {

    Build a business and earn more

    - Create your own trading apps by taking advantage of the power - of Deriv's trading services. Share your apps with fellow - traders or customers, and get a chance to earn more or build - your own business. + Create your own trading apps by taking advantage of the power of Deriv's trading + services. Share your apps with fellow traders or customers, and get a chance to earn + more or build your own business.

    - ) -} \ No newline at end of file + ); +}; diff --git a/src/components/homepage/ClientLibraries/ClientLibraries.tsx b/src/components/homepage/ClientLibraries/ClientLibraries.tsx index 7d8cfda7..b3f93aab 100644 --- a/src/components/homepage/ClientLibraries/ClientLibraries.tsx +++ b/src/components/homepage/ClientLibraries/ClientLibraries.tsx @@ -1,22 +1,21 @@ -import styles from "./ClientLibraries.module.scss"; +import styles from './ClientLibraries.module.scss'; export const ClientLibraries = () => { return ( -
    -
    +
    +
    -

    Comprehensive all-in-one client library

    -

    - Simplify your development processes and get your app up and - running
    +

    Comprehensive all-in-one client library

    +

    + Simplify your development processes and get your app up and running
    faster with the client library of your choice.

    @@ -25,9 +24,9 @@ export const ClientLibraries = () => {
    - ) -} \ No newline at end of file + ); +}; diff --git a/src/components/homepage/DelayedFallbackHomepage/DelayedFallbackHomepage.jsx b/src/components/homepage/DelayedFallbackHomepage/DelayedFallbackHomepage.jsx index d51df391..a8b2b9b1 100644 --- a/src/components/homepage/DelayedFallbackHomepage/DelayedFallbackHomepage.jsx +++ b/src/components/homepage/DelayedFallbackHomepage/DelayedFallbackHomepage.jsx @@ -1,10 +1,10 @@ -import styles from "./DelayedFallbackHomepage.module.scss"; +import styles from './DelayedFallbackHomepage.module.scss'; export default function DelayedFallbackHomepage() { - return ( -
    -
    -
    -
    - ); + return ( +
    +
    +
    +
    + ); } diff --git a/src/components/homepage/DerivApiFeatures/DerivApiFeatures.tsx b/src/components/homepage/DerivApiFeatures/DerivApiFeatures.tsx index af727087..7e2ee3eb 100644 --- a/src/components/homepage/DerivApiFeatures/DerivApiFeatures.tsx +++ b/src/components/homepage/DerivApiFeatures/DerivApiFeatures.tsx @@ -1,16 +1,15 @@ -import styles from "./DerivApiFeatures.module.scss"; +import styles from './DerivApiFeatures.module.scss'; export const DerivApiFeatures = () => { return ( -
    -
    +
    +

    Deriv API features

    - Deriv API gives you full access to all the trading - functionalities of DTrader and allows you to build your own - comprehensive trading systems and analysis tools. + Deriv API gives you full access to all the trading functionalities of DTrader and allows you + to build your own comprehensive trading systems and analysis tools.

    With our API, you'll be able to:

      @@ -44,5 +43,5 @@ export const DerivApiFeatures = () => {
    - ) -} \ No newline at end of file + ); +}; diff --git a/src/components/homepage/GetStarted/GetStarted.tsx b/src/components/homepage/GetStarted/GetStarted.tsx index c399bb15..a5de75b7 100644 --- a/src/components/homepage/GetStarted/GetStarted.tsx +++ b/src/components/homepage/GetStarted/GetStarted.tsx @@ -1,62 +1,59 @@ -import styles from "./GetStarted.module.scss"; +import styles from './GetStarted.module.scss'; export const GetStarted = () => { return ( -
    -
    -

    Get started with our API in 3 simple steps:

    -
    +
    +
    +

    Get started with our API in 3 simple steps:

    +
    -
    +

    1. Sign up

    -
    +
    Create a free Deriv account to access
    our API (or use your Binary.com login details).
    -
    - Create a free Deriv account to access our API (or use your - Binary.com login details). +
    + Create a free Deriv account to access our API (or use your Binary.com login details).
    - -
    + +

    2. Register your app

    -
    - Fill out the registration form to start using Deriv API. -
    +
    Fill out the registration form to start using Deriv API.
    -
    - - ) -} \ No newline at end of file + ); +}; diff --git a/src/components/homepage/HeroHeader/HeroHeader.tsx b/src/components/homepage/HeroHeader/HeroHeader.tsx index 9eaf4e90..5c3e152d 100644 --- a/src/components/homepage/HeroHeader/HeroHeader.tsx +++ b/src/components/homepage/HeroHeader/HeroHeader.tsx @@ -1,15 +1,14 @@ -import styles from "./HeroHeader.module.scss"; +import styles from './HeroHeader.module.scss'; export const HeroHeader = () => { return (

    Deriv API

    - Use our powerful, flexible, and free API to build a custom trading{" "} -
    + Use our powerful, flexible, and free API to build a custom trading
    platform - for yourself or for your business.

    - ) -} \ No newline at end of file + ); +}; diff --git a/src/components/homepage/Homepage/Homepage.jsx b/src/components/homepage/Homepage/Homepage.jsx index ab21cdd8..1d79b93e 100644 --- a/src/components/homepage/Homepage/Homepage.jsx +++ b/src/components/homepage/Homepage/Homepage.jsx @@ -1,26 +1,26 @@ -import { HomepageFooter } from "../HomepageFooter/HomepageFooter" -import { HeroHeader } from "../HeroHeader/HeroHeader"; -import { ClientLibraries } from "../ClientLibraries/ClientLibraries" -import { HomepageSlider } from "../HomepageSlider/HomepageSlider"; -import { Benefits } from "../Benefits/Benefits"; -import { WaysToEarn } from "../WaysToEarn/WaysToEarn" -import { GetStarted } from "../GetStarted/GetStarted" -import { DerivApiFeatures } from "../DerivApiFeatures/DerivApiFeatures" -import { RenderOfficialDomainContents } from "../../utility/RenderOfficialDomainContents/RenderOfficialDomainContents"; +import { HomepageFooter } from '../HomepageFooter/HomepageFooter'; +import { HeroHeader } from '../HeroHeader/HeroHeader'; +import { ClientLibraries } from '../ClientLibraries/ClientLibraries'; +import { HomepageSlider } from '../HomepageSlider/HomepageSlider'; +import { Benefits } from '../Benefits/Benefits'; +import { WaysToEarn } from '../WaysToEarn/WaysToEarn'; +import { GetStarted } from '../GetStarted/GetStarted'; +import { DerivApiFeatures } from '../DerivApiFeatures/DerivApiFeatures'; +import { RenderOfficialDomainContents } from '../../utility/RenderOfficialDomainContents/RenderOfficialDomainContents'; export default function HomePage() { - return ( -
    - - - -
    - - - - -
    - -
    - ); + return ( +
    + + + +
    + + + + +
    + +
    + ); } diff --git a/src/components/homepage/HomepageFooter/HomepageFooter.tsx b/src/components/homepage/HomepageFooter/HomepageFooter.tsx index 84b0b7d2..704a8d36 100644 --- a/src/components/homepage/HomepageFooter/HomepageFooter.tsx +++ b/src/components/homepage/HomepageFooter/HomepageFooter.tsx @@ -1,31 +1,29 @@ export const HomepageFooter = () => { return ( -
    -
    -
    +
    +
    +

    Get connected

    -

    - Discuss ideas and share solutions with developers worldwide. -

    +

    Discuss ideas and share solutions with developers worldwide.

    Join our community
    -
    +

    We're here to help

    Email us at - api-support@deriv.com + api-support@deriv.com
    if you have any questions.

    - ) -} + ); +}; diff --git a/src/components/homepage/HomepageSlider/HomepageSlider.tsx b/src/components/homepage/HomepageSlider/HomepageSlider.tsx index a1a040f7..11cd99a5 100644 --- a/src/components/homepage/HomepageSlider/HomepageSlider.tsx +++ b/src/components/homepage/HomepageSlider/HomepageSlider.tsx @@ -139,9 +139,9 @@ export const HomepageSlider = () => { return ( -
    -

    See what our clients say

    -
    +
    +

    See what our clients say

    +
    { - Probably the best API for making your business successful in trading derivatives out - there. + Probably the best API for making your business successful in trading derivatives + out there. } author={ @@ -183,4 +183,4 @@ export const HomepageSlider = () => {
    ); -} +}; diff --git a/src/components/homepage/HomepageSlider/Slide.tsx b/src/components/homepage/HomepageSlider/Slide.tsx index 96da9046..fc88b94f 100644 --- a/src/components/homepage/HomepageSlider/Slide.tsx +++ b/src/components/homepage/HomepageSlider/Slide.tsx @@ -1,11 +1,11 @@ -import styles from "./HomepageSlider.module.scss"; +import styles from './HomepageSlider.module.scss'; export const Slide = ({ content, author }) => { - return ( -
    -
    {content}
    -
    -

    {author}

    -
    - ); -} + return ( +
    +
    {content}
    +
    +

    {author}

    +
    + ); +}; diff --git a/src/components/homepage/WaysToEarn/WaysToEarn.tsx b/src/components/homepage/WaysToEarn/WaysToEarn.tsx index ca8fb836..d2c5e136 100644 --- a/src/components/homepage/WaysToEarn/WaysToEarn.tsx +++ b/src/components/homepage/WaysToEarn/WaysToEarn.tsx @@ -1,4 +1,4 @@ -import styles from "./WaysToEarn.module.scss"; +import styles from './WaysToEarn.module.scss'; export const WaysToEarn = () => { return (
    @@ -10,28 +10,26 @@ export const WaysToEarn = () => {

    - Register your app with Deriv, and add a percentage markup to - the contract prices to profit from every purchased contract. + Register your app with Deriv, and add a percentage markup to the contract prices to profit + from every purchased contract.

    - Sign up as an affiliate, build your app, and get commissions - on trades completed via your app and the affiliate plan you - select. + Sign up as an affiliate, build your app, and get commissions on trades completed via your + app and the affiliate plan you select.

    - Sign up as a payment agent, build your own custom payment - website, and use our API to earn commission on every payment - you process for Deriv’s clients. + Sign up as a payment agent, build your own custom payment website, and use our API to earn + commission on every payment you process for Deriv’s clients.

    - ) -} \ No newline at end of file + ); +}; diff --git a/src/components/json-schemas/JsonSchemas.jsx b/src/components/json-schemas/JsonSchemas.jsx index 6240dd36..02348d32 100644 --- a/src/components/json-schemas/JsonSchemas.jsx +++ b/src/components/json-schemas/JsonSchemas.jsx @@ -1,68 +1,68 @@ -import style from "./JsonSchemas.module.scss"; +import style from './JsonSchemas.module.scss'; const JsonSchemas = () => { - const json_navigation = [ - { - id: "json-schemas", - title: "JSON Schemas", - path: "https://github.com/binary-com/websockets/tree/gh-pages/config", - }, - { - id: "changelog", - title: "changelog", - path: "https://github.com/binary-com/websockets/commits/gh-pages", - }, - { - id: "json-editor", - title: "JSON Editor with JSON Schema support", - path: "https://jeremydorn.com/json-editor/", - }, - { - id: "json-schema_ts", - title: "Generate JSON Schema from TypeScript", - path: "https://lbovet.github.io/typson-demo/", - }, - { - id: "json-schema_object", - title: "Generate JSON Schema from JSON Object", - path: "https://jsonschema.net/", - }, - { - id: "json-schema_validator", - title: "JSON Schema Validator", - path: "https://www.jsonschemavalidator.net/", - }, - ]; + const json_navigation = [ + { + id: 'json-schemas', + title: 'JSON Schemas', + path: 'https://github.com/binary-com/websockets/tree/gh-pages/config', + }, + { + id: 'changelog', + title: 'changelog', + path: 'https://github.com/binary-com/websockets/commits/gh-pages', + }, + { + id: 'json-editor', + title: 'JSON Editor with JSON Schema support', + path: 'https://jeremydorn.com/json-editor/', + }, + { + id: 'json-schema_ts', + title: 'Generate JSON Schema from TypeScript', + path: 'https://lbovet.github.io/typson-demo/', + }, + { + id: 'json-schema_object', + title: 'Generate JSON Schema from JSON Object', + path: 'https://jsonschema.net/', + }, + { + id: 'json-schema_validator', + title: 'JSON Schema Validator', + path: 'https://www.jsonschemavalidator.net/', + }, + ]; - return ( -
    -

    JSON Schemas

    -

    - Our API is defined by - - {" "} - {json_navigation[0].title} - - . Get updates by looking for "JSON Schema Update" in the - - {" "} - {json_navigation[1].title} - - . -

    -

    Useful tools:

    - {json_navigation.map( - ({ id, title, path }, i) => - i > 1 && ( -

    - - {title} - + return ( +

    +

    JSON Schemas

    +

    + Our API is defined by + + {' '} + {json_navigation[0].title} + + . Get updates by looking for "JSON Schema Update" in the + + {' '} + {json_navigation[1].title} + + .

    - ) - )} -
    - ); +

    Useful tools:

    + {json_navigation.map( + ({ id, title, path }, i) => + i > 1 && ( +

    + + {title} + +

    + ) + )} +
    + ); }; export default JsonSchemas; diff --git a/src/components/playground/ApiExplorer/ApiExplorer.jsx b/src/components/playground/ApiExplorer/ApiExplorer.jsx index 6eb661c6..cb6be937 100644 --- a/src/components/playground/ApiExplorer/ApiExplorer.jsx +++ b/src/components/playground/ApiExplorer/ApiExplorer.jsx @@ -1,21 +1,21 @@ -import SchemaTitle from "../Schema/SchemaTitle"; -import { PlaygroundComponent } from "../PlaygroundComponent/PlaygroundComponent"; -import React from "react"; -import style from "../PlaygroundComponent/PlaygroundComponent.module.scss"; +import SchemaTitle from '../Schema/SchemaTitle'; +import { PlaygroundComponent } from '../PlaygroundComponent/PlaygroundComponent'; +import React from 'react'; +import style from '../PlaygroundComponent/PlaygroundComponent.module.scss'; const ApiExplorer = () => { - return ( -
    -
    - API Explorer -
    -
    -
    - + return ( +
    +
    + API Explorer +
    +
    +
    + +
    +
    -
    -
    - ); + ); }; export default ApiExplorer; diff --git a/src/components/playground/PlaygroundComponent/PlaygroundComponent.jsx b/src/components/playground/PlaygroundComponent/PlaygroundComponent.jsx index 48f182e9..7d8bb16a 100644 --- a/src/components/playground/PlaygroundComponent/PlaygroundComponent.jsx +++ b/src/components/playground/PlaygroundComponent/PlaygroundComponent.jsx @@ -1,281 +1,252 @@ -import { useEffect, useRef, useState, useCallback } from "react"; -import { createSignal } from "solid-js"; -import { useLocation } from "react-router-dom"; -import SchemaWrapper from "../Schema/SchemaWrapper"; -import SchemaTitle from "../Schema/SchemaTitle"; -import RequestJSONBox from "./RequestJSONBox/RequestJSONBox"; -import TokenInputField from "./TokenInputField/TokenInputField"; -import SelectRequestInput from "./SelectRequestInput/SelectRequestInput"; -import { isDisplayAuthDoc, isDisplaySelectedDoc, send } from "../../../state/stateSignal"; -import { api, generateDerivApiInstance } from "../../../global-functions/appid"; -import { playground_requests } from "../../../data-stores/playground_requests"; -import { data_get_api_token } from "../../../data-stores/data-app-registration"; -import { ticksSubject } from "../../../global-functions/ticksSubject"; -import styles from "./PlaygroundComponent.module.scss"; +import { useEffect, useRef, useState, useCallback } from 'react'; +import { createSignal } from 'solid-js'; +import { useLocation } from 'react-router-dom'; +import SchemaWrapper from '../Schema/SchemaWrapper'; +import SchemaTitle from '../Schema/SchemaTitle'; +import RequestJSONBox from './RequestJSONBox/RequestJSONBox'; +import TokenInputField from './TokenInputField/TokenInputField'; +import SelectRequestInput from './SelectRequestInput/SelectRequestInput'; +import { isDisplayAuthDoc, isDisplaySelectedDoc, send } from '../../../state/stateSignal'; +import { api, generateDerivApiInstance } from '../../../global-functions/appid'; +import { playground_requests } from '../../../data-stores/playground_requests'; +import { data_get_api_token } from '../../../data-stores/data-app-registration'; +import { ticksSubject } from '../../../global-functions/ticksSubject'; +import styles from './PlaygroundComponent.module.scss'; // eslint-disable-next-line import/no-extraneous-dependencies -import { createBrowserHistory } from "history"; +import { createBrowserHistory } from 'history'; export const PlaygroundComponent = () => { - const DEFAULT_VALUE = "Select API Call - Version 3"; - const [current_api, setCurrentAPI] = useState(api); - const [is_initial_socket, setIsInitialSocket] = useState(true); - const [messages, setMessages] = useState([]); - const [messagesSignal, setMessagesSignal] = createSignal([]); - const request_input = useRef(null); - const [request_info, setRequestInfo] = useState({}); - const [response_info, setResponseInfo] = useState({}); - const [scroll_direction, setScrollDirection] = useState("down"); - const [text_data, setTextData] = useState({ - request: "", - selected_value: DEFAULT_VALUE, - token: "", - }); - const [selected, setSelected] = useState(DEFAULT_VALUE); - const location = useLocation(); - const history = createBrowserHistory(); + const DEFAULT_VALUE = 'Select API Call - Version 3'; + const [current_api, setCurrentAPI] = useState(api); + const [is_initial_socket, setIsInitialSocket] = useState(true); + const [messages, setMessages] = useState([]); + const [messagesSignal, setMessagesSignal] = createSignal([]); + const request_input = useRef(null); + const [request_info, setRequestInfo] = useState({}); + const [response_info, setResponseInfo] = useState({}); + const [scroll_direction, setScrollDirection] = useState('down'); + const [text_data, setTextData] = useState({ + request: '', + selected_value: DEFAULT_VALUE, + token: '', + }); + const [selected, setSelected] = useState(DEFAULT_VALUE); + const location = useLocation(); + const history = createBrowserHistory(); - // Reset playground state when unmounting the component. - useEffect(() => { - return () => { - send('EMPTY_TOKEN'); - } - }, []) - - // add/remove event listeners on component mount/unmount - useEffect(() => { - // mounting - document.addEventListener("visibilitychange", documentVisibility); - // unmounting - return () => document.removeEventListener("visibilitychange", documentVisibility); - }, []); + // Reset playground state when unmounting the component. + useEffect(() => { + return () => { + send('EMPTY_TOKEN'); + }; + }, []); - // If the user switches to a different tab, it will trigger the visibility state. - const documentVisibility = () => { - // If the visibility state is hidden, we will close the API. - if (document.visibilityState === "hidden") { - current_api.connection.close(); - ticksSubject.complete(); - setScrollDirection("down"); - } - // When we switch back to the main window, initiate a new API call. - setCurrentAPI(api); - } + // add/remove event listeners on component mount/unmount + useEffect(() => { + // mounting + document.addEventListener('visibilitychange', documentVisibility); + // unmounting + return () => document.removeEventListener('visibilitychange', documentVisibility); + }, []); - // Dynamically import JSON to update the select value of the playground dropdown. - useEffect(() => { - const hash_value = window.location.hash.split("#")[1]; - const request_body = playground_requests.find( - (el) => el.name === hash_value - ); - const is_not_placeholder = text_data.selected_value === request_body?.name; - if (is_not_placeholder) dynamicImportJSON(text_data.selected_value); - }, [text_data.selected_value]); + // If the user switches to a different tab, it will trigger the visibility state. + const documentVisibility = () => { + // If the visibility state is hidden, we will close the API. + if (document.visibilityState === 'hidden') { + current_api.connection.close(); + ticksSubject.complete(); + setScrollDirection('down'); + } + // When we switch back to the main window, initiate a new API call. + setCurrentAPI(api); + }; - // We need to dynamically import new data when the user selects a function - // through the link hash. - useEffect(() => { - const hash_value = window.location.hash.split("#")[1]; - if (hash_value) { - dynamicImportJSON(hash_value); - send('SELECT_API'); - } - }, [window.location.hash]); + // Dynamically import JSON to update the select value of the playground dropdown. + useEffect(() => { + const hash_value = window.location.hash.split('#')[1]; + const request_body = playground_requests.find(el => el.name === hash_value); + const is_not_placeholder = text_data.selected_value === request_body?.name; + if (is_not_placeholder) dynamicImportJSON(text_data.selected_value); + }, [text_data.selected_value]); - // A new data object has to be created if the user updates the link hash, - // This way, new data will be displayed in the UI. - useEffect(() => { - if (window.location.hash) { - const hash_value = window.location.hash.split("#")[1]; - const find_select_value = playground_requests.find( - (el) => el.name === hash_value - ); - const hash_text_data = { - ...text_data, - request: JSON.stringify(find_select_value?.body, null, 2), - selected_value: find_select_value?.title, - }; - setTextData(hash_text_data); - } - }, [window.location.hash, playground_requests]); + // We need to dynamically import new data when the user selects a function + // through the link hash. + useEffect(() => { + const hash_value = window.location.hash.split('#')[1]; + if (hash_value) { + dynamicImportJSON(hash_value); + send('SELECT_API'); + } + }, [window.location.hash]); - const dynamicImportJSON = useCallback((selected_value) => { - import(`../../../../config/v3/${selected_value}/send.json`) - .then((data) => { - setRequestInfo(data); - }) - .catch((error) => { - // eslint-disable-next-line - console.log(error); - }); - import(`../../../../config/v3/${selected_value}/receive.json`) - .then((data) => { - setResponseInfo(data); - }) - .catch((error) => { - // eslint-disable-next-line - console.log(error); - }); - }, [setRequestInfo, setResponseInfo]) + // A new data object has to be created if the user updates the link hash, + // This way, new data will be displayed in the UI. + useEffect(() => { + if (window.location.hash) { + const hash_value = window.location.hash.split('#')[1]; + const find_select_value = playground_requests.find(el => el.name === hash_value); + const hash_text_data = { + ...text_data, + request: JSON.stringify(find_select_value?.body, null, 2), + selected_value: find_select_value?.title, + }; + setTextData(hash_text_data); + } + }, [window.location.hash, playground_requests]); - const displayAuthDoc = () => dynamicImportJSON('authorize'); + const dynamicImportJSON = useCallback( + selected_value => { + import(`../../../../config/v3/${selected_value}/send.json`) + .then(data => { + setRequestInfo(data); + }) + .catch(error => { + // eslint-disable-next-line + console.log(error); + }); + import(`../../../../config/v3/${selected_value}/receive.json`) + .then(data => { + setResponseInfo(data); + }) + .catch(error => { + // eslint-disable-next-line + console.log(error); + }); + }, + [setRequestInfo, setResponseInfo] + ); - const sendRequest = useCallback(() => { - if ( - !request_input.current?.value && - text_data.selected_value === DEFAULT_VALUE - ) { - alert("Invalid JSON!"); - return; - } - let _request; - try { - _request = - request_input.current?.value && - JSON.parse(request_input.current?.value); - } catch (error) { - alert("Invalid JSON!"); - return; - } + const displayAuthDoc = () => dynamicImportJSON('authorize'); - const is_current_api_ready = current_api.connection.readyState === 1; - const subscribed_tick_history = - _request.ticks_history && _request.subscribe === 1; - let relevant_api = current_api; - if (!is_current_api_ready && is_initial_socket) { - relevant_api = generateDerivApiInstance(); - setIsInitialSocket(false); - } else if (current_api.connection.readyState !== 1 && !is_initial_socket) { - relevant_api = generateDerivApiInstance(); - setIsInitialSocket(true); - } - if (_request.ticks || subscribed_tick_history) { - ticksSubject.next(_request); - ticksSubject.subscribe({ - next: (res) => { - setMessagesSignal([ - ...messagesSignal(), - { body: _request, type: "req" }, - { body: res, type: "res" }, - ]); - setMessages(messagesSignal()); - }, - error: (err) => { - setMessages([ - ...messages, - { body: _request, type: "req" }, - { body: err, type: "err" }, - ]); - }, - }); - } - if (_request && !_request.ticks) { - relevant_api - .send(_request) - .then((res) => { - setMessages([ - ...messages, - { body: _request, type: "req" }, - { body: res, type: "res" }, - ]); - }) - .catch((err) => { - setMessages([ - ...messages, - { body: _request, type: "req" }, - { body: err, type: "err" }, - ]); - }); - } - setCurrentAPI(relevant_api); - }, [current_api, request_input, messages, is_initial_socket, text_data]); + const sendRequest = useCallback(() => { + if (!request_input.current?.value && text_data.selected_value === DEFAULT_VALUE) { + alert('Invalid JSON!'); + return; + } + let _request; + try { + _request = request_input.current?.value && JSON.parse(request_input.current?.value); + } catch (error) { + alert('Invalid JSON!'); + return; + } + + const is_current_api_ready = current_api.connection.readyState === 1; + const subscribed_tick_history = _request.ticks_history && _request.subscribe === 1; + let relevant_api = current_api; + if (!is_current_api_ready && is_initial_socket) { + relevant_api = generateDerivApiInstance(); + setIsInitialSocket(false); + } else if (current_api.connection.readyState !== 1 && !is_initial_socket) { + relevant_api = generateDerivApiInstance(); + setIsInitialSocket(true); + } + if (_request.ticks || subscribed_tick_history) { + ticksSubject.next(_request); + ticksSubject.subscribe({ + next: res => { + setMessagesSignal([ + ...messagesSignal(), + { body: _request, type: 'req' }, + { body: res, type: 'res' }, + ]); + setMessages(messagesSignal()); + }, + error: err => { + setMessages([...messages, { body: _request, type: 'req' }, { body: err, type: 'err' }]); + }, + }); + } + if (_request && !_request.ticks) { + relevant_api + .send(_request) + .then(res => { + setMessages([...messages, { body: _request, type: 'req' }, { body: res, type: 'res' }]); + }) + .catch(err => { + setMessages([...messages, { body: _request, type: 'req' }, { body: err, type: 'err' }]); + }); + } + setCurrentAPI(relevant_api); + }, [current_api, request_input, messages, is_initial_socket, text_data]); - const handleAuthenticateClick = useCallback( - (inserted_token) => { - const new_text_data = { - token: inserted_token, - selected_value: "authorize", - request: JSON.stringify({ authorize: inserted_token }, null, 2), - }; - const old_text_data = { ...text_data }; - Promise.resolve(setTextData({ ...new_text_data })).then(() => { - sendRequest(); - if (isDisplaySelectedDoc()) setTextData(old_text_data); - }); - send('CLICK_AUTHENTICATE'); - if (isDisplayAuthDoc()) displayAuthDoc(); - }, - [setTextData, sendRequest] - ); + const handleAuthenticateClick = useCallback( + inserted_token => { + const new_text_data = { + token: inserted_token, + selected_value: 'authorize', + request: JSON.stringify({ authorize: inserted_token }, null, 2), + }; + const old_text_data = { ...text_data }; + Promise.resolve(setTextData({ ...new_text_data })).then(() => { + sendRequest(); + if (isDisplaySelectedDoc()) setTextData(old_text_data); + }); + send('CLICK_AUTHENTICATE'); + if (isDisplayAuthDoc()) displayAuthDoc(); + }, + [setTextData, sendRequest] + ); - const handleSelectChange = useCallback( - (event, name) => { - event.preventDefault(); - history.push(`${location.pathname}#${name}`); - const request_body = playground_requests.find( - (el) => el.name === event.currentTarget.value - ); - const new_text_data = { - ...text_data, - selected_value: event.currentTarget.value, - request: JSON.stringify(request_body?.body, null, 4), - }; - setTextData({ ...new_text_data }); - send('SELECT_API'); - }, - [text_data] - ); + const handleSelectChange = useCallback( + (event, name) => { + event.preventDefault(); + history.push(`${location.pathname}#${name}`); + const request_body = playground_requests.find(el => el.name === event.currentTarget.value); + const new_text_data = { + ...text_data, + selected_value: event.currentTarget.value, + request: JSON.stringify(request_body?.body, null, 4), + }; + setTextData({ ...new_text_data }); + send('SELECT_API'); + }, + [text_data] + ); - const handleTextAreaInput = useCallback( - (e) => setTextData({ ...text_data, request: e.target.value }), - [text_data] - ); + const handleTextAreaInput = useCallback(e => setTextData({ ...text_data, request: e.target.value }), [text_data]); - const json_box_props = { - current_api, - sendRequest, - messages, - setMessages, - request_example: text_data.request, - handleChange: handleTextAreaInput, - request_input, - setScrollDirection, - scroll_direction, - }; + const json_box_props = { + current_api, + sendRequest, + messages, + setMessages, + request_example: text_data.request, + handleChange: handleTextAreaInput, + request_input, + setScrollDirection, + scroll_direction, + }; - return ( -
    -
    - -
    - -
    -
    - - {data_get_api_token.textFocus} - -
    - {data_get_api_token.button} + return ( +
    +
    + +
    + +
    +
    + + {data_get_api_token.textFocus} + +
    {data_get_api_token.button}
    +
    +
    + +
    +
    +
    + +
    +
    + +
    -
    -
    - -
    -
    -
    - -
    -
    -
    -
    -
    - ); + ); }; diff --git a/src/components/playground/PlaygroundComponent/RequestJSONBox/ConsoleMessage.jsx b/src/components/playground/PlaygroundComponent/RequestJSONBox/ConsoleMessage.jsx index 75e684e8..b1fbc743 100644 --- a/src/components/playground/PlaygroundComponent/RequestJSONBox/ConsoleMessage.jsx +++ b/src/components/playground/PlaygroundComponent/RequestJSONBox/ConsoleMessage.jsx @@ -1,14 +1,14 @@ -import React from "react"; -import CodeContent from "../../../global/CodeBlock/CodeContent"; -import style from "../PlaygroundComponent.module.scss"; +import React from 'react'; +import CodeContent from '../../../global/CodeBlock/CodeContent'; +import style from '../PlaygroundComponent.module.scss'; const ConsoleMessage = ({ message }) => { - const payload = JSON.stringify(message.body, null, 4); - return ( -
    - -
    - ); + const payload = JSON.stringify(message.body, null, 4); + return ( +
    + +
    + ); }; export default ConsoleMessage; diff --git a/src/components/playground/PlaygroundComponent/RequestJSONBox/RequestJSONBox.jsx b/src/components/playground/PlaygroundComponent/RequestJSONBox/RequestJSONBox.jsx index 0c49fe19..39e472fa 100644 --- a/src/components/playground/PlaygroundComponent/RequestJSONBox/RequestJSONBox.jsx +++ b/src/components/playground/PlaygroundComponent/RequestJSONBox/RequestJSONBox.jsx @@ -1,113 +1,107 @@ -import { useEffect, useRef, useState } from "react"; -import { ResetSendButtonsBlock } from "../../../global/ResetSendButtonsBlock/ResetSendButtonsBlock"; -import ConsoleMessage from "./ConsoleMessage"; -import "../../../../global-functions/appid"; -import style from "./RequestJSONBox.module.scss"; +import { useEffect, useRef, useState } from 'react'; +import { ResetSendButtonsBlock } from '../../../global/ResetSendButtonsBlock/ResetSendButtonsBlock'; +import ConsoleMessage from './ConsoleMessage'; +import '../../../../global-functions/appid'; +import style from './RequestJSONBox.module.scss'; const RequestJSONBox = ({ - request_example, - messages, - handleChange, - isAppRegistration, - request_input, - sendRequest, - setMessages, - current_api, - isRegister, - inputListText, - setScrollDirection, - scroll_direction + request_example, + messages, + handleChange, + isAppRegistration, + request_input, + sendRequest, + setMessages, + current_api, + isRegister, + inputListText, + setScrollDirection, + scroll_direction, }) => { - const [is_scrolling, setIsScrolling] = useState(true); - const messagesRef = useRef(null); - const [isActive, setIsActive] = useState(false) - - useEffect(() => { - if(isActive==true){ - setIsScrolling(true) - } - },[]) + const [is_scrolling, setIsScrolling] = useState(true); + const messagesRef = useRef(null); + const [isActive, setIsActive] = useState(false); - const onScrollRequest = (event) => { - setIsActive(true) - const scroll_height = event?.target?.scrollHeight; - const scroll_top = event?.target?.scrollTop; - const client_height = event?.target?.clientHeight; - const reached_bottom = scroll_top + client_height >= scroll_height; - const scrolling_top = scroll_top + client_height <= scroll_height; - - if (reached_bottom && scroll_direction === "down") { - setIsScrolling(true); - setScrollDirection("up"); - } - - if (scrolling_top && scroll_direction === "up") { - setIsScrolling(false); - setScrollDirection("down"); - } - }; + useEffect(() => { + if (isActive == true) { + setIsScrolling(true); + } + }, []); - useEffect(() => { - setTimeout(() => { - if (is_scrolling) { - messagesRef.current?.scrollTo({ - top: messagesRef.current.scrollHeight, - left: messagesRef.current.scrollHeight, - behavior: "smooth", - }); - } - }, 1); - }, [messagesRef, messages, is_scrolling]); + const onScrollRequest = event => { + setIsActive(true); + const scroll_height = event?.target?.scrollHeight; + const scroll_top = event?.target?.scrollTop; + const client_height = event?.target?.clientHeight; + const reached_bottom = scroll_top + client_height >= scroll_height; + const scrolling_top = scroll_top + client_height <= scroll_height; - return ( -
    - {isAppRegistration ? ( -
    Request JSON
    - ) : ( - - )} -