1- import React , { useEffect , useState , lazy , useReducer , useRef } from "react" ;
1+ import React , {
2+ useEffect ,
3+ useState ,
4+ lazy ,
5+ useReducer ,
6+ useRef ,
7+ useMemo ,
8+ } from "react" ;
29import type {
310 DashboardAnalyticsConfig ,
411 ChartDataPoint ,
512 ChartWidget ,
13+ IdMatcherFunction ,
614} from "../../types" ;
715import type { AxisOptions } from "react-charts" ;
16+ import { useDocumentInfo } from "payload/components/utilities" ;
817import { MetricMap } from "../../providers/plausible/client" ;
918import { useTheme } from "payload/dist/admin/components/utilities/Theme" ;
1019
@@ -16,6 +25,7 @@ type ChartData = {
1625type ChartOptions = {
1726 timeframe ?: string ;
1827 metric : ChartWidget [ "metric" ] ;
28+ idMatcher : IdMatcherFunction ;
1929} ;
2030
2131type Props = {
@@ -30,38 +40,57 @@ const ChartComponent = lazy(() =>
3040
3141const ViewsChart : React . FC < Props > = ( { options } ) => {
3242 const [ chartData , setChartData ] = useState < ChartData [ ] > ( [ ] ) ;
43+ const [ isLoading , setIsLoading ] = useState < boolean > ( true ) ;
3344 const chartRef = useRef < any > ( null ) ;
3445 const theme = useTheme ( ) ;
46+ const { publishedDoc } = useDocumentInfo ( ) ;
3547
36- const { timeframe, metric } = options ;
48+ const { timeframe, metric, idMatcher } = options ;
49+
50+ const pageId = useMemo ( ( ) => {
51+ if ( publishedDoc ) return idMatcher ( publishedDoc ) ;
52+ else return "" ;
53+ } , [ publishedDoc ] ) ;
3754
3855 const timeframeIndicator =
3956 timeframe === "month"
4057 ? new Date ( ) . toLocaleString ( "default" , { month : "long" } )
4158 : timeframe ?? "30d" ;
4259
4360 useEffect ( ( ) => {
44- const getChartData = fetch ( `/api/analytics/globalChartData` , {
45- method : "post" ,
46- credentials : "include" ,
47- headers : {
48- Accept : "application/json" ,
49- "Content-Type" : "application/json" ,
50- } ,
51- body : JSON . stringify ( { timeframe : timeframe , metric : metric } ) ,
52- } ) . then ( ( response ) => response . json ( ) ) ;
53-
54- getChartData . then ( ( data : ChartDataPoint [ ] ) => {
55- const processedData : ChartData [ ] = [
56- {
57- label : "Visitors" ,
58- data : data ,
61+ if ( pageId ) {
62+ const getChartData = fetch ( `/api/analytics/pageChartData` , {
63+ method : "post" ,
64+ credentials : "include" ,
65+ headers : {
66+ Accept : "application/json" ,
67+ "Content-Type" : "application/json" ,
5968 } ,
60- ] ;
61- setChartData ( processedData ) ;
62- } ) ;
69+ body : JSON . stringify ( {
70+ timeframe : timeframe ,
71+ metric : metric ,
72+ pageId : pageId ,
73+ } ) ,
74+ } ) . then ( ( response ) => response . json ( ) ) ;
75+
76+ getChartData . then ( ( data : ChartDataPoint [ ] ) => {
77+ const processedData : ChartData [ ] = [
78+ {
79+ label : MetricMap [ metric ] . label ,
80+ data : data ,
81+ } ,
82+ ] ;
83+ setChartData ( processedData ) ;
84+ setIsLoading ( false ) ;
85+ } ) ;
86+ } else {
87+ setIsLoading ( false ) ;
88+ }
89+ } , [ publishedDoc , pageId ] ) ;
6390
91+ useEffect ( ( ) => {
6492 const importChart = async ( ) => {
93+ /* Dynamic import for react-charts due to ESM and how bundling is done with Payload */
6594 const { Chart } = await import ( "react-charts" ) ;
6695 chartRef . current = Chart ;
6796 } ;
@@ -96,7 +125,10 @@ const ViewsChart: React.FC<Props> = ({ options }) => {
96125 marginBottom : "1.5rem" ,
97126 } }
98127 >
99- { chartRef ?. current && chartData ?. length && chartData . length > 0 ? (
128+ { pageId !== "" &&
129+ chartRef ?. current &&
130+ chartData ?. length &&
131+ chartData . length > 0 ? (
100132 < >
101133 < h1 style = { { fontSize : "1.25rem" , marginBottom : "0.5rem" } } >
102134 { MetricMap [ metric ] . label } ({ timeframeIndicator } )
@@ -116,8 +148,10 @@ const ViewsChart: React.FC<Props> = ({ options }) => {
116148 />
117149 </ div >
118150 </ >
151+ ) : isLoading ? (
152+ < > Loading...</ >
119153 ) : (
120- < > </ >
154+ < div > No { MetricMap [ metric ] . label } data found. </ div >
121155 ) }
122156 </ section >
123157 ) ;
0 commit comments