diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 0000000..41560af --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,10 @@ +version: "3.8" +services: + admin-panel: + image: ghcr.io/opexdev/admin-panel + build: + context: . + args: + - REACT_APP_DEFAULT_DIRECTION=LTR + - REACT_APP_BRAND_NAME=OPEX + - GENERATE_SOURCEMAP=$GENERATE_SOURCEMAP diff --git a/docker-compose.yml b/docker-compose.yml index 99cd56f..5264efb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,6 +7,7 @@ services: - FRONT_URL=$FRONT_URL - CLIENT_ID=$CLIENT_ID - CLIENT_SECRET=$CLIENT_SECRET + - SUPERSET_URL=$SUPERSET_URL networks: - default deploy: diff --git a/env-map.js b/env-map.js index f529cfa..f643316 100644 --- a/env-map.js +++ b/env-map.js @@ -2,5 +2,6 @@ window.env = { REACT_APP_API_BASE_URL: "$API_BASE_URL", REACT_APP_FRONT_URL: "$FRONT_URL", REACT_APP_CLIENT_ID: "$CLIENT_ID", + REACT_APP_SUPERSET_URL:"$SUPERSET_URL", REACT_APP_CLIENT_SECRET: "$CLIENT_SECRET", }; diff --git a/package-lock.json b/package-lock.json index 00d2909..70bf659 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^12.1.4", "@testing-library/user-event": "^13.5.0", + "apexcharts": "^3.35.3", "axios": "^0.26.1", "bignumber.js": "^9.0.2", "jwt-decode": "^3.1.2", @@ -19,6 +20,7 @@ "node-sass": "^7.0.1", "rc-scrollbars": "^1.1.5", "react": "^18.0.0", + "react-apexcharts": "^1.4.0", "react-dom": "^18.0.0", "react-hot-toast": "^2.2.0", "react-router-dom": "^6.3.0", @@ -3702,6 +3704,19 @@ "node": ">= 8" } }, + "node_modules/apexcharts": { + "version": "3.35.3", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.35.3.tgz", + "integrity": "sha512-UDlxslJr3DG63I/SgoiivIu4lpP25GMaKFK8NvCHmTksTQshx4ng3oPPrYvdsBFOvD/ajPYIh/p7rNB0jq8vXg==", + "dependencies": { + "svg.draggable.js": "^2.2.2", + "svg.easing.js": "^2.0.0", + "svg.filter.js": "^2.0.2", + "svg.pathmorphing.js": "^0.1.3", + "svg.resize.js": "^1.4.3", + "svg.select.js": "^3.0.1" + } + }, "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -11620,6 +11635,18 @@ "node": ">=0.10.0" } }, + "node_modules/react-apexcharts": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.0.tgz", + "integrity": "sha512-DrcMV4aAMrUG+n6412yzyATWEyCDWlpPBBhVbpzBC4PDeuYU6iF84SmExbck+jx5MUm4U5PM3/T307Mc3kzc9Q==", + "dependencies": { + "prop-types": "^15.5.7" + }, + "peerDependencies": { + "apexcharts": "^3.18.0", + "react": ">=0.13" + } + }, "node_modules/react-app-polyfill": { "version": "3.0.0", "license": "MIT", @@ -13194,6 +13221,89 @@ "version": "2.0.4", "license": "MIT" }, + "node_modules/svg.draggable.js": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz", + "integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==", + "dependencies": { + "svg.js": "^2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.easing.js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz", + "integrity": "sha1-iqmUawqOJ4V6XEChDrpAkeVpHxI=", + "dependencies": { + "svg.js": ">=2.3.x" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.filter.js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz", + "integrity": "sha1-kQCOFROJ3ZIwd5/L5uLJo2LRwgM=", + "dependencies": { + "svg.js": "^2.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.js": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz", + "integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==" + }, + "node_modules/svg.pathmorphing.js": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz", + "integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==", + "dependencies": { + "svg.js": "^2.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.resize.js": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz", + "integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==", + "dependencies": { + "svg.js": "^2.6.5", + "svg.select.js": "^2.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.resize.js/node_modules/svg.select.js": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz", + "integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==", + "dependencies": { + "svg.js": "^2.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.select.js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz", + "integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==", + "dependencies": { + "svg.js": "^2.6.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/svgo": { "version": "1.3.2", "license": "MIT", @@ -16974,6 +17084,19 @@ "picomatch": "^2.0.4" } }, + "apexcharts": { + "version": "3.35.3", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.35.3.tgz", + "integrity": "sha512-UDlxslJr3DG63I/SgoiivIu4lpP25GMaKFK8NvCHmTksTQshx4ng3oPPrYvdsBFOvD/ajPYIh/p7rNB0jq8vXg==", + "requires": { + "svg.draggable.js": "^2.2.2", + "svg.easing.js": "^2.0.0", + "svg.filter.js": "^2.0.2", + "svg.pathmorphing.js": "^0.1.3", + "svg.resize.js": "^1.4.3", + "svg.select.js": "^3.0.1" + } + }, "aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -21800,6 +21923,14 @@ "loose-envify": "^1.1.0" } }, + "react-apexcharts": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.0.tgz", + "integrity": "sha512-DrcMV4aAMrUG+n6412yzyATWEyCDWlpPBBhVbpzBC4PDeuYU6iF84SmExbck+jx5MUm4U5PM3/T307Mc3kzc9Q==", + "requires": { + "prop-types": "^15.5.7" + } + }, "react-app-polyfill": { "version": "3.0.0", "requires": { @@ -22842,6 +22973,70 @@ "svg-parser": { "version": "2.0.4" }, + "svg.draggable.js": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz", + "integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==", + "requires": { + "svg.js": "^2.0.1" + } + }, + "svg.easing.js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz", + "integrity": "sha1-iqmUawqOJ4V6XEChDrpAkeVpHxI=", + "requires": { + "svg.js": ">=2.3.x" + } + }, + "svg.filter.js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz", + "integrity": "sha1-kQCOFROJ3ZIwd5/L5uLJo2LRwgM=", + "requires": { + "svg.js": "^2.2.5" + } + }, + "svg.js": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz", + "integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==" + }, + "svg.pathmorphing.js": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz", + "integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==", + "requires": { + "svg.js": "^2.4.0" + } + }, + "svg.resize.js": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz", + "integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==", + "requires": { + "svg.js": "^2.6.5", + "svg.select.js": "^2.1.2" + }, + "dependencies": { + "svg.select.js": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz", + "integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==", + "requires": { + "svg.js": "^2.2.5" + } + } + } + }, + "svg.select.js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz", + "integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==", + "requires": { + "svg.js": "^2.6.5" + } + }, "svgo": { "version": "1.3.2", "requires": { diff --git a/package.json b/package.json index 3716827..b0da195 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^12.1.4", "@testing-library/user-event": "^13.5.0", + "apexcharts": "^3.35.3", "axios": "^0.26.1", "bignumber.js": "^9.0.2", "jwt-decode": "^3.1.2", @@ -14,6 +15,7 @@ "node-sass": "^7.0.1", "rc-scrollbars": "^1.1.5", "react": "^18.0.0", + "react-apexcharts": "^1.4.0", "react-dom": "^18.0.0", "react-hot-toast": "^2.2.0", "react-router-dom": "^6.3.0", diff --git a/src/components/Dashboard/Charts/OrdersChart.js b/src/components/Dashboard/Charts/OrdersChart.js new file mode 100644 index 0000000..9fe6119 --- /dev/null +++ b/src/components/Dashboard/Charts/OrdersChart.js @@ -0,0 +1,134 @@ +import React, {useEffect, useState} from 'react'; +import Chart from 'react-apexcharts' +import {GetSupersetAccessToken, GetTotalOrders} from "./api"; +import Loading from "../../Loading"; + +const OrdersChart = () => { + + + const [loading, setLoading] = useState(true); + const [error, setError] = useState(false); + + const [orders, setOrders] = useState([{ + name: 'orders', + data: [] + }]) + + const [times, setTimes] = useState([]) + + useEffect(() => { + + GetSupersetAccessToken().then((res) => { + GetTotalOrders(res.data.access_token).then((res) => { + const series = [{ + name: 'orders' + }]; + series[0].data = res.data.result[0].data.map((t) => t["COUNT(id)"]) + const xAxis = res.data.result[0].data.map((t) => t["__timestamp"]) + setOrders(series) + setTimes(xAxis) + setLoading(false) + setError(false) + }).catch((e) => { + setLoading(false) + setError(true) + }) + }).catch((e) => { + setLoading(false) + setError(true) + }) + + + }, []) + + const options = { + chart: { + height: 350, + width: "100%", + type: 'area', + + toolbar: { + show: false, + }, + + zoom: { + enabled: false, + type: 'x', + autoScaleYaxis: false, + zoomedArea: { + fill: { + color: '#90CAF9', + opacity: 0.4 + }, + stroke: { + color: '#0D47A1', + opacity: 0.4, + width: 1 + } + } + }, + + + theme: { + mode: 'dark', + palette: 'palette1', + monochrome: { + enabled: false, + color: '#255aee', + shadeTo: 'dark', + shadeIntensity: 0.65 + }, + } + + }, + dataLabels: { + enabled: false + }, + stroke: { + curve: 'smooth' + }, + xaxis: { + type: 'datetime', + categories: [...times], + labels: { + style: { + colors: "#ecececc7" + }, + }, + }, + + yaxis: { + + labels: { + style: { + colors: "#ecececc7" + }, + }, + }, + + tooltip: { + enabled: true, + theme: "dark", + x: { + format: 'dd/MM/yy' + }, + }, + + }; + + const content = () => { + if (loading) { + return
+ } + if (error) { + return
Server Error
+ } else return + } + + + return ( + content() + ); +}; + +export default OrdersChart; \ No newline at end of file diff --git a/src/components/Dashboard/Charts/TradesByPair.js b/src/components/Dashboard/Charts/TradesByPair.js new file mode 100644 index 0000000..69bdfaf --- /dev/null +++ b/src/components/Dashboard/Charts/TradesByPair.js @@ -0,0 +1,11 @@ +import React from 'react'; + +const TradesByPair = () => { + return ( +
+ +
+ ); +}; + +export default TradesByPair; \ No newline at end of file diff --git a/src/components/Dashboard/Charts/TradesChart.js b/src/components/Dashboard/Charts/TradesChart.js new file mode 100644 index 0000000..d6f71ed --- /dev/null +++ b/src/components/Dashboard/Charts/TradesChart.js @@ -0,0 +1,134 @@ +import React, {useEffect, useState} from 'react'; +import Chart from 'react-apexcharts' +import {GetSupersetAccessToken, GetTotalOrders, GetTotalTrades} from "./api"; +import Loading from "../../Loading"; + +const TradesChart = () => { + + + const [loading, setLoading] = useState(true); + const [error, setError] = useState(false); + + const [orders, setOrders] = useState([{ + name: 'orders', + data: [] + }]) + + const [times, setTimes] = useState([]) + + useEffect(() => { + + GetSupersetAccessToken().then((res) => { + GetTotalTrades(res.data.access_token).then((res) => { + const series = [{ + name: 'trades' + }]; + series[0].data = res.data.result[0].data.map((t) => t["COUNT(id)"]) + const xAxis = res.data.result[0].data.map((t) => t["__timestamp"]) + setOrders(series) + setTimes(xAxis) + setLoading(false) + setError(false) + }).catch((e) => { + setLoading(false) + setError(true) + }) + }).catch((e) => { + setLoading(false) + setError(true) + }) + + + }, []) + + const options = { + chart: { + height: 350, + width: "100%", + type: 'area', + + toolbar: { + show: false, + }, + + zoom: { + enabled: false, + type: 'x', + autoScaleYaxis: false, + zoomedArea: { + fill: { + color: '#90CAF9', + opacity: 0.4 + }, + stroke: { + color: '#0D47A1', + opacity: 0.4, + width: 1 + } + } + }, + + theme: { + mode: 'dark', + palette: 'palette1', + monochrome: { + enabled: false, + color: '#255aee', + shadeTo: 'dark', + shadeIntensity: 0.65 + }, + } + + }, + + colors:['#7def9d', '#3acc6a', '#2c9c18'], + dataLabels: { + enabled: false + }, + stroke: { + curve: 'smooth' + }, + xaxis: { + type: 'datetime', + categories: [...times], + labels: { + style: { + colors: "#ecececc7" + }, + }, + }, + yaxis: { + min: 100, + max: 4000, + labels: { + style: { + colors: "#ecececc7" + }, + }, + }, + tooltip: { + enabled: true, + theme: "dark", + x: { + format: 'dd/MM/yy' + }, + }, + + }; + + const content = () => { + if (loading) { + return
+ } + if (error) { + return
Server Error
+ } else return + } + + + return ( + content() + ); +}; + +export default TradesChart; \ No newline at end of file diff --git a/src/components/Dashboard/Charts/api.js b/src/components/Dashboard/Charts/api.js new file mode 100644 index 0000000..d2536a6 --- /dev/null +++ b/src/components/Dashboard/Charts/api.js @@ -0,0 +1,36 @@ +import axios from "axios"; + +const Superset = axios.create({ + baseURL: window.env.REACT_APP_SUPERSET_URL, + timeout: 15000, +}); + + +export const GetSupersetAccessToken = () => { + const payload = { + "password":"admin", + "provider":"db", + "refresh":true, + "username":"admin" + } + return Superset.post(`/api/v1/security/login`, payload) +} + +export const GetTotalOrders = (supersetToken) => { + Superset.defaults.headers.common['Authorization'] = `Bearer ${supersetToken}`; + const payload = {"datasource":{"id":24,"type":"table"},"force":false,"queries":[{"time_range":"No filter","granularity":"create_date","filters":[],"extras":{"time_grain_sqla":"P1D","having":"","having_druid":[],"where":""},"applied_time_extras":{},"columns":[],"metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"id","description":null,"expression":null,"filterable":true,"groupby":true,"id":763,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"INTEGER","type_generic":0,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(id)","optionName":"metric_23yrkrt7dig_k94rvhqgt3s","sqlExpression":null}],"annotation_layers":[],"timeseries_limit":0,"order_desc":true,"url_params":{"form_data_key":"c89xY-LscESgWDaBEO1mZQKCqYKqLxY0IJLjL_OPvdgjkOJIQNv8cyad-pg8UKmj","slice_id":"134"},"custom_params":{},"custom_form_data":{},"is_timeseries":true,"post_processing":[{"operation":"pivot","options":{"index":["__timestamp"],"columns":[],"aggregates":{"COUNT(id)":{"operator":"mean"}},"drop_missing_columns":false,"flatten_columns":false,"reset_index":false}},null,null,{"operation":"flatten"}]}],"form_data":{"datasource":"24__table","viz_type":"big_number","slice_id":134,"url_params":{"form_data_key":"c89xY-LscESgWDaBEO1mZQKCqYKqLxY0IJLjL_OPvdgjkOJIQNv8cyad-pg8UKmj","slice_id":"134"},"granularity_sqla":"create_date","time_grain_sqla":"P1D","time_range":"No filter","metric":{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"id","description":null,"expression":null,"filterable":true,"groupby":true,"id":763,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"INTEGER","type_generic":0,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(id)","optionName":"metric_23yrkrt7dig_k94rvhqgt3s","sqlExpression":null},"adhoc_filters":[],"show_timestamp":true,"show_trend_line":true,"start_y_axis_at_zero":true,"color_picker":{"a":1,"b":137,"g":193,"r":90},"header_font_size":0.4,"subheader_font_size":0.15,"y_axis_format":"SMART_NUMBER","time_format":"smart_date","rolling_type":"None","extra_form_data":{},"force":null,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"} + return Superset.post(`/api/v1/chart/data`, payload) +} + +export const GetTotalTrades = (supersetToken) => { + Superset.defaults.headers.common['Authorization'] = `Bearer ${supersetToken}`; + const payload = {"datasource":{"id":25,"type":"table"},"force":false,"queries":[{"time_range":"No filter","granularity":"trade_date","filters":[],"extras":{"time_grain_sqla":"P1D","having":"","having_druid":[],"where":""},"applied_time_extras":{},"columns":[],"metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"id","description":null,"expression":null,"filterable":true,"groupby":true,"id":783,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"INTEGER","type_generic":0,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(id)","optionName":"metric_mj3d0qyo07h_nlz57z8jw9r","sqlExpression":null}],"annotation_layers":[],"timeseries_limit":0,"order_desc":true,"url_params":{"form_data_key":"kF9VNcBanNAEBkjrs93UPERhp-gCLSEaIDbc9-EoNjbuldF-wsipqXYyy0DnlJy0","slice_id":"137"},"custom_params":{},"custom_form_data":{},"is_timeseries":true,"post_processing":[{"operation":"pivot","options":{"index":["__timestamp"],"columns":[],"aggregates":{"COUNT(id)":{"operator":"mean"}},"drop_missing_columns":false,"flatten_columns":false,"reset_index":false}},{"operation":"flatten"}]}],"form_data":{"datasource":"25__table","viz_type":"big_number","slice_id":137,"url_params":{"form_data_key":"kF9VNcBanNAEBkjrs93UPERhp-gCLSEaIDbc9-EoNjbuldF-wsipqXYyy0DnlJy0","slice_id":"137"},"granularity_sqla":"trade_date","time_grain_sqla":"P1D","time_range":"No filter","metric":{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"id","description":null,"expression":null,"filterable":true,"groupby":true,"id":783,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"INTEGER","type_generic":0,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(id)","optionName":"metric_mj3d0qyo07h_nlz57z8jw9r","sqlExpression":null},"adhoc_filters":[],"compare_lag":"","compare_suffix":"","show_timestamp":true,"show_trend_line":true,"start_y_axis_at_zero":true,"color_picker":{"a":1,"b":68,"g":127,"r":255},"header_font_size":0.4,"subheader_font_size":0.15,"y_axis_format":"SMART_NUMBER","time_format":"smart_date","rolling_type":"None","extra_form_data":{},"force":null,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"} + return Superset.post(`/api/v1/chart/data`, payload) +} +export const NumberOfTradesByPair = (supersetToken) => { + Superset.defaults.headers.common['Authorization'] = `Bearer ${supersetToken}`; + const payload = {"datasource":{"id":24,"type":"table"},"force":false,"queries":[{"time_range":"No filter","granularity":"create_date","filters":[],"extras":{"time_grain_sqla":"P1D","having":"","having_druid":[],"where":""},"applied_time_extras":{},"columns":["symbol"],"metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"id","description":null,"expression":null,"filterable":true,"groupby":true,"id":763,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"INTEGER","type_generic":0,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(id)","optionName":"metric_6md1nf6j36y_yb4kf8kaej9","sqlExpression":null}],"orderby":[[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"id","description":null,"expression":null,"filterable":true,"groupby":true,"id":763,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"INTEGER","type_generic":0,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(id)","optionName":"metric_6md1nf6j36y_yb4kf8kaej9","sqlExpression":null},false]],"annotation_layers":[],"row_limit":10000,"series_columns":["symbol"],"timeseries_limit":0,"order_desc":true,"url_params":{"form_data_key":"4MpeVQSFtXd0kvNTyH4cIjhKC9nah703_bj-NuTAKRJKntjReGLVCduQ70yxUhPy","slice_id":"135"},"custom_params":{},"custom_form_data":{},"is_timeseries":true,"time_offsets":[],"post_processing":[{"operation":"pivot","options":{"index":["__timestamp"],"columns":["symbol"],"aggregates":{"COUNT(id)":{"operator":"mean"}},"drop_missing_columns":false,"flatten_columns":false,"reset_index":false}},{"operation":"rename","options":{"columns":{"COUNT(id)":null},"level":0,"inplace":true}},{"operation":"flatten"}]}],"form_data":{"datasource":"24__table","viz_type":"echarts_timeseries_smooth","slice_id":135,"url_params":{"form_data_key":"4MpeVQSFtXd0kvNTyH4cIjhKC9nah703_bj-NuTAKRJKntjReGLVCduQ70yxUhPy","slice_id":"135"},"granularity_sqla":"create_date","time_grain_sqla":"P1D","time_range":"No filter","metrics":[{"aggregate":"COUNT","column":{"advanced_data_type":null,"certification_details":null,"certified_by":null,"column_name":"id","description":null,"expression":null,"filterable":true,"groupby":true,"id":763,"is_certified":false,"is_dttm":false,"python_date_format":null,"type":"INTEGER","type_generic":0,"verbose_name":null,"warning_markdown":null},"expressionType":"SIMPLE","hasCustomLabel":false,"isNew":false,"label":"COUNT(id)","optionName":"metric_6md1nf6j36y_yb4kf8kaej9","sqlExpression":null}],"groupby":["symbol"],"adhoc_filters":[],"order_desc":true,"row_limit":10000,"rolling_type":null,"comparison_type":"values","annotation_layers":[],"forecastPeriods":10,"forecastInterval":0.8,"x_axis_title_margin":15,"y_axis_title_margin":15,"y_axis_title_position":"Left","color_scheme":"d3Category20","only_total":true,"markerSize":6,"show_legend":true,"legendType":"scroll","legendOrientation":"top","x_axis_time_format":"smart_date","rich_tooltip":true,"tooltipTimeFormat":"smart_date","y_axis_format":"SMART_NUMBER","y_axis_bounds":[null,null],"extra_form_data":{},"force":null,"result_format":"json","result_type":"full"},"result_format":"json","result_type":"full"} + return Superset.post(`/api/v1/chart/data`, payload) +} + + diff --git a/src/components/Dashboard/Dashboard.js b/src/components/Dashboard/Dashboard.js index f00ce74..3055a1b 100644 --- a/src/components/Dashboard/Dashboard.js +++ b/src/components/Dashboard/Dashboard.js @@ -1,8 +1,9 @@ import React, {useEffect, useState} from "react"; -import CounterWidget from "./CounterWidget"; import useAxiosPrivate from "../../hooks/useAxiosPrivate"; import Loading from "../Loading"; -import {toAbsoluteUrl} from "../utils"; +import OrdersChart from "./Charts/OrdersChart"; +import ScrollBar from "../ScrollBar"; +import TradesChart from "./Charts/TradesChart"; const Dashboard = () => { const [users, setUsers] = useState(null); @@ -55,49 +56,72 @@ const Dashboard = () => { }, []) - return
+ return +
-
+ {/*

Admin Panel

+*/} -
-
- {users !== null ? -
-

Total Users

- {users} -
: - } +
+
+ {users !== null ? +
+

Total Users

+ {users} +
: + } +
+
+ {withdraws !== null ? +
+

Withdraws Req

+ {withdraws} +
: + } +
+
+ {kyc !== null ? +
+

KYC Req

+ {kyc} +
: + } +
-
- {withdraws !== null ? -
-

Withdraws Req

- {withdraws} -
: - } -
-
- {kyc !== null ? -
-

KYC Req

- {kyc} -
: - } + + +
+
+

Total Orders

+
+
+
+

Total Trades

+
+
+
-
- {/*
+ {/*
} icon="fa-users" name="Total Users"/> } icon="fa-money-bill-transfer" name="Withdraw Req"/> } icon="fa-user" name="KYC Req"/>
*/} -
+ +
+ } diff --git a/src/scss/_layout.scss b/src/scss/_layout.scss index 4a0f5ad..055f680 100644 --- a/src/scss/_layout.scss +++ b/src/scss/_layout.scss @@ -5,6 +5,11 @@ body { html, body { font-family: 'Roboto Flex', iranyekan, serif; color: #ecececc7 !important; + +} + +h4{ + font-size: 1vw !important; } @@ -33,16 +38,12 @@ html, body { width: 100vw; height: 100vh; display: flex; - background: red !important; z-index: 180000; } .sidebar { height: 100vh; - width: 10%; - /* - background: #0a2555; - */ + width: 13%; background: #24242e; color: #f7f7f7; position: fixed; @@ -61,11 +62,9 @@ html, body { flex-direction: column; justify-content: space-between; overflow: hidden; - width: 90%; + width: 87%; height: 100vh; - background: greenyellow; - - margin-left: 10%; + margin-left: 13%; transition: all 0.5s; }