package handler import ( "fmt" "net/http" "dealroom/templates" ) func (h *Handler) handleAnalytics(w http.ResponseWriter, r *http.Request) { profile := getProfile(r.Context()) dealID := r.URL.Query().Get("deal_id") deals := h.getDeals(profile) var dealCount, fileCount, requestCount, fulfilledCount int if dealID != "" { h.db.QueryRow("SELECT COUNT(*) FROM deals WHERE id = ? AND organization_id = ? AND is_archived = 0", dealID, profile.OrganizationID).Scan(&dealCount) h.db.QueryRow("SELECT COUNT(*) FROM files WHERE deal_id = ?", dealID).Scan(&fileCount) h.db.QueryRow("SELECT COUNT(*) FROM diligence_requests WHERE deal_id = ?", dealID).Scan(&requestCount) h.db.QueryRow("SELECT COUNT(*) FROM diligence_requests WHERE deal_id = ? AND atlas_status = 'fulfilled'", dealID).Scan(&fulfilledCount) } else { h.db.QueryRow("SELECT COUNT(*) FROM deals WHERE organization_id = ? AND is_archived = 0", profile.OrganizationID).Scan(&dealCount) h.db.QueryRow("SELECT COUNT(*) FROM files f JOIN deals d ON f.deal_id = d.id WHERE d.organization_id = ?", profile.OrganizationID).Scan(&fileCount) h.db.QueryRow("SELECT COUNT(*) FROM diligence_requests r JOIN deals d ON r.deal_id = d.id WHERE d.organization_id = ?", profile.OrganizationID).Scan(&requestCount) h.db.QueryRow("SELECT COUNT(*) FROM diligence_requests r JOIN deals d ON r.deal_id = d.id WHERE d.organization_id = ? AND r.atlas_status = 'fulfilled'", profile.OrganizationID).Scan(&fulfilledCount) } completionPct := 0 if requestCount > 0 { completionPct = (fulfilledCount * 100) / requestCount } stats := &templates.AnalyticsStats{ DealCount: dealCount, FileCount: fileCount, RequestCount: requestCount, CompletionPct: completionPct, } templates.AnalyticsPage(profile, stats, deals, dealID).Render(r.Context(), w) } func (h *Handler) handleAnalyticsBuyers(w http.ResponseWriter, r *http.Request) { dealID := r.URL.Query().Get("deal_id") if dealID == "" { w.Write([]byte(`

Select a deal to see buyer activity.

`)) return } rows, err := h.db.Query(` SELECT COALESCE(buyer_group, 'Unknown') as bg, COUNT(CASE WHEN activity_type = 'download' THEN 1 END) as downloads, MAX(created_at) as last_access, SUM(COALESCE(time_spent_seconds, 0)) as total_time, COUNT(CASE WHEN activity_type = 'view' THEN 1 END) as views FROM deal_activity WHERE deal_id = ? AND COALESCE(buyer_group, '') != '' GROUP BY COALESCE(buyer_group, 'Unknown') ORDER BY last_access DESC`, dealID) if err != nil { http.Error(w, "Error", 500) return } defer rows.Close() w.Header().Set("Content-Type", "text/html") html := `` hasRows := false for rows.Next() { hasRows = true var bg, lastAccess string var downloads, totalTime, views int rows.Scan(&bg, &downloads, &lastAccess, &totalTime, &views) timeStr := fmt.Sprintf("%dm", totalTime/60) if totalTime < 60 { timeStr = fmt.Sprintf("%ds", totalTime) } html += fmt.Sprintf(``, bg, downloads, lastAccess, timeStr, views) } if !hasRows { html += `` } html += `
Buyer Group Downloads Last Accessed Total Time Files Viewed
%s %d %s %s %d
No buyer activity recorded yet.
` w.Write([]byte(html)) }