import React from 'react';
import './App.css';
import './bbb-icons.css';
import { FormattedMessage, FormattedDate, injectIntl } from 'react-intl';
import Card from './components/Card';
import UsersTable from './components/UsersTable';
import StatusTable from './components/StatusTable';
import PollsTable from './components/PollsTable';
import ErrorMessage from './components/ErrorMessage';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true,
activitiesJson: {},
tab: 'overview',
meetingId: '',
learningDashboardAccessToken: '',
};
}
componentDidMount() {
this.setDashboardParams();
setInterval(() => {
this.fetchActivitiesJson();
}, 10000);
}
setDashboardParams() {
let learningDashboardAccessToken = '';
let meetingId = '';
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
if (typeof params.meeting !== 'undefined') {
meetingId = params.meeting;
}
if (typeof params.report !== 'undefined') {
learningDashboardAccessToken = params.report;
} else {
const cookieName = `learningDashboardAccessToken-${params.meeting}`;
const cDecoded = decodeURIComponent(document.cookie);
const cArr = cDecoded.split('; ');
cArr.forEach((val) => {
if (val.indexOf(`${cookieName}=`) === 0) learningDashboardAccessToken = val.substring((`${cookieName}=`).length);
});
// Extend AccessToken lifetime by 30d (in each access)
if (learningDashboardAccessToken !== '') {
const cookieExpiresDate = new Date();
cookieExpiresDate.setTime(cookieExpiresDate.getTime() + (3600000 * 24 * 30));
document.cookie = `learningDashboardAccessToken-${meetingId}=${learningDashboardAccessToken}; expires=${cookieExpiresDate.toGMTString()}; path=/;SameSite=None;Secure`;
}
}
this.setState({ learningDashboardAccessToken, meetingId }, this.fetchActivitiesJson);
}
fetchActivitiesJson() {
const { learningDashboardAccessToken, meetingId } = this.state;
if (learningDashboardAccessToken !== '') {
fetch(`${meetingId}/${learningDashboardAccessToken}/learning_dashboard_data.json`)
.then((response) => response.json())
.then((json) => {
this.setState({ activitiesJson: json, loading: false });
document.title = `Learning Dashboard - ${json.name}`;
}).catch(() => {
this.setState({ loading: false });
});
} else {
this.setState({ loading: false });
}
}
render() {
const {
activitiesJson, tab, learningDashboardAccessToken, loading,
} = this.state;
const { intl } = this.props;
document.title = `${intl.formatMessage({ id: 'app.learningDashboard.dashboardTitle', defaultMessage: 'Learning Dashboard' })} - ${activitiesJson.name}`;
function totalOfRaiseHand() {
if (activitiesJson && activitiesJson.users) {
return Object.values(activitiesJson.users)
.reduce((prevVal, elem) => prevVal + elem.emojis.filter((emoji) => emoji.name === 'raiseHand').length, 0);
}
return 0;
}
function tsToHHmmss(ts) {
return (new Date(ts).toISOString().substr(11, 8));
}
function totalOfActivity() {
const minTime = Object.values(activitiesJson.users || {}).reduce((prevVal, elem) => {
if (prevVal === 0 || elem.registeredOn < prevVal) return elem.registeredOn;
return prevVal;
}, 0);
const maxTime = Object.values(activitiesJson.users || {}).reduce((prevVal, elem) => {
if (elem.leftOn === 0) return (new Date()).getTime();
if (elem.leftOn > prevVal) return elem.leftOn;
return prevVal;
}, 0);
return maxTime - minTime;
}
function getAverageActivityScore() {
let meetingAveragePoints = 0;
const allUsers = Object.values(activitiesJson.users || {})
.filter((currUser) => !currUser.isModerator);
const nrOfUsers = allUsers.length;
// Calculate points of Talking
const usersTalkTime = allUsers.map((currUser) => currUser.talk.totalTime);
const maxTalkTime = Math.max(...usersTalkTime);
const totalTalkTime = usersTalkTime.reduce((prev, val) => prev + val, 0);
if (totalTalkTime > 0) {
meetingAveragePoints += ((totalTalkTime / nrOfUsers) / maxTalkTime) * 2;
}
// Calculate points of Chatting
const usersTotalOfMessages = allUsers.map((currUser) => currUser.totalOfMessages);
const maxMessages = Math.max(...usersTotalOfMessages);
const totalMessages = usersTotalOfMessages.reduce((prev, val) => prev + val, 0);
if (maxMessages > 0) {
meetingAveragePoints += ((totalMessages / nrOfUsers) / maxMessages) * 2;
}
// Calculate points of Raise hand
const usersRaiseHand = allUsers.map((currUser) => currUser.emojis.filter((emoji) => emoji.name === 'raiseHand').length);
const maxRaiseHand = Math.max(...usersRaiseHand);
const totalRaiseHand = usersRaiseHand.reduce((prev, val) => prev + val, 0);
if (maxRaiseHand > 0) {
meetingAveragePoints += ((totalRaiseHand / nrOfUsers) / maxMessages) * 2;
}
// Calculate points of Emojis
const usersEmojis = allUsers.map((currUser) => currUser.emojis.filter((emoji) => emoji.name !== 'raiseHand').length);
const maxEmojis = Math.max(...usersEmojis);
const totalEmojis = usersEmojis.reduce((prev, val) => prev + val, 0);
if (maxEmojis > 0) {
meetingAveragePoints += ((totalEmojis / nrOfUsers) / maxEmojis) * 2;
}
// Calculate points of Polls
const totalOfPolls = Object.values(activitiesJson.polls || {}).length;
if (totalOfPolls > 0) {
const totalAnswers = allUsers
.reduce((prevVal, currUser) => prevVal + Object.values(currUser.answers || {}).length, 0);
meetingAveragePoints += ((totalAnswers / nrOfUsers) / totalOfPolls) * 2;
}
return meetingAveragePoints;
}
function getErrorMessage() {
if (learningDashboardAccessToken === '') {
return intl.formatMessage({ id: 'app.learningDashboard.errors.invalidToken', defaultMessage: 'Invalid session token' });
}
return intl.formatMessage({ id: 'app.learningDashboard.errors.dataUnavailable', defaultMessage: 'Data is no longer available' });
}
if (loading === false && typeof activitiesJson.name === 'undefined') return