// 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} 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;