diff --git a/package-lock.json b/package-lock.json index c871d64..4a4633d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,6 @@ "dicebear": "^9.2.1", "flatpickr": "^4.6.13", "headlessui": "^0.0.0", - "jsvectormap": "^1.5.3", "match-sorter": "^6.3.1", "react": "^18.2.0", "react-apexcharts": "^1.4.1", @@ -4462,11 +4461,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jsvectormap": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/jsvectormap/-/jsvectormap-1.5.3.tgz", - "integrity": "sha512-HStTEhZEVr8t3t6juApO603nr1y54K/wjcdOvgGtvpE1etZ9Isg/sLdqh7OX4+RJ8srdP7WiBoTV/93aMqhLhw==" - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz", diff --git a/package.json b/package.json index 0df5313..516adc2 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,6 @@ "dicebear": "^9.2.1", "flatpickr": "^4.6.13", "headlessui": "^0.0.0", - "jsvectormap": "^1.5.3", "match-sorter": "^6.3.1", "react": "^18.2.0", "react-apexcharts": "^1.4.1", diff --git a/src/components/Charts/ChartThree.tsx b/src/components/Charts/ChartThree.tsx deleted file mode 100644 index d21012a..0000000 --- a/src/components/Charts/ChartThree.tsx +++ /dev/null @@ -1,163 +0,0 @@ -import { ApexOptions } from 'apexcharts'; -import React, { useState } from 'react'; -import ReactApexChart from 'react-apexcharts'; - -interface ChartThreeState { - series: number[]; -} - -const options: ApexOptions = { - chart: { - fontFamily: 'Satoshi, sans-serif', - type: 'donut', - }, - colors: ['#3C50E0', '#6577F3', '#8FD0EF', '#0FADCF'], - labels: ['Desktop', 'Tablet', 'Mobile', 'Unknown'], - legend: { - show: false, - position: 'bottom', - }, - - plotOptions: { - pie: { - donut: { - size: '65%', - background: 'transparent', - }, - }, - }, - dataLabels: { - enabled: false, - }, - responsive: [ - { - breakpoint: 2600, - options: { - chart: { - width: 380, - }, - }, - }, - { - breakpoint: 640, - options: { - chart: { - width: 200, - }, - }, - }, - ], -}; - -const ChartThree: React.FC = () => { - const [state, setState] = useState({ - series: [65, 34, 12, 56], - }); - - const handleReset = () => { - setState((prevState) => ({ - ...prevState, - series: [65, 34, 12, 56], - })); - }; - handleReset; - - return ( -
-
-
-
- Visitors Analytics -
-
-
-
- - - - - - - -
-
-
- -
-
- -
-
- -
-
-
- -

- Desktop - 65% -

-
-
-
-
- -

- Tablet - 34% -

-
-
-
-
- -

- Mobile - 45% -

-
-
-
-
- -

- Unknown - 12% -

-
-
-
-
- ); -}; - -export default ChartThree; diff --git a/src/components/Maps/MapOne.tsx b/src/components/Maps/MapOne.tsx deleted file mode 100644 index c20d375..0000000 --- a/src/components/Maps/MapOne.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import jsVectorMap from 'jsvectormap'; -import 'jsvectormap/dist/css/jsvectormap.css'; -import { useEffect } from 'react'; -import '../../js/us-aea-en'; - -const MapOne = () => { - useEffect(() => { - const mapOne = new jsVectorMap({ - selector: '#mapOne', - map: 'us_aea_en', - zoomButtons: true, - - regionStyle: { - initial: { - fill: '#C8D0D8', - }, - hover: { - fillOpacity: 1, - fill: '#3056D3', - }, - }, - regionLabelStyle: { - initial: { - fontFamily: 'Satoshi', - fontWeight: 'semibold', - fill: '#fff', - }, - hover: { - cursor: 'pointer', - }, - }, - - labels: { - regions: { - render(code: string) { - return code.split('-')[1]; - }, - }, - }, - }); - mapOne; - }); - - return ( -
-

- Region labels -

-
-
- ); -}; - -export default MapOne; diff --git a/src/components/Tables/TableOne.tsx b/src/components/Tables/TableOne.tsx deleted file mode 100644 index 5619a5d..0000000 --- a/src/components/Tables/TableOne.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import { BRAND } from '../../types/app/brand'; -import BrandOne from '../../images/brand/brand-01.svg'; -import BrandTwo from '../../images/brand/brand-02.svg'; -import BrandThree from '../../images/brand/brand-03.svg'; -import BrandFour from '../../images/brand/brand-04.svg'; -import BrandFive from '../../images/brand/brand-05.svg'; - -const brandData: BRAND[] = [ - { - logo: BrandOne, - name: 'Google', - visitors: 3.5, - revenues: '5,768', - sales: 590, - conversion: 4.8, - }, - { - logo: BrandTwo, - name: 'Twitter', - visitors: 2.2, - revenues: '4,635', - sales: 467, - conversion: 4.3, - }, - { - logo: BrandThree, - name: 'Github', - visitors: 2.1, - revenues: '4,290', - sales: 420, - conversion: 3.7, - }, - { - logo: BrandFour, - name: 'Vimeo', - visitors: 1.5, - revenues: '3,580', - sales: 389, - conversion: 2.5, - }, - { - logo: BrandFive, - name: 'Facebook', - visitors: 3.5, - revenues: '6,768', - sales: 390, - conversion: 4.2, - }, -]; - -const TableOne = () => { - return ( -
-

- Top Channels -

- -
-
-
-
- Source -
-
-
-
- Visitors -
-
-
-
- Revenues -
-
-
-
- Sales -
-
-
-
- Conversion -
-
-
- - {brandData.map((brand, key) => ( -
-
-
- Brand -
-

- {brand.name} -

-
- -
-

{brand.visitors}K

-
- -
-

${brand.revenues}

-
- -
-

{brand.sales}

-
- -
-

{brand.conversion}%

-
-
- ))} -
-
- ); -}; - -export default TableOne; diff --git a/src/components/Tables/TableThree.tsx b/src/components/Tables/TableThree.tsx deleted file mode 100644 index aaa18d1..0000000 --- a/src/components/Tables/TableThree.tsx +++ /dev/null @@ -1,156 +0,0 @@ -import { Package } from '../../types/app/package'; - -const packageData: Package[] = [ - { - name: 'Free package', - price: 0.0, - invoiceDate: `Jan 13,2023`, - status: 'Paid', - }, - { - name: 'Standard Package', - price: 59.0, - invoiceDate: `Jan 13,2023`, - status: 'Paid', - }, - { - name: 'Business Package', - price: 99.0, - invoiceDate: `Jan 13,2023`, - status: 'Unpaid', - }, - { - name: 'Standard Package', - price: 59.0, - invoiceDate: `Jan 13,2023`, - status: 'Pending', - }, -]; - -const TableThree = () => { - return ( -
-
- - - - - - - - - - - {packageData.map((packageItem, key) => ( - - - - - - - ))} - -
- Package - - Invoice date - - Status - - Actions -
-
- {packageItem.name} -
-

${packageItem.price}

-
-

- {packageItem.invoiceDate} -

-
-

- {packageItem.status} -

-
-
- - - -
-
-
-
- ); -}; - -export default TableThree; diff --git a/src/components/Tables/TableTwo.tsx b/src/components/Tables/TableTwo.tsx deleted file mode 100644 index 92734b5..0000000 --- a/src/components/Tables/TableTwo.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import { Product } from '../../types/app/product'; -import ProductOne from '../../images/product/product-01.png'; -import ProductTwo from '../../images/product/product-02.png'; -import ProductThree from '../../images/product/product-03.png'; -import ProductFour from '../../images/product/product-04.png'; - -const productData: Product[] = [ - { - image: ProductOne, - name: 'Apple Watch Series 7', - category: 'Electronics', - price: 296, - sold: 22, - profit: 45, - }, - { - image: ProductTwo, - name: 'Macbook Pro M1', - category: 'Electronics', - price: 546, - sold: 12, - profit: 125, - }, - { - image: ProductThree, - name: 'Dell Inspiron 15', - category: 'Electronics', - price: 443, - sold: 64, - profit: 247, - }, - { - image: ProductFour, - name: 'HP Probook 450', - category: 'Electronics', - price: 499, - sold: 72, - profit: 103, - }, -]; - -const TableTwo = () => { - return ( -
-
-

- Top Products -

-
- -
-
-

Product Name

-
-
-

Category

-
-
-

Price

-
-
-

Sold

-
-
-

Profit

-
-
- - {productData.map((product, key) => ( -
-
-
-
- Product -
-

- {product.name} -

-
-
-
-

- {product.category} -

-
-
-

- ${product.price} -

-
-
-

{product.sold}

-
-
-

${product.profit}

-
-
- ))} -
- ); -}; - -export default TableTwo; diff --git a/src/components/Charts/ChartTwo.tsx b/src/pages/Stats/components/NewOldVisitors/ChartTwo.tsx similarity index 100% rename from src/components/Charts/ChartTwo.tsx rename to src/pages/Stats/components/NewOldVisitors/ChartTwo.tsx diff --git a/src/components/Charts/chart.d.ts b/src/pages/Stats/components/NewOldVisitors/chart.d.ts similarity index 100% rename from src/components/Charts/chart.d.ts rename to src/pages/Stats/components/NewOldVisitors/chart.d.ts diff --git a/src/pages/Stats/components/NewOldVisitors/index.tsx b/src/pages/Stats/components/NewOldVisitors/index.tsx new file mode 100644 index 0000000..3f02396 --- /dev/null +++ b/src/pages/Stats/components/NewOldVisitors/index.tsx @@ -0,0 +1,124 @@ +import { ApexOptions } from 'apexcharts'; +import React, { useEffect, useState } from 'react'; +import ReactApexChart from 'react-apexcharts'; +import dayjs from 'dayjs'; + +interface ChartThreeState { + series: number[]; +} + +const options: ApexOptions = { + chart: { + fontFamily: 'Satoshi, sans-serif', + type: 'donut', + }, + colors: ['#91C8EA', '#727cf5'], + labels: ['新访客', '老访客'], + legend: { + show: false, + position: 'bottom', + }, + plotOptions: { + pie: { + donut: { + size: '65%', + background: 'transparent', + }, + }, + }, + dataLabels: { + enabled: false, + }, + responsive: [ + { + breakpoint: 2600, + options: { + chart: { + width: 380, + }, + }, + }, + { + breakpoint: 640, + options: { + chart: { + width: 200, + }, + }, + }, + ], +}; + +const ChartThree: React.FC = () => { + const [result, setResult] = useState({ newVisitors: 0, oldVisitors: 0 }) + const [date, setDate] = useState(dayjs(new Date()).format("YYYY/MM/DD")); + + const [state, setState] = useState({ + series: [0, 0], + }); + + const getDataList = async () => { + const siteId = import.meta.env.VITE_BAIDU_TONGJI_SITE_ID; + const token = import.meta.env.VITE_BAIDU_TONGJI_ACCESS_TOKEN; + + const response = await fetch(`/api/rest/2.0/tongji/report/getData?access_token=${token}&site_id=${siteId}&start_date=${date}&end_date=${date}&metrics=new_visitor_count%2Cnew_visitor_ratio&method=trend%2Ftime%2Fa&gran=day&area=`); + const data = await response.json(); + const { result } = data; + + const newVisitors = result.items[1][0][1] + const oldVisitors = 100 - result.items[1][0][1] + + setState({ series: [newVisitors, oldVisitors] }) + setResult({ newVisitors, oldVisitors }) + } + + useEffect(() => { + getDataList() + }, []) + + return ( +
+
+
+
+ 新老访客 +
+
+
+ +
+
+ +
+
+ +
+
+
+ +

+ 新访客 + {result.newVisitors}% +

+
+
+ +
+
+ +

+ 老访客 + {result.oldVisitors}% +

+
+
+
+
+ ); +}; + +export default ChartThree; diff --git a/src/pages/Stats/components/VisitorsStatisChat/index.tsx b/src/pages/Stats/components/VisitorsStatisChat/index.tsx index 930fce7..498dec5 100644 --- a/src/pages/Stats/components/VisitorsStatisChat/index.tsx +++ b/src/pages/Stats/components/VisitorsStatisChat/index.tsx @@ -13,7 +13,7 @@ const VisitorsStatisChat = () => { const [endDate, setEndDate] = useState(dayjs(new Date()).format("YYYY/MM/DD")); const [loading, setLoading] = useState(false); - // Echarts相关配置 + // 图表相关配置 const [options, setOptions] = useState({ legend: { show: false, diff --git a/src/pages/Stats/index.tsx b/src/pages/Stats/index.tsx index 88254c9..d37471b 100644 --- a/src/pages/Stats/index.tsx +++ b/src/pages/Stats/index.tsx @@ -1,14 +1,12 @@ import Title from "@/components/Title" import VisitorsStatisChat from "./components/VisitorsStatisChat" -import ChartThree from "@/components/Charts/ChartThree" -import ChartTwo from "@/components/Charts/ChartTwo" +import NewOldVisitors from './components/NewOldVisitors' +import ChartTwo from "./components/VisitorsStatisChat" import ChatCard from "@/components/Chat/ChatCard" -import MapOne from "@/components/Maps/MapOne" -import TableOne from "@/components/Tables/TableOne" import CardDataStats from "@/components/CardDataStats" import { AiOutlineEye, AiOutlineMeh, AiOutlineStock, AiOutlineFieldTime } from "react-icons/ai"; -import { useCallback, useEffect, useState } from "react" +import { useEffect, useState } from "react" import dayjs from 'dayjs'; import { Result } from "./type" @@ -41,6 +39,8 @@ export default () => { const response = await fetch(`/api/rest/2.0/tongji/report/getData?access_token=${token}&site_id=${siteId}&start_date=${date}&end_date=${date}&metrics=pv_count%2Cip_count%2Cbounce_ratio%2Cavg_visit_time&method=overview%2FgetTimeTrendRpt`); const data = await response.json(); const { result } = data; + console.log(result); + setResult(result); let pv = 0; @@ -50,16 +50,25 @@ export default () => { let count = 0 result.items[1].forEach((item: number[]) => { - if (!Number(item[0])) return; + if (Number(item[3])) { + pv += Number(item[0]); + ip += Number(item[1]); + bounce += Number(item[2]); + avgTime += Number(item[3]); + } else if (Number(item[2])) { + pv += Number(item[0]); + ip += Number(item[1]); + bounce += Number(item[2]); + } else if (Number(item[1])) { + pv += Number(item[0]); + ip += Number(item[1]); + } else if (Number(item[0])) { + pv += Number(item[0]); + } - count++ - pv += Number(item[0]); - ip += Number(item[1]); - bounce += Number(item[2]); - avgTime += Number(item[3]); + count++; }); - console.log(count, bounce, avgTime); setStats({ pv, ip, bounce: bounce / count, avgTime: formatTime(avgTime / count) }) }; @@ -72,6 +81,7 @@ export default () => { <> + {/* 基本数据 */} <div className="mt-2 grid grid-cols-1 gap-2 md:grid-cols-2 xl:grid-cols-4"> <CardDataStats title="今日访客" total={stats.pv + ''} rate="0.43%" levelUp> <AiOutlineEye className="fill-primary dark:fill-white text-2xl" /> @@ -92,15 +102,9 @@ export default () => { <div className="rounded-lg mt-2 grid grid-cols-12 gap-2"> <VisitorsStatisChat /> - <ChartTwo /> - <ChartThree /> - <MapOne /> - - <div className="col-span-12 xl:col-span-8"> - <TableOne /> - </div> - - <ChatCard /> + <NewOldVisitors /> + {/* <ChartTwo /> + <ChatCard /> */} </div> </> )