import { Router } from 'express'; import { authMiddleware } from '../auth/middleware'; import { pool } from '../db/pool'; const router = Router(); router.use(authMiddleware); // Get analytics overview router.get('/overview', async (req, res) => { try { const { days = 30 } = req.query; // Total clicks const clicksResult = await pool.query(` SELECT COUNT(*) as total_clicks FROM clicks WHERE clicked_at >= NOW() - INTERVAL '${parseInt(days as string)} days' `); // Unique products clicked const uniqueProductsResult = await pool.query(` SELECT COUNT(DISTINCT product_id) as unique_products FROM clicks WHERE clicked_at >= NOW() - INTERVAL '${parseInt(days as string)} days' `); // Clicks by day const clicksByDayResult = await pool.query(` SELECT DATE(clicked_at) as date, COUNT(*) as clicks FROM clicks WHERE clicked_at >= NOW() - INTERVAL '${parseInt(days as string)} days' GROUP BY DATE(clicked_at) ORDER BY date DESC `); // Top products const topProductsResult = await pool.query(` SELECT p.id, p.name_raw as name, p.price_rec as price, COUNT(c.id) as click_count FROM clicks c JOIN store_products p ON c.product_id = p.id WHERE c.clicked_at >= NOW() - INTERVAL '${parseInt(days as string)} days' GROUP BY p.id, p.name_raw, p.price_rec ORDER BY click_count DESC LIMIT 10 `); res.json({ overview: { total_clicks: parseInt(clicksResult.rows[0].total_clicks), unique_products: parseInt(uniqueProductsResult.rows[0].unique_products) }, clicks_by_day: clicksByDayResult.rows, top_products: topProductsResult.rows }); } catch (error) { console.error('Error fetching analytics:', error); res.status(500).json({ error: 'Failed to fetch analytics' }); } }); // Get product analytics router.get('/products/:id', async (req, res) => { try { const { id } = req.params; const { days = 30 } = req.query; // Total clicks for this product const totalResult = await pool.query(` SELECT COUNT(*) as total_clicks FROM clicks WHERE product_id = $1 AND clicked_at >= NOW() - INTERVAL '${parseInt(days as string)} days' `, [id]); // Clicks by day const byDayResult = await pool.query(` SELECT DATE(clicked_at) as date, COUNT(*) as clicks FROM clicks WHERE product_id = $1 AND clicked_at >= NOW() - INTERVAL '${parseInt(days as string)} days' GROUP BY DATE(clicked_at) ORDER BY date DESC `, [id]); res.json({ product_id: parseInt(id), total_clicks: parseInt(totalResult.rows[0].total_clicks), clicks_by_day: byDayResult.rows }); } catch (error) { console.error('Error fetching product analytics:', error); res.status(500).json({ error: 'Failed to fetch product analytics' }); } }); // Get campaign analytics router.get('/campaigns/:id', async (req, res) => { try { const { id } = req.params; const { days = 30 } = req.query; // Total clicks for this campaign const totalResult = await pool.query(` SELECT COUNT(*) as total_clicks FROM clicks WHERE campaign_id = $1 AND clicked_at >= NOW() - INTERVAL '${parseInt(days as string)} days' `, [id]); // Clicks by product in this campaign const byProductResult = await pool.query(` SELECT p.id, p.name_raw as name, COUNT(c.id) as clicks FROM clicks c JOIN store_products p ON c.product_id = p.id WHERE c.campaign_id = $1 AND c.clicked_at >= NOW() - INTERVAL '${parseInt(days as string)} days' GROUP BY p.id, p.name_raw ORDER BY clicks DESC `, [id]); res.json({ campaign_id: parseInt(id), total_clicks: parseInt(totalResult.rows[0].total_clicks), clicks_by_product: byProductResult.rows }); } catch (error) { console.error('Error fetching campaign analytics:', error); res.status(500).json({ error: 'Failed to fetch campaign analytics' }); } }); export default router;