PluginProbe ʕ •ᴥ•ʔ
Presto Player / trunk
Presto Player vtrunk
4.3.0 4.2.4 4.2.3 4.2.2 4.2.0 4.2.1 trunk 1.10.0 1.10.1 1.10.2 1.11.0 1.12.0 1.13.0 1.14.0 1.14.1 1.5.10 1.5.11 1.5.12 1.5.13 1.5.14 1.5.15 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.13 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3-beta1 2.3.0 2.3.1 2.3.2 2.3.3 3.0.0 3.0.0-beta1 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.1.0 3.1.1 3.1.2 3.1.3 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4
presto-player / src / admin / dashboard / hooks / useTopPerforming.js
presto-player / src / admin / dashboard / hooks Last commit date
test 1 week ago useCompleteOnboarding.js 1 week ago useDateRangePicker.js 1 month ago useEmail.ts 1 month ago useEngagementChartData.js 1 month ago useLicenseSettings.js 1 month ago useLink.js 1 month ago useMediaDetail.js 1 month ago useMediaLibrary.js 1 month ago useMediaList.ts 1 month ago usePerformanceSettings.js 1 month ago useRegisterActivePage.js 1 month ago useSettingOption.js 1 month ago useSimpleSettingsPage.js 1 month ago useTopPerforming.js 1 month ago useTopVideosPaginated.js 1 month ago useUpgradeCTA.js 1 month ago useUserDetail.js 1 month ago
useTopPerforming.js
139 lines
1 import { useState, useEffect, useMemo } from "@wordpress/element";
2 import apiFetch from "@wordpress/api-fetch";
3 import { addQueryArgs } from "@wordpress/url";
4 import { transformUserItem } from "../utils/transformers";
5 import { ALL_TIME_START, toAnalyticsDate } from "../utils";
6 import useTopVideosPaginated from "./useTopVideosPaginated";
7
8 /**
9 * Hook to fetch top performing media and users with server-side pagination.
10 *
11 * Pass `selectedDates` (the same shape exposed by `useEngagementChartData`)
12 * to keep the tables in sync with the chart's date filter. When
13 * `selectedDates` is null/empty, the hook falls back to all-time so the
14 * Dashboard tab and free-version surfaces keep their existing snapshot
15 * behaviour.
16 *
17 * Both media and users are paginated via the same X-WP-Total /
18 * X-WP-TotalPages convention exposed by the analytics REST controller.
19 * Each card owns its own fetch lifecycle and abort controller so the two
20 * tables can re-paginate independently without cancelling one another.
21 *
22 * @param {Object} options
23 * @param {number} [options.mediaPerPage=10]
24 * @param {number} [options.usersPerPage=5]
25 * @param {{from: ?Date, to: ?Date}} [options.selectedDates]
26 */
27 const useTopPerforming = ({
28 mediaPerPage = 10,
29 usersPerPage = 5,
30 selectedDates,
31 } = {}) => {
32 const isPremium = !!window?.prestoPlayer?.isPremium;
33
34 const dateParams = useMemo(() => {
35 const from = selectedDates?.from;
36 const to = selectedDates?.to;
37 return {
38 start: from ? toAnalyticsDate(from) : ALL_TIME_START,
39 end: toAnalyticsDate(to || from || new Date()),
40 };
41 }, [selectedDates?.from, selectedDates?.to]);
42
43 // --- Media (delegated to the shared paginated hook) ---
44 const {
45 topMedia,
46 isLoading: isLoadingMedia,
47 error: mediaError,
48 page: mediaPage,
49 setPage: setMediaPage,
50 pagination: mediaPagination,
51 } = useTopVideosPaginated({
52 dateParams,
53 perPage: mediaPerPage,
54 enabled: isPremium,
55 });
56
57 // --- Users (kept inline; no equivalent shared hook yet) ---
58 const [topUsers, setTopUsers] = useState([]);
59 const [usersPage, setUsersPage] = useState(1);
60 const [usersPagination, setUsersPagination] = useState({
61 totalItems: 0,
62 totalPages: 0,
63 });
64 const [usersError, setUsersError] = useState(null);
65 const [hasLoadedUsers, setHasLoadedUsers] = useState(!isPremium);
66
67 useEffect(() => {
68 setUsersPage(1);
69 }, [dateParams.start, dateParams.end]);
70
71 useEffect(() => {
72 if (!isPremium) {
73 setTopUsers([]);
74 setHasLoadedUsers(true);
75 return undefined;
76 }
77
78 const controller = new AbortController();
79
80 (async () => {
81 try {
82 const response = await apiFetch({
83 path: addQueryArgs(window.prestoPlayer.api.analyticsTopUsers, {
84 ...dateParams,
85 per_page: usersPerPage,
86 page: usersPage,
87 }),
88 parse: false,
89 signal: controller.signal,
90 });
91 const totalItems = parseInt(
92 response.headers.get("X-WP-Total") || "0",
93 10
94 );
95 const totalPages = parseInt(
96 response.headers.get("X-WP-TotalPages") || "0",
97 10
98 );
99 const json = await response.json();
100
101 setTopUsers((json || []).map(transformUserItem));
102 setUsersPagination({ totalItems, totalPages });
103 setUsersError(null);
104 } catch (err) {
105 if (err.name === "AbortError") return;
106 setUsersError(err.message || "An error occurred");
107 console.error("Error fetching top performing users:", err);
108 setTopUsers([]);
109 } finally {
110 setHasLoadedUsers(true);
111 }
112 })();
113
114 return () => controller.abort();
115 }, [isPremium, dateParams, usersPage, usersPerPage]);
116
117 const data = {
118 topMedia,
119 topUsers,
120 };
121
122 const isLoading = isPremium && (isLoadingMedia || !hasLoadedUsers);
123 const error = mediaError || usersError;
124
125 return {
126 data,
127 isLoading,
128 error,
129 mediaPage,
130 setMediaPage,
131 mediaPagination,
132 usersPage,
133 setUsersPage,
134 usersPagination,
135 };
136 };
137
138 export default useTopPerforming;
139