Skip to content

Commit

Permalink
Version 3.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
hbiede committed Apr 1, 2021
1 parent 8f93642 commit 50a8fca
Show file tree
Hide file tree
Showing 12 changed files with 66 additions and 22 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "la-feedback-system",
"version": "3.0.1",
"version": "3.1.0",
"repository": "https://github.com/hbiede/LA-Feedback-System",
"readme": "./README.md",
"private": true,
Expand Down
17 changes: 9 additions & 8 deletions public/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,15 @@ function get_outstanding_feedback() {

function get_interactions() {
$conn = get_connection();
$ps = $conn->prepare('SELECT IFNULL(canvas_username, username) AS \'username\', CONCAT(name, IF(is_admin, \' (Admin)\', \'\')) AS \'name\', ' .
'cse_usernames.course, COUNT(i.interaction_key) AS count, COUNT(t.interaction_key) AS wCount, ' .
'COUNT(f.feedback_key) AS fCount, ' .
'AVG(rating) AS avg, AVG(sentiment) AS sentiment FROM cse_usernames ' .
'LEFT JOIN interactions i on cse_usernames.username_key = i.la_username_key ' .
'LEFT JOIN feedback f on i.interaction_key = f.interaction_key ' .
'LEFT JOIN (SELECT interaction_key FROM interactions WHERE interactions.time_of_interaction >= CURDATE() - INTERVAL 7 DAY) t on t.interaction_key = i.interaction_key ' .
'GROUP BY username ORDER BY username;');
$ps = $conn->prepare("SELECT IFNULL(canvas_username, username) AS 'username', CONCAT(name, IF(is_admin, ' (Admin)', '')) AS 'name', " .
"cse_usernames.course, COUNT(i.interaction_key) AS count, COUNT(t.interaction_key) AS wCount, " .
"COUNT(f.feedback_key) AS fCount, " .
"AVG(rating) AS avg, AVG(sentiment) AS sentiment " .
"FROM cse_usernames " .
"LEFT JOIN interactions i on cse_usernames.username_key = i.la_username_key " .
"LEFT JOIN feedback f on i.interaction_key = f.interaction_key " .
"LEFT JOIN (SELECT interaction_key FROM interactions WHERE interactions.time_of_interaction >= CURDATE() - INTERVAL 7 DAY) t on t.interaction_key = i.interaction_key " .
"GROUP BY canvas_username HAVING COUNT(i.interaction_key) > 0 ORDER BY canvas_username;");
$returnVal = [];
if ($ps) {
$ps->execute();
Expand Down
2 changes: 2 additions & 0 deletions public/data/tableSetup.sql
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ CREATE TABLE interactions
student_username_key int not null,
course varchar(10),
interaction_type varchar(30) null,
was_recommended tinyint(1) default 0 not null,
seeking_feedback tinyint(1) default 0 not null,
has_received_feedback tinyint(1) default 0 null,
time_of_interaction timestamp default current_timestamp() not null,
Expand Down Expand Up @@ -92,6 +93,7 @@ SELECT time_of_interaction,
IFNULL(cus.name, cus.username) AS 'student',
i.course,
interaction_type,
IF(was_recommended, 'Recommended', 'Not Recommended') AS 'recommendation_status',
seeking_feedback,
has_received_feedback
FROM interactions i
Expand Down
3 changes: 2 additions & 1 deletion public/interactionDownload.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ function send_interactions_csv() {
"i.course, " .
"interaction_type, " .
"seeking_feedback, " .
"has_received_feedback " .
"has_received_feedback, " .
"IF(was_recommended, 'Recommended', 'Not Recommended') AS 'recommendation_status' " .
"FROM interactions i " .
"LEFT JOIN cse_usernames cul on i.la_username_key = cul.username_key " .
"LEFT JOIN cse_usernames cus on i.student_username_key = cus.username_key " .
Expand Down
5 changes: 3 additions & 2 deletions public/sendEmail.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
// studentID: string,
// laCSE: string,
// course: string,
// interactionType: string | null
// interactionType: string | null,
// recommended?: boolean,
//}

// Returns a JSON encoded message as follows:
Expand Down Expand Up @@ -67,7 +68,7 @@ function send_email($obj, $interaction_id) {

$obj = json_decode(file_get_contents('php://input'));
if (isset($obj) && isset($obj->{'laCSE'}) && isset($obj->{'studentID'}) && isset($obj->{'course'})) {
$interaction_id = add_interaction($obj->{'laCSE'}, $obj->{'studentID'}, $obj->{'course'}, $obj->{'interactionType'});
$interaction_id = add_interaction($obj->{'laCSE'}, $obj->{'studentID'}, $obj->{'course'}, $obj->{'interactionType'}, isset($obj->{'recommended'}) && ($obj->{'recommended'} === true || $obj->{'recommended'} === 'true'));

if ($interaction_id !== null && $interaction_id > 0 &&
(has_been_a_week($obj->{'laCSE'}) || mt_rand() / mt_getrandmax() < FEEDBACK_RATE) &&
Expand Down
7 changes: 4 additions & 3 deletions public/sqlManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,16 +172,17 @@ function add_cse($username, $name = null, $email = null) {
return null;
}

function add_interaction($la_cse, $student_id, $course, $interaction_type) {
function add_interaction($la_cse, $student_id, $course, $interaction_type, $recommended = false) {
$la_id = get_username_id($la_cse);
if ($la_id === $student_id) return null;
$conn = get_connection();
if ($conn !== null && is_int($la_id) && is_int($student_id) && $la_id >= 0) {
$conn->begin_transaction();
$ps = $conn->prepare("INSERT INTO interactions (la_username_key, student_username_key, course, " .
"interaction_type) VALUE (?, ?, ?, ?);");
"interaction_type, was_recommended) VALUE (?, ?, ?, ?, ?);");
if ($ps) {
$ps->bind_param("siss", $la_id, $student_id, $course, $interaction_type);
$recommended_int = $recommended ? 1 : 0;
$ps->bind_param("sissi", $la_id, $student_id, $course, $interaction_type, $recommended_int);
$ps->execute();
if ($ps->error) {
error_log($ps->error);
Expand Down
1 change: 1 addition & 0 deletions src/CHANGELOG.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"changes": [
"## 3.1.0\n- Allow LAs to submit a student as a potential LA for the PC to reach out to in the future\n- Fix error of students being attributed interactions in the admin table",
"## 3.0.1\n- Prevent removing the super user as an admin\n- Allow sorting by course on Admin's Students tab",
"## 3.0.0\n- Convert to UNL's authentication system",
"## 2.2.1\n- Fix error with removing admins",
Expand Down
2 changes: 1 addition & 1 deletion src/components/AdminComponents/LASummaryTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ const LASummaryTable = ({ showLA }: Props) => {
href={`${ServiceInterface.getPath()}/interactionDownload.php`}
type="button"
variant="primary"
style={{ marginBottom: 20 }}
style={{ marginBottom: 20, marginLeft: 10 }}
>
Download Interactions as CSV
</Button>
Expand Down
11 changes: 9 additions & 2 deletions src/redux/actions/LogInteraction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ import ServiceInterface from 'statics/ServiceInterface';
* @param course The course for which the student had an interaction
* @param multiples If the LA logged multiple students at once
* @param interactionType The type of interaction (i.e., 'office hour', 'lab')
* @param recommended If the student was recommended by the LA
*/
const LogInteraction = (
studentID: number,
course: string | null = null,
multiples = false,
interactionType: string | null = null
interactionType: string | null = null,
recommended = false
) => {
const { setResponse, username } = api.getState();
if (studentID === null) {
Expand All @@ -37,7 +39,12 @@ const LogInteraction = (
return;
}

ServiceInterface.logInteraction(studentID, course, interactionType)
ServiceInterface.logInteraction(
studentID,
course,
interactionType,
recommended
)
.then((response) => {
if (response === '0' || response === 0) {
setResponse({
Expand Down
4 changes: 3 additions & 1 deletion src/redux/modules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,14 @@ export type AppReduxState = {
* @param course The course for which the student had an interaction
* @param multiples If the LA logged multiple students at onces
* @param interactionType The type of interaction (i.e., 'office hour', 'lab')
* @param recommended If the student was recommended by the LA
*/
logInteraction: (
studentID: number,
course?: string | null,
multiples?: boolean,
interactionType?: string | null
interactionType?: string | null,
recommended?: boolean
) => void;
/**
* Logs the current user out
Expand Down
29 changes: 27 additions & 2 deletions src/screens/FeedbackForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@ const LA_USERNAME_ID = 'la_username';
const COURSE_ID = 'course';
const STUDENT_ID = 'student_login';
const INTERACTION_TYPE_ID = 'interaction_type';
const RECOMMENDED_ID = 'recommended_checkbox';

const LA_LABEL = 'LA Canvas Username';
const COURSE_LABEL = 'Course';
const STUDENT_LABEL = 'Student';
const INTERACTION_TYPE_LABEL = 'Interaction Type';
const RECOMMENDED_LABEL =
'Would you recommend this student as a potential LA? (The PC will reach out to them)';

type Props = {
style?: CSSProperties;
Expand Down Expand Up @@ -92,6 +95,7 @@ const FeedbackForm = ({ style }: Props) => {
const [interactionTypeRecord, setInteractionTypeRecord] = useState<
string | null
>(course);
const [recommended, setRecommended] = useState(false);

useEffect(() => {
api.subscribe(
Expand Down Expand Up @@ -121,6 +125,11 @@ const FeedbackForm = ({ style }: Props) => {
case INTERACTION_TYPE_ID:
setInteractionTypeRecord(value);
break;
case RECOMMENDED_ID:
setRecommended(
(event as ChangeEvent<HTMLInputElement>).currentTarget.checked
);
break;
default:
setResponse({ content: `${id} is an invalid ID`, class: 'danger' });
break;
Expand Down Expand Up @@ -159,7 +168,8 @@ const FeedbackForm = ({ style }: Props) => {
student.id,
student.course,
students.length > 1,
interactionTypeRecord
interactionTypeRecord,
recommended
);
});
setStudents([]);
Expand All @@ -182,6 +192,7 @@ const FeedbackForm = ({ style }: Props) => {

// Prevent reload
event.preventDefault();
setRecommended(false);
return false;
},
[
Expand All @@ -191,9 +202,10 @@ const FeedbackForm = ({ style }: Props) => {
interactionTypeRecord,
usernameRecord,
isAdmin,
incrementSessionInteractions,
setSelectedUsername,
incrementSessionInteractions,
logInteraction,
recommended,
]
);

Expand Down Expand Up @@ -329,6 +341,19 @@ const FeedbackForm = ({ style }: Props) => {
</div>
</FormGroup>

<FormGroup as={Row} controlId={RECOMMENDED_ID}>
<div className="col-sm-9">
<Form.Check
type="checkbox"
label={RECOMMENDED_LABEL}
checked={recommended}
aria-label={RECOMMENDED_LABEL}
aria-checked={recommended}
onChange={handleChange}
/>
</div>
</FormGroup>

<FormGroup>
<div className="col-sm-9">
<Button
Expand Down
5 changes: 4 additions & 1 deletion src/statics/ServiceInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ class ServiceInterface {
* @param studentID The database ID of the student being logged
* @param course The course for which the student had an interaction
* @param interactionType The type of interaction (i.e., 'office hour', 'lab')
* @param recommended If the student was recommended by the LA
*/
static logInteraction = async (
studentID: number,
course: string | null = null,
interactionType: string | null = null
interactionType: string | null = null,
recommended = false
): Promise<string | number | null> => {
const { course: defaultCourse, setResponse } = api.getState();
const laCSE = ServiceInterface.getActiveUser();
Expand All @@ -39,6 +41,7 @@ class ServiceInterface {
? defaultCourse
: course,
interactionType,
recommended,
}),
};
let status = null;
Expand Down

0 comments on commit 50a8fca

Please sign in to comment.