Separa heatmap mobile/desktop, opt-out analytics per operatori, dashboard costi con KPI e trend mensili. Co-authored-by: Cursor <cursoragent@cursor.com>
100 lines
4.0 KiB
ERB
100 lines
4.0 KiB
ERB
<% 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>
|
|
|
|
<section class="panel admin-analytics-preview">
|
|
<h3><%= t("admin.analytics.preview.title") %></h3>
|
|
<p class="muted admin-table-sub"><%= t("admin.analytics.preview.lead") %></p>
|
|
<% if @analytics_preview_active %>
|
|
<p class="admin-analytics-preview__status"><%= t("admin.analytics.preview.active") %></p>
|
|
<div class="admin-filter-actions">
|
|
<%= button_to t("admin.analytics.preview.disable"),
|
|
admin_analytics_preview_path,
|
|
method: :delete,
|
|
class: "admin-btn admin-btn--outline admin-btn--sm" %>
|
|
<%= link_to t("admin.analytics.preview.open_site"),
|
|
root_path,
|
|
class: "admin-btn admin-btn--primary admin-btn--sm",
|
|
target: "_blank",
|
|
rel: "noopener" %>
|
|
</div>
|
|
<% else %>
|
|
<div class="admin-filter-actions">
|
|
<%= button_to t("admin.analytics.preview.enable"),
|
|
admin_analytics_preview_path(return_to: root_path),
|
|
method: :post,
|
|
class: "admin-btn admin-btn--primary admin-btn--sm" %>
|
|
</div>
|
|
<% end %>
|
|
</section>
|
|
|
|
<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.moves") %></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[:moves] %></td>
|
|
<td><%= row[:clicks] %></td>
|
|
<td class="muted"><%= avg %>%</td>
|
|
<td class="muted"><%= row[:max_scroll] %>%</td>
|
|
<td>
|
|
<% heatmap_params = { page_path: row[:page_path], from: @filters[:from], to: @filters[:to] } %>
|
|
<% heatmap_params[:device] = @filters[:device] if @filters[:device].present? %>
|
|
<%= link_to t("admin.analytics.index.heatmap"), admin_analytics_page_path(heatmap_params) %>
|
|
</td>
|
|
</tr>
|
|
<% end %>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<% else %>
|
|
<p class="empty"><%= t("admin.analytics.index.none") %></p>
|
|
<% end %>
|
|
</div>
|