- ✅ 覆盖了 45+个追踪事件 - ✅ 补充了 4个核心功能模块的完整埋点 - ✅ 提供了 详细的集成指南和示例代码 - ✅ 提升了 Retention指标覆盖率至90% - ✅ 建立了 Revenue转化追踪基础
326 lines
9.3 KiB
JavaScript
326 lines
9.3 KiB
JavaScript
// src/hooks/useDashboardEvents.js
|
||
// 个人中心(Dashboard/Center)事件追踪 Hook
|
||
|
||
import { useCallback, useEffect } from 'react';
|
||
import { usePostHogTrack } from './usePostHogRedux';
|
||
import { RETENTION_EVENTS } from '../lib/constants';
|
||
import { logger } from '../utils/logger';
|
||
|
||
/**
|
||
* 个人中心事件追踪 Hook
|
||
* @param {Object} options - 配置选项
|
||
* @param {string} options.pageType - 页面类型 ('center' | 'profile' | 'settings')
|
||
* @param {Function} options.navigate - 路由导航函数
|
||
* @returns {Object} 事件追踪处理函数集合
|
||
*/
|
||
export const useDashboardEvents = ({ pageType = 'center', navigate } = {}) => {
|
||
const { track } = usePostHogTrack();
|
||
|
||
// 🎯 页面浏览事件 - 页面加载时触发
|
||
useEffect(() => {
|
||
const eventMap = {
|
||
'center': RETENTION_EVENTS.DASHBOARD_CENTER_VIEWED,
|
||
'profile': RETENTION_EVENTS.PROFILE_PAGE_VIEWED,
|
||
'settings': RETENTION_EVENTS.SETTINGS_PAGE_VIEWED,
|
||
};
|
||
|
||
const eventName = eventMap[pageType] || RETENTION_EVENTS.DASHBOARD_VIEWED;
|
||
|
||
track(eventName, {
|
||
page_type: pageType,
|
||
timestamp: new Date().toISOString(),
|
||
});
|
||
|
||
logger.debug('useDashboardEvents', `📊 Dashboard Page Viewed: ${pageType}`);
|
||
}, [track, pageType]);
|
||
|
||
/**
|
||
* 追踪功能卡片点击
|
||
* @param {string} cardName - 卡片名称 ('watchlist' | 'following_events' | 'comments' | 'subscription')
|
||
* @param {Object} cardData - 卡片数据
|
||
*/
|
||
const trackFunctionCardClicked = useCallback((cardName, cardData = {}) => {
|
||
if (!cardName) {
|
||
logger.warn('useDashboardEvents', 'Card name is required');
|
||
return;
|
||
}
|
||
|
||
track(RETENTION_EVENTS.FUNCTION_CARD_CLICKED, {
|
||
card_name: cardName,
|
||
data_count: cardData.count || 0,
|
||
has_data: Boolean(cardData.count && cardData.count > 0),
|
||
timestamp: new Date().toISOString(),
|
||
});
|
||
|
||
logger.debug('useDashboardEvents', '🎴 Function Card Clicked', {
|
||
cardName,
|
||
count: cardData.count,
|
||
});
|
||
}, [track]);
|
||
|
||
/**
|
||
* 追踪自选股列表查看
|
||
* @param {number} stockCount - 自选股数量
|
||
* @param {boolean} hasRealtime - 是否有实时行情
|
||
*/
|
||
const trackWatchlistViewed = useCallback((stockCount = 0, hasRealtime = false) => {
|
||
track('Watchlist Viewed', {
|
||
stock_count: stockCount,
|
||
has_realtime: hasRealtime,
|
||
is_empty: stockCount === 0,
|
||
timestamp: new Date().toISOString(),
|
||
});
|
||
|
||
logger.debug('useDashboardEvents', '⭐ Watchlist Viewed', {
|
||
stockCount,
|
||
hasRealtime,
|
||
});
|
||
}, [track]);
|
||
|
||
/**
|
||
* 追踪自选股点击
|
||
* @param {Object} stock - 股票对象
|
||
* @param {string} stock.code - 股票代码
|
||
* @param {string} stock.name - 股票名称
|
||
* @param {number} position - 在列表中的位置
|
||
*/
|
||
const trackWatchlistStockClicked = useCallback((stock, position = 0) => {
|
||
if (!stock || !stock.code) {
|
||
logger.warn('useDashboardEvents', 'Stock object is required');
|
||
return;
|
||
}
|
||
|
||
track(RETENTION_EVENTS.STOCK_CLICKED, {
|
||
stock_code: stock.code,
|
||
stock_name: stock.name || '',
|
||
source: 'watchlist',
|
||
position,
|
||
timestamp: new Date().toISOString(),
|
||
});
|
||
|
||
logger.debug('useDashboardEvents', '🎯 Watchlist Stock Clicked', {
|
||
stockCode: stock.code,
|
||
position,
|
||
});
|
||
}, [track]);
|
||
|
||
/**
|
||
* 追踪自选股添加
|
||
* @param {Object} stock - 股票对象
|
||
* @param {string} stock.code - 股票代码
|
||
* @param {string} stock.name - 股票名称
|
||
* @param {string} source - 来源 ('search' | 'stock_detail' | 'manual')
|
||
*/
|
||
const trackWatchlistStockAdded = useCallback((stock, source = 'manual') => {
|
||
if (!stock || !stock.code) {
|
||
logger.warn('useDashboardEvents', 'Stock object is required');
|
||
return;
|
||
}
|
||
|
||
track('Watchlist Stock Added', {
|
||
stock_code: stock.code,
|
||
stock_name: stock.name || '',
|
||
source,
|
||
timestamp: new Date().toISOString(),
|
||
});
|
||
|
||
logger.debug('useDashboardEvents', '➕ Watchlist Stock Added', {
|
||
stockCode: stock.code,
|
||
source,
|
||
});
|
||
}, [track]);
|
||
|
||
/**
|
||
* 追踪自选股移除
|
||
* @param {Object} stock - 股票对象
|
||
* @param {string} stock.code - 股票代码
|
||
* @param {string} stock.name - 股票名称
|
||
*/
|
||
const trackWatchlistStockRemoved = useCallback((stock) => {
|
||
if (!stock || !stock.code) {
|
||
logger.warn('useDashboardEvents', 'Stock object is required');
|
||
return;
|
||
}
|
||
|
||
track('Watchlist Stock Removed', {
|
||
stock_code: stock.code,
|
||
stock_name: stock.name || '',
|
||
timestamp: new Date().toISOString(),
|
||
});
|
||
|
||
logger.debug('useDashboardEvents', '➖ Watchlist Stock Removed', {
|
||
stockCode: stock.code,
|
||
});
|
||
}, [track]);
|
||
|
||
/**
|
||
* 追踪关注的事件列表查看
|
||
* @param {number} eventCount - 关注的事件数量
|
||
*/
|
||
const trackFollowingEventsViewed = useCallback((eventCount = 0) => {
|
||
track('Following Events Viewed', {
|
||
event_count: eventCount,
|
||
is_empty: eventCount === 0,
|
||
timestamp: new Date().toISOString(),
|
||
});
|
||
|
||
logger.debug('useDashboardEvents', '📌 Following Events Viewed', {
|
||
eventCount,
|
||
});
|
||
}, [track]);
|
||
|
||
/**
|
||
* 追踪关注的事件点击
|
||
* @param {Object} event - 事件对象
|
||
* @param {number} event.id - 事件ID
|
||
* @param {string} event.title - 事件标题
|
||
* @param {number} position - 在列表中的位置
|
||
*/
|
||
const trackFollowingEventClicked = useCallback((event, position = 0) => {
|
||
if (!event || !event.id) {
|
||
logger.warn('useDashboardEvents', 'Event object is required');
|
||
return;
|
||
}
|
||
|
||
track(RETENTION_EVENTS.NEWS_ARTICLE_CLICKED, {
|
||
news_id: event.id,
|
||
news_title: event.title || '',
|
||
source: 'following_events',
|
||
position,
|
||
timestamp: new Date().toISOString(),
|
||
});
|
||
|
||
logger.debug('useDashboardEvents', '📰 Following Event Clicked', {
|
||
eventId: event.id,
|
||
position,
|
||
});
|
||
}, [track]);
|
||
|
||
/**
|
||
* 追踪事件评论列表查看
|
||
* @param {number} commentCount - 评论数量
|
||
*/
|
||
const trackCommentsViewed = useCallback((commentCount = 0) => {
|
||
track('Event Comments Viewed', {
|
||
comment_count: commentCount,
|
||
is_empty: commentCount === 0,
|
||
timestamp: new Date().toISOString(),
|
||
});
|
||
|
||
logger.debug('useDashboardEvents', '💬 Comments Viewed', {
|
||
commentCount,
|
||
});
|
||
}, [track]);
|
||
|
||
/**
|
||
* 追踪订阅信息查看
|
||
* @param {Object} subscription - 订阅信息
|
||
* @param {string} subscription.plan - 订阅计划 ('free' | 'pro' | 'enterprise')
|
||
* @param {string} subscription.status - 订阅状态 ('active' | 'expired' | 'cancelled')
|
||
*/
|
||
const trackSubscriptionViewed = useCallback((subscription = {}) => {
|
||
track(RETENTION_EVENTS.SUBSCRIPTION_PAGE_VIEWED, {
|
||
subscription_plan: subscription.plan || 'free',
|
||
subscription_status: subscription.status || 'unknown',
|
||
is_paid_user: subscription.plan !== 'free',
|
||
timestamp: new Date().toISOString(),
|
||
});
|
||
|
||
logger.debug('useDashboardEvents', '💳 Subscription Viewed', {
|
||
plan: subscription.plan,
|
||
status: subscription.status,
|
||
});
|
||
}, [track]);
|
||
|
||
/**
|
||
* 追踪升级按钮点击
|
||
* @param {string} currentPlan - 当前计划
|
||
* @param {string} targetPlan - 目标计划
|
||
* @param {string} source - 来源位置
|
||
*/
|
||
const trackUpgradePlanClicked = useCallback((currentPlan = 'free', targetPlan = 'pro', source = 'dashboard') => {
|
||
track(RETENTION_EVENTS.UPGRADE_PLAN_CLICKED, {
|
||
current_plan: currentPlan,
|
||
target_plan: targetPlan,
|
||
source,
|
||
timestamp: new Date().toISOString(),
|
||
});
|
||
|
||
logger.debug('useDashboardEvents', '⬆️ Upgrade Plan Clicked', {
|
||
currentPlan,
|
||
targetPlan,
|
||
source,
|
||
});
|
||
}, [track]);
|
||
|
||
/**
|
||
* 追踪个人资料更新
|
||
* @param {Array<string>} updatedFields - 更新的字段列表
|
||
*/
|
||
const trackProfileUpdated = useCallback((updatedFields = []) => {
|
||
track(RETENTION_EVENTS.PROFILE_UPDATED, {
|
||
updated_fields: updatedFields,
|
||
field_count: updatedFields.length,
|
||
timestamp: new Date().toISOString(),
|
||
});
|
||
|
||
logger.debug('useDashboardEvents', '✏️ Profile Updated', {
|
||
updatedFields,
|
||
});
|
||
}, [track]);
|
||
|
||
/**
|
||
* 追踪设置更改
|
||
* @param {string} settingName - 设置名称
|
||
* @param {any} oldValue - 旧值
|
||
* @param {any} newValue - 新值
|
||
*/
|
||
const trackSettingChanged = useCallback((settingName, oldValue, newValue) => {
|
||
if (!settingName) {
|
||
logger.warn('useDashboardEvents', 'Setting name is required');
|
||
return;
|
||
}
|
||
|
||
track(RETENTION_EVENTS.SETTINGS_CHANGED, {
|
||
setting_name: settingName,
|
||
old_value: String(oldValue),
|
||
new_value: String(newValue),
|
||
timestamp: new Date().toISOString(),
|
||
});
|
||
|
||
logger.debug('useDashboardEvents', '⚙️ Setting Changed', {
|
||
settingName,
|
||
oldValue,
|
||
newValue,
|
||
});
|
||
}, [track]);
|
||
|
||
return {
|
||
// 功能卡片事件
|
||
trackFunctionCardClicked,
|
||
|
||
// 自选股相关事件
|
||
trackWatchlistViewed,
|
||
trackWatchlistStockClicked,
|
||
trackWatchlistStockAdded,
|
||
trackWatchlistStockRemoved,
|
||
|
||
// 关注事件相关
|
||
trackFollowingEventsViewed,
|
||
trackFollowingEventClicked,
|
||
|
||
// 评论相关
|
||
trackCommentsViewed,
|
||
|
||
// 订阅相关
|
||
trackSubscriptionViewed,
|
||
trackUpgradePlanClicked,
|
||
|
||
// 个人资料和设置
|
||
trackProfileUpdated,
|
||
trackSettingChanged,
|
||
};
|
||
};
|
||
|
||
export default useDashboardEvents;
|