feat(analytics): implement learning analytics feature with data collection and display
All checks were successful
Build & Push Docker Image / build (push) Successful in 6m33s
All checks were successful
Build & Push Docker Image / build (push) Successful in 6m33s
This commit is contained in:
@@ -4,13 +4,14 @@ import {
|
||||
ArrowLeft, Play, Square, Users, Settings, FileVideo, Radio,
|
||||
Loader2, Copy, ExternalLink, Lock, Mic, MicOff, UserCheck,
|
||||
Shield, Save, UserPlus, X, Share2, Globe, Send,
|
||||
FileText, Upload, Trash2, Link,
|
||||
FileText, Upload, Trash2, Link, BarChart3,
|
||||
} from 'lucide-react';
|
||||
import Modal from '../components/Modal';
|
||||
import api from '../services/api';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import { useLanguage } from '../contexts/LanguageContext';
|
||||
import RecordingList from '../components/RecordingList';
|
||||
import AnalyticsList from '../components/AnalyticsList';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
export default function RoomDetail() {
|
||||
@@ -22,6 +23,7 @@ export default function RoomDetail() {
|
||||
const [room, setRoom] = useState(null);
|
||||
const [status, setStatus] = useState({ running: false, participantCount: 0, moderatorCount: 0 });
|
||||
const [recordings, setRecordings] = useState([]);
|
||||
const [analytics, setAnalytics] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [actionLoading, setActionLoading] = useState(null);
|
||||
const [activeTab, setActiveTab] = useState('overview');
|
||||
@@ -93,10 +95,20 @@ export default function RoomDetail() {
|
||||
}
|
||||
};
|
||||
|
||||
const fetchAnalytics = async () => {
|
||||
try {
|
||||
const res = await api.get(`/analytics/room/${uid}`);
|
||||
setAnalytics(res.data.analytics || []);
|
||||
} catch {
|
||||
// Ignore
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchRoom();
|
||||
fetchStatus();
|
||||
fetchRecordings();
|
||||
fetchAnalytics();
|
||||
const interval = setInterval(fetchStatus, 10000);
|
||||
return () => clearInterval(interval);
|
||||
}, [uid]);
|
||||
@@ -183,6 +195,7 @@ export default function RoomDetail() {
|
||||
record_meeting: !!editRoom.record_meeting,
|
||||
guest_access: !!editRoom.guest_access,
|
||||
moderator_code: editRoom.moderator_code,
|
||||
learning_analytics: !!editRoom.learning_analytics,
|
||||
});
|
||||
setRoom(res.data.room);
|
||||
setEditRoom(res.data.room);
|
||||
@@ -331,6 +344,7 @@ export default function RoomDetail() {
|
||||
const tabs = [
|
||||
{ id: 'overview', label: t('room.overview'), icon: Play },
|
||||
{ id: 'recordings', label: t('room.recordings'), icon: FileVideo, count: recordings.length },
|
||||
{ id: 'analytics', label: t('room.analytics'), icon: BarChart3, count: analytics.length },
|
||||
...(isOwner ? [{ id: 'settings', label: t('room.settings'), icon: Settings }] : []),
|
||||
];
|
||||
|
||||
@@ -528,6 +542,10 @@ export default function RoomDetail() {
|
||||
<RecordingList recordings={recordings} onRefresh={fetchRecordings} />
|
||||
)}
|
||||
|
||||
{activeTab === 'analytics' && (
|
||||
<AnalyticsList analytics={analytics} onRefresh={fetchAnalytics} />
|
||||
)}
|
||||
|
||||
{activeTab === 'settings' && isOwner && editRoom && (
|
||||
<form onSubmit={handleSaveSettings} className="card p-6 space-y-5 max-w-2xl">
|
||||
<div>
|
||||
@@ -621,6 +639,15 @@ export default function RoomDetail() {
|
||||
/>
|
||||
<span className="text-sm text-th-text">{t('room.allowRecording')}</span>
|
||||
</label>
|
||||
<label className="flex items-center gap-3 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={!!editRoom.learning_analytics}
|
||||
onChange={e => setEditRoom({ ...editRoom, learning_analytics: e.target.checked })}
|
||||
className="w-4 h-4 rounded border-th-border text-th-accent focus:ring-th-ring"
|
||||
/>
|
||||
<span className="text-sm text-th-text">{t('room.enableAnalytics')}</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* Guest access section */}
|
||||
|
||||
Reference in New Issue
Block a user