Skip to content

Commit 42d7dfb

Browse files
committed
stats for assistants
1 parent 028e671 commit 42d7dfb

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

app/controllers/assistants_controller.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ class AssistantsController < BaseAssistantsController
55
def show
66
@chat = Chat.new
77
@chat.assistant = Assistant.find(params[:id])
8+
9+
# Prepare data for chats per day chart (last 30 days)
10+
@chats_per_day = prepare_chats_per_day_data(@assistant)
811
end
912

1013
# GET /assistants/new
@@ -31,4 +34,26 @@ def clone
3134
def users
3235
redirect_to assistant_assistant_users_path(@assistant)
3336
end
37+
38+
private
39+
40+
def prepare_chats_per_day_data(assistant)
41+
# Get last 30 days
42+
end_date = Date.today
43+
start_date = end_date - 60.days
44+
45+
# Get chats grouped by day
46+
chats_by_day = assistant.chats
47+
.where(created_at: start_date.beginning_of_day..end_date.end_of_day)
48+
.group('DATE(created_at)')
49+
.count
50+
51+
# Fill in missing days with 0
52+
(start_date..end_date).map do |date|
53+
{
54+
date: date.strftime('%Y-%m-%d'),
55+
count: chats_by_day[date] || 0
56+
}
57+
end
58+
end
3459
end

app/views/assistants/show.html.erb

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@
2828
<%= render "chats/form", chat: @chat, assistant: @chat.assistant %>
2929
</div>
3030
</div>
31+
32+
<!-- Chart Section -->
33+
<div class="mt-8 bg-white rounded-lg shadow-sm border border-stone-200 p-6">
34+
<h2 class="text-stone-700 font-light text-2xl mb-4">Chat Activity - Last 30 Days</h2>
35+
<div class="w-full" style="height: 300px;">
36+
<canvas id="chatsPerDayChart"></canvas>
37+
</div>
38+
</div>
39+
3140
<div>
3241
<h1 class="text-stone-700 font-light text-3xl mt-6">Recent Chats</h1>
3342
<%= render "shared/chat_list", chats: @assistant.chats.limit(10).order(created_at: :desc) %>
@@ -46,6 +55,7 @@
4655
</div>
4756
</div>
4857
</div>
58+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js"></script>
4959
<script>
5060
document.querySelector('a[href="#"]').addEventListener("click", function(e) {
5161
e.preventDefault();
@@ -54,4 +64,96 @@
5464
document.getElementById("close-modal").addEventListener("click", function() {
5565
document.getElementById("details-modal").classList.add("hidden");
5666
});
67+
68+
// Initialize Chart.js
69+
function initializeChart() {
70+
const ctx = document.getElementById('chatsPerDayChart');
71+
if (!ctx) return;
72+
73+
// Destroy existing chart if it exists to prevent duplicates
74+
if (window.chatsChart) {
75+
window.chatsChart.destroy();
76+
}
77+
78+
const chartData = <%= raw @chats_per_day.to_json %>;
79+
const labels = chartData.map(d => {
80+
const date = new Date(d.date);
81+
return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
82+
});
83+
const data = chartData.map(d => d.count);
84+
85+
window.chatsChart = new Chart(ctx, {
86+
type: 'line',
87+
data: {
88+
labels: labels,
89+
datasets: [{
90+
label: 'Chats per Day',
91+
data: data,
92+
borderColor: '#0ea5e9',
93+
backgroundColor: 'rgba(14, 165, 233, 0.1)',
94+
tension: 0.3,
95+
fill: true,
96+
pointRadius: 3,
97+
pointHoverRadius: 5,
98+
pointBackgroundColor: '#0ea5e9',
99+
pointBorderColor: '#fff',
100+
pointBorderWidth: 2
101+
}]
102+
},
103+
options: {
104+
responsive: true,
105+
maintainAspectRatio: false,
106+
plugins: {
107+
legend: {
108+
display: false
109+
},
110+
tooltip: {
111+
backgroundColor: 'rgba(0, 0, 0, 0.8)',
112+
padding: 12,
113+
titleFont: {
114+
size: 13
115+
},
116+
bodyFont: {
117+
size: 13
118+
},
119+
callbacks: {
120+
label: function(context) {
121+
return 'Chats: ' + context.parsed.y;
122+
}
123+
}
124+
}
125+
},
126+
scales: {
127+
y: {
128+
beginAtZero: true,
129+
ticks: {
130+
stepSize: 1,
131+
font: {
132+
size: 11
133+
}
134+
},
135+
grid: {
136+
color: 'rgba(0, 0, 0, 0.05)'
137+
}
138+
},
139+
x: {
140+
ticks: {
141+
maxRotation: 45,
142+
minRotation: 45,
143+
font: {
144+
size: 10
145+
}
146+
},
147+
grid: {
148+
display: false
149+
}
150+
}
151+
}
152+
}
153+
});
154+
}
155+
156+
// Listen for both DOMContentLoaded and Turbo events
157+
document.addEventListener('DOMContentLoaded', initializeChart);
158+
document.addEventListener('turbo:load', initializeChart);
57159
</script>

0 commit comments

Comments
 (0)