Aggiunge heatmaps first-party (click/scroll) con pagina admin Analytics.
Raccoglie eventi aggregati dietro consenso cookie, senza PII né tracking su admin/regia/live/replay; GA4 resta invariato. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
<% content_for :body_class, "admin-body" %>
|
||||
|
||||
<div class="admin-page-head">
|
||||
<h2 class="admin-page-title"><%= t("admin.analytics.index.title") %></h2>
|
||||
<p class="muted admin-page-sub"><%= t("admin.analytics.index.lead") %></p>
|
||||
</div>
|
||||
|
||||
<div class="panel admin-sessions-filters">
|
||||
<%= form_with url: admin_analytics_path, method: :get, local: true, class: "admin-filter-form" do %>
|
||||
<div class="admin-filter-grid">
|
||||
<label class="admin-filter-field">
|
||||
<span><%= t("admin.analytics.filters.from") %></span>
|
||||
<%= date_field_tag :from, @filters[:from] %>
|
||||
</label>
|
||||
<label class="admin-filter-field">
|
||||
<span><%= t("admin.analytics.filters.to") %></span>
|
||||
<%= date_field_tag :to, @filters[:to] %>
|
||||
</label>
|
||||
<label class="admin-filter-field">
|
||||
<span><%= t("admin.analytics.filters.device") %></span>
|
||||
<%= select_tag :device,
|
||||
options_for_select(
|
||||
[[t("admin.analytics.filters.any"), ""]] + AnalyticsEvent::DEVICES.map { |d| [d, d] },
|
||||
@filters[:device]
|
||||
) %>
|
||||
</label>
|
||||
</div>
|
||||
<div class="admin-filter-actions">
|
||||
<%= submit_tag t("admin.analytics.filters.apply"), class: "admin-btn admin-btn--primary admin-btn--sm" %>
|
||||
<%= link_to t("admin.analytics.filters.reset"), admin_analytics_path, class: "admin-btn admin-btn--outline admin-btn--sm" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<% if @pages.any? %>
|
||||
<div class="admin-table-wrap">
|
||||
<table class="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%= t("admin.analytics.index.table.path") %></th>
|
||||
<th><%= t("admin.analytics.index.table.pageviews") %></th>
|
||||
<th><%= t("admin.analytics.index.table.clicks") %></th>
|
||||
<th><%= t("admin.analytics.index.table.avg_scroll") %></th>
|
||||
<th><%= t("admin.analytics.index.table.max_scroll") %></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @pages.each do |row| %>
|
||||
<% avg = row[:scroll_samples].positive? ? (row[:scroll_sum].to_f / row[:scroll_samples]).round : 0 %>
|
||||
<tr>
|
||||
<td><code class="admin-mono"><%= row[:page_path] %></code></td>
|
||||
<td><%= row[:pageviews] %></td>
|
||||
<td><%= row[:clicks] %></td>
|
||||
<td class="muted"><%= avg %>%</td>
|
||||
<td class="muted"><%= row[:max_scroll] %>%</td>
|
||||
<td>
|
||||
<%= link_to t("admin.analytics.index.heatmap"),
|
||||
admin_analytics_page_path(page_path: row[:page_path], from: @filters[:from], to: @filters[:to], device: @filters[:device]) %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<% else %>
|
||||
<p class="empty"><%= t("admin.analytics.index.none") %></p>
|
||||
<% end %>
|
||||
</div>
|
||||
Reference in New Issue
Block a user