import React from "react";
import PropTypes from "prop-types";
import MenuItem from "@material-ui/core/MenuItem";
import Grid from "@material-ui/core/Grid";
import Button from "@material-ui/core/Button/Button";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import TextField from "@material-ui/core/TextField";
import IconButton from "@material-ui/core/IconButton/IconButton";
import ClassroomClimateIconImage from "../../../assets/images/ClassroomClimateIconImage.svg";
import GenerateReportImage from "../../../assets/images/GenerateReportImage.svg";
import { withStyles } from "@material-ui/core/styles";
// import spreadsheetData from "../../../SPREADSHEET_SECRETS";
import FirebaseContext from "../../../components/Firebase/FirebaseContext";
import AppBar from "../../../components/AppBar";
import Typography from "@material-ui/core/Typography/Typography";
// import { ImmortalDB } from "immortal-db";
import moment from "moment";
import NotesListDetailTable from "../../../components/ResultsComponents/NotesListDetailTable.tsx";
import BehaviorCounterResults from "../../../components/ResultsComponents/BehaviorCounterResults.js";
import AverageToneRating from "../../../components/ResultsComponents/AverageToneRating.js";
import ClimateTrendsGraph from "../../../components/ResultsComponents/ClimateTrendsGraph.tsx";
const styles = {
root: {
flexGrow: 1,
height: "100vh",
flexDirection: "column"
},
main: {
flex: 1,
height: "90%",
marginTop: "10vh"
},
grow: {
flexGrow: 1
},
menuButton: {
marginLeft: -12,
marginRight: 20
},
viewButtons: {
minWidth: 150,
textAlign: "center"
},
buttonsList: {
position: "relative",
top: "3vh"
},
title: {
position: "relative",
left: "33%",
top: "10%"
},
secondTitle: {
position: "relative",
left: "40%",
top: "10%"
},
chart: {
position: "relative",
left: "7%",
top: "5%"
},
generateReport: {
position: "relative",
right: "10%",
top: "76%",
left: "10%"
},
resultsContent: {
height: "60vh",
position: "relative",
top: "8vh"
}
};
const ViewEnum = {
SUMMARY: 1,
DETAILS: 2,
TRENDS: 3,
NOTES: 4,
NEXT_STEPS: 5
};
/**
* classroom climate results
* @class ClassroomClimateResultsPage
*/
class ClassroomClimateResultsPage extends React.Component {
/**
* @param {Props} props
*/
constructor(props) {
super(props);
// this.handleAppend = this.handleAppend.bind(this);
// this.handleTypeChange = this.handleTypeChange.bind(this);
}
state = {
auth: true,
anchorEl: null,
help: false,
type: null,
hex: "#FFFFFF",
entries: [],
dbCounter: 0, // @Hack @Temporary !!!
view: ViewEnum.SUMMARY,
sessionDates: [],
disapprovalBehaviorCount: 0,
redirectionsBehaviorCount: 0,
nonspecificBehaviorCount: 0,
specificBehaviorCount: 0,
averageToneRating: 0,
percentage: false,
sessionId: null,
trendsDates: [],
trendsPos: [],
trendsNeg: [],
trendsPosCol: [],
trendsNegCol: [],
notes: []
};
/** lifecycle method invoked after component mounts */
componentDidMount() {
const teacherId = this.props.location.state.teacher.id;
console.log(this.props.location.state);
this.handleDateFetching(this.props.location.state.teacher.id);
console.log(teacherId);
console.log("handle behavior count results fetching called");
const firebase = this.context;
firebase.fetchBehaviourTypeCount(this.state.sessionId).then(() => {
console.log(
this.state.disapprovalBehaviorCount +
" " +
this.state.redirectionsBehaviorCount +
" " +
this.state.nonspecificBehaviorCount +
" " +
this.state.specificBehaviorCount
);
});
this.handleTrendsFetching(teacherId);
}
/**
* @param {Object} entry
*/
/* handleAppend(entry) {
const newEntries = this.state.entries;
// entry.type = this.state.type;
newEntries.push(entry);
this.setState({ entries: newEntries });
// this.handleSpreadsheetAppend(entry);
this.handleDBinsert(entry);
} */
// handleTypeChange(newType) {
// this.setState({ type: newType });
// this.changeHex(newType);
// }
/* handleChange = event => {
this.setState({ auth: event.target.checked });
};
handleMenu = event => {
this.setState({ anchorEl: event.currentTarget });
};
handleClose = () => {
this.setState({ anchorEl: null });
};
handleHelpModal = () => {
this.setState({ help: true });
};
handleClickAway = () => {
this.setState({ help: false });
};
handleDBinsert = async entry => {
await ImmortalDB.set(
JSON.stringify(this.state.dbCounter),
JSON.stringify(entry)
);
this.setState({ dbCounter: this.state.dbCounter + 1 });
};
*/
/* handleSpreadsheetAppend = entry => {
let url = new URL(spreadsheetData.scriptLink),
params = {
sheet: "ClassroomClimateTime",
del: "false",
TrnDur: entry.time
};
Object.keys(params).forEach(key =>
url.searchParams.append(key, params[key])
);
fetch(url, {
method: "POST",
credentials: "include",
mode: "no-cors",
headers: {
"content-type": "application/json"
}
})
.then(response => console.log("Success"))
.catch(error => console.error("Error:", error));
}; */
summaryClick = () => {
if (this.state.view !== ViewEnum.SUMMARY) {
this.setState({ view: ViewEnum.SUMMARY });
}
};
detailsClick = () => {
if (this.state.view !== ViewEnum.DETAILS) {
this.setState({ view: ViewEnum.DETAILS });
}
};
trendsClick = () => {
if (this.state.view !== ViewEnum.TRENDS) {
this.setState({ view: ViewEnum.TRENDS });
}
};
notesClick = () => {
if (this.state.view !== ViewEnum.NOTES) {
this.setState({ view: ViewEnum.NOTES });
}
};
nextStepsClick = () => {
if (this.state.view !== ViewEnum.NEXT_STEPS) {
this.setState({ view: ViewEnum.NEXT_STEPS });
}
};
/**
* @param {string} teacherId
*/
handleDateFetching = teacherId => {
console.log("handle date fetching called");
const firebase = this.context;
firebase.fetchSessionDates(teacherId, "climate").then(dates =>
this.setState({
sessionDates: dates
})
);
firebase.fetchAvgToneRating(this.state.sessionId);
firebase.fetchBehaviourTypeCount(this.state.sessionId);
firebase.fetchBehaviourTrend(teacherId);
};
/**
* @param {string} teacherId
*/
handleTrendsFetching = teacherId => {
const firebase = this.context;
const dateArray = [];
const posArray = [];
const negArray = [];
const posBkgColor = [];
const negBkgColor = [];
firebase.fetchBehaviourTrend(teacherId).then(dataSet => {
dataSet.map(data => {
dateArray.push(moment(data.dayOfEvent.value).format("MMM Do YYYY"));
posArray.push(data.positive);
negArray.push(data.negative);
posBkgColor.push("#009365");
negBkgColor.push("#E55529");
});
this.setState({
trendsDates: dateArray,
trendsPos: posArray,
trendsNeg: negArray,
trendsPosCol: posBkgColor,
trendsNegCol: negBkgColor
});
});
};
/**
* @param {string} sessionId
*/
handleNotesFetching = sessionId => {
const firebase = this.context;
firebase.handleFetchNotesResults(sessionId).then(notesArr => {
console.log(notesArr);
const formattedNotesArr = [];
notesArr.map(note => {
const newTimestamp = new Date(
note.timestamp.seconds * 1000
).toLocaleString("en-US", {
hour: "numeric",
minute: "numeric",
hour12: true
});
formattedNotesArr.push({
id: note.id,
content: note.content,
timestamp: newTimestamp
});
});
console.log(formattedNotesArr);
this.setState({
notes: formattedNotesArr
});
});
};
trendsFormatData = () => {
return {
labels: this.state.trendsDates,
datasets: [
{
label: "Disapproval",
data: this.state.trendsNeg,
backgroundColor: this.state.trendsNegCol
},
{
label: "Positive",
data: this.state.trendsPos,
backgroundColor: this.state.trendsPosCol
}
]
};
};
/**
* @param {event} event
*/
changeSessionId = event => {
console.log("sessionId", event.target.value);
let specificCount = 0;
let nonspecificCount = 0;
let disapprovalCount = 0;
let redirectionCount = 0;
this.setState(
{
sessionId: event.target.value
},
() => {
this.handleNotesFetching(this.state.sessionId);
const firebase = this.context;
firebase.fetchAvgToneRating(this.state.sessionId).then(json =>
json.map(toneRating => {
this.setState({
averageToneRating: toneRating.average
});
})
);
firebase
.fetchBehaviourTypeCount(this.state.sessionId)
.then(json => console.log("attempt behavior count: ", json));
// .gets json, then map to the state
firebase.fetchBehaviourTypeCount(this.state.sessionId).then(json => {
json.map(behavior => {
if (behavior.behaviorResponse === "specificapproval") {
specificCount = behavior.count;
} else if (behavior.behaviorResponse === "nonspecificapproval") {
nonspecificCount = behavior.count;
} else if (behavior.behaviorResponse === "disapproval") {
disapprovalCount = behavior.count;
} else if (behavior.behaviorResponse === "redirection") {
redirectionCount = behavior.count;
}
});
this.setState({
redirectionsBehaviorCount: redirectionCount,
disapprovalBehaviorCount: disapprovalCount,
nonspecificBehaviorCount: nonspecificCount,
specificBehaviorCount: specificCount
});
});
}
);
};
/**
* render function
* @return {ReactElement}
*/
render() {
const { classes } = this.props;
return (
<div className={classes.root}>
<FirebaseContext.Consumer>
{firebase => <AppBar firebase={firebase} />}
</FirebaseContext.Consumer>
<main>
<Grid
container
spacing={0}
justify="center"
direction={"row"}
alignItems={"center"}
>
<Grid container item xs={3}>
<List className={classes.buttonsList}>
<ListItem>
<img
src={ClassroomClimateIconImage}
style={{
width: "15vw",
height: "10vh",
position: "center"
}}
/>
</ListItem>
<ListItem>
<TextField
select
className={classes.viewButtons}
label="Date"
value={this.state.sessionId}
onChange={this.changeSessionId}
InputLabelProps={{ shrink: true }}
>
{this.state.sessionDates.map((date, index) => {
return (
<MenuItem key={index} id={date.id} value={date.id}>
<em>
{moment(date.sessionStart.value).format(
"MMM Do YY hh:mm A"
)}
</em>
</MenuItem>
);
})}
</TextField>
</ListItem>
<ListItem>
<Button
size="large"
color={"primary"}
variant={
this.state.view === ViewEnum.SUMMARY
? "contained"
: "outlined"
}
className={classes.viewButtons}
onClick={this.summaryClick}
>
Summary
</Button>
</ListItem>
<ListItem>
<Button
size="large"
color={"primary"}
variant={
this.state.view === ViewEnum.DETAILS
? "contained"
: "outlined"
}
className={classes.viewButtons}
onClick={this.detailsClick}
>
Details
</Button>
</ListItem>
<ListItem>
<Button
size="large"
color={"primary"}
variant={
this.state.view === ViewEnum.TRENDS
? "contained"
: "outlined"
}
className={classes.viewButtons}
onClick={this.trendsClick}
>
Trends
</Button>
</ListItem>
<ListItem>
<Button
size="large"
color={"primary"}
variant={
this.state.view === ViewEnum.NOTES
? "contained"
: "outlined"
}
className={classes.viewButtons}
onClick={this.notesClick}
>
Notes
</Button>
</ListItem>
<ListItem>
<Button
size="large"
color={"primary"}
variant={
this.state.view === ViewEnum.NEXT_STEPS
? "contained"
: "outlined"
}
className={classes.viewButtons}
onClick={this.nextStepsClick}
>
Next Steps
</Button>
</ListItem>
<ListItem>
<IconButton className={classes.generateReport}>
<img
src={GenerateReportImage}
style={{
height: "88px",
width: "88px"
}}
/>
</IconButton>
</ListItem>
</List>
</Grid>
<Grid
container
item
xs={8}
justify="center"
direction={"row"}
alignItems={"center"}
>
<Typography
variant={"h4"}
alignItems={"center"}
justify={"center"}
>
Classroom Climate Results
</Typography>
<Grid item xs={10}>
<div>
{this.state.view === ViewEnum.SUMMARY ? (
<div className={classes.resultsContent}>
{/* {(this.state.percentage = false)} */}
<Grid>
<FirebaseContext.Consumer>
{firebase => (
<AverageToneRating
averageToneRating={this.state.averageToneRating}
firebase={firebase}
/>
)}
</FirebaseContext.Consumer>
</Grid>
<Grid>
<FirebaseContext.Consumer>
{firebase => (
<BehaviorCounterResults
percentage={this.state.percentage}
disapprovalBehaviorCount={
this.state.disapprovalBehaviorCount
}
redirectionsBehaviorCount={
this.state.redirectionsBehaviorCount
}
nonspecificBehaviorCount={
this.state.nonspecificBehaviorCount
}
specificBehaviorCount={
this.state.specificBehaviorCount
}
firebase={firebase}
/>
)}
</FirebaseContext.Consumer>
</Grid>
</div>
) : this.state.view === ViewEnum.DETAILS ? (
<div className={classes.detailsGraph}>
{/* {(this.state.percentage = true)} */}
<Grid>
<FirebaseContext.Consumer>
{firebase => (
<BehaviorCounterResults
percentage={this.state.percentage}
disapprovalBehaviorCount={
this.state.disapprovalBehaviorCount
}
redirectionsBehaviorCount={
this.state.redirectionsBehaviorCount
}
nonspecificBehaviorCount={
this.state.nonspecificBehaviorCount
}
specificBehaviorCount={
this.state.specificBehaviorCount
}
firebase={firebase}
/>
)}
</FirebaseContext.Consumer>
</Grid>
</div>
) : this.state.view === ViewEnum.TRENDS ? (
<div className={classes.resultsContent}>
<ClimateTrendsGraph data={this.trendsFormatData} />
</div>
) : this.state.view === ViewEnum.NOTES ? (
<div className={classes.resultsContent}>
<NotesListDetailTable data={this.state.notes} />
</div>
) : this.state.view === ViewEnum.NEXT_STEPS ? (
<div className={classes.resultsContent} /> // replace this null with next steps content
) : null}
</div>
</Grid>
</Grid>
</Grid>
</main>
</div>
);
}
}
ClassroomClimateResultsPage.propTypes = {
classes: PropTypes.object.isRequired,
location: PropTypes.object.isRequired
};
ClassroomClimateResultsPage.contextType = FirebaseContext;
export default withStyles(styles)(ClassroomClimateResultsPage);