import React, { Component } from 'react'; import { ArrowDropDownRounded as ArrowDropDownRoundedIcon, GroupRounded as GroupRoundedIcon, HomeRounded as HomeRoundedIcon } from "@material-ui/icons"; import { withRouter } from 'react-router-dom'; import Select from "react-select"; import NavBar from "./NavBar"; import Footer from "./Footer"; import Error404 from "./Error404"; import "./css/History.css"; import "./css/MistakesHistory.css"; import Collapsible from "react-collapsible"; import Checkbox from '@material-ui/core/Checkbox'; export default withRouter(class GroupStats extends Component { constructor(props) { super(props); this.state = { user: props.user, db: props.db, navbarItems: [ { type: "link", link: `/groups/${this.props.match.params.groupId}`, icon: , hideTextMobile: true, }, { type: "link", link: "/", icon: , hideTextMobile: true, } ], role: null, groupName: "", sets: {}, selectedSet: { value: "all_sets", label: "All sets", }, includeCompoundTests: true, incorrectAnswers: [], filteredIncorrectAnswers: [], setsWithHistory: {}, }; let isMounted = true; Object.defineProperty(this, "isMounted", { get: () => isMounted, set: (value) => isMounted = value, }); } setState = (state, callback = null) => { if (this.isMounted) super.setState(state, callback); } async componentDidMount() { let newState = { sets: {}, setsWithHistory: {}, }; await this.state.db .collection("users") .doc(this.state.user.uid) .collection("groups") .doc(this.props.match.params.groupId) .get() .then((userGroupDoc) => { newState.role = userGroupDoc.data().role; }) .catch((error) => { console.log(`Can't access user group: ${error}`); newState.role = "none"; }); if (newState.role === "owner") { await this.state.db .collection("groups") .doc(this.props.match.params.groupId) .get() .then(async (groupDoc) => { document.title = `Stats | ${groupDoc.data().display_name} | Parandum`; newState.groupName = groupDoc.data().display_name; return Promise.all(groupDoc.data().sets.map((setId) => { return this.state.db.collection("sets") .doc(setId) .get() .then((doc) => { newState.sets[setId] = { title: doc.data().title, }; }); })); }).catch((error) => { console.log(`Can't access group: ${error}`); newState.groupName = ""; document.title = "Stats | Parandum"; }); const groupSetIds = Object.keys(newState.sets); if (groupSetIds.length > 0) await this.state.db.collection("incorrect_answers") .where("groups", "array-contains", this.props.match.params.groupId) .orderBy("term", "asc") .orderBy("definition", "asc") .get() .then((querySnapshot) => { let incorrectAnswers = []; const docs = querySnapshot.docs .filter((doc) => doc.data().setIds.some(item => groupSetIds.includes(item))); docs .map((doc, index, array) => { if (index === 0 || doc.data().term !== array[index - 1].data().term || doc.data().definition !== array[index - 1].data().definition) { incorrectAnswers.push({ term: doc.data().term, definition: doc.data().definition, answers: [{ answer: doc.data().answer, switchLanguage: doc.data().switch_language, setIds: doc.data().setIds, }], count: doc.data().switch_language ? 0 : 1, switchedCount: doc.data().switch_language ? 1 : 0, setIds: doc.data().setIds, }); } else { incorrectAnswers[incorrectAnswers.length - 1].answers.push({ answer: doc.data().answer, switchLanguage: doc.data().switch_language, setIds: doc.data().setIds, }); doc.data().setIds.map((setId) => { if (!incorrectAnswers[incorrectAnswers.length - 1].setIds.includes(setId)) return incorrectAnswers[incorrectAnswers.length - 1].setIds.push(setId); return true; }); if (doc.data().switch_language) { incorrectAnswers[incorrectAnswers.length - 1].switchedCount++; } else { incorrectAnswers[incorrectAnswers.length - 1].count++; } } doc.data().setIds.map((setId) => newState.setsWithHistory[setId] = true); return true; }); newState.incorrectAnswers = incorrectAnswers.sort((a, b) => b.count + b.switchedCount - a.count - a.switchedCount); newState.filteredIncorrectAnswers = newState.incorrectAnswers; newState.totalIncorrect = docs.length; }) .catch((error) => { newState.incorrectAnswers = []; newState.totalIncorrect = 0; console.log(`Couldn't get group progress: ${error}`); }); } this.setState(newState); this.props.page.load(); this.props.logEvent("select_content", { content_type: "group_stats", item_id: this.props.match.params.groupId, }); } componentWillUnmount() { this.isMounted = false; this.props.page.unload(); } arraysHaveSameMembers = (arr1, arr2) => { const set1 = new Set(arr1); const set2 = new Set(arr2); return arr1.every(item => set2.has(item)) && arr2.every(item => set1.has(item)); } handleSetSelectionChange = (selectedSet = this.state.selectedSet) => { let totalIncorrect = 0; const filteredIncorrectAnswers = (selectedSet.value === "all_sets" ? JSON.parse(JSON.stringify(this.state.incorrectAnswers)) : JSON.parse(JSON.stringify(this.state.incorrectAnswers)) .filter((vocabItem) => vocabItem.setIds.includes(selectedSet.value) ) ) .map((vocabItem) => { let newVocabItem = vocabItem; if (selectedSet.value === "all_sets") { if (this.state.includeCompoundTests) { newVocabItem.answers = vocabItem.answers; } else { newVocabItem.answers = vocabItem.answers .filter((answer) => answer.setIds.length === 1 ) } } else { newVocabItem.answers = vocabItem.answers .filter((answer) => this.arraysHaveSameMembers(answer.setIds, [selectedSet.value]) || ( this.state.includeCompoundTests && answer.setIds.includes(selectedSet.value) ) ) } newVocabItem.switchedCount = newVocabItem.answers.filter((answer) => answer.switchLanguage === true).length; newVocabItem.count = newVocabItem.answers.length - newVocabItem.switchedCount; totalIncorrect += newVocabItem.answers.length; return newVocabItem; }); this.setState({ filteredIncorrectAnswers: filteredIncorrectAnswers, selectedSet: selectedSet, totalIncorrect: totalIncorrect, }); } handleIncludeCompoundTestsChange = (event) => { this.setState({ includeCompoundTests: event.target.checked, }, () => this.handleSetSelectionChange()); } render() { return ( this.state.role !== null ? (this.state.role === "owner" ?

Group Stats: {this.state.groupName}