Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Progress Notes Frontend & Backend #102

Merged
merged 23 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
52b9c3c
feat: add create program notes backend
aaronchan32 Apr 24, 2024
bf8e682
fix: THead unique key prop warning
aaronchan32 Apr 25, 2024
b282836
feat: add edited by field to notes
aaronchan32 May 6, 2024
f895805
fix: fix styling issues
aaronchan32 May 6, 2024
351c445
feat: add edit and delete functionality to progress notes and change …
aaronchan32 May 9, 2024
1d2d520
fix: fix calendar styling
aaronchan32 May 9, 2024
b3cf525
feat: add download progress notes functionality using react-pdf
aaronchan32 May 10, 2024
d6ed60f
feat: add mobile responsiveness
aaronchan32 May 10, 2024
d13740f
Merge branch 'main' of https://github.com/TritonSE/PIA-Program-Manage…
aaronchan32 May 10, 2024
230b01e
feat: create program context provider shared across Home, Programs, a…
aaronchan32 May 10, 2024
953d0c3
fix: fix styling to be consistent across pages
aaronchan32 May 11, 2024
b19253c
feat: add progress note filtering and add loading spinner to pages
aaronchan32 May 11, 2024
d05157e
feat: add account type authorization checks on frontend and backend
aaronchan32 May 11, 2024
a70c342
refactor: refactor notes logic and fix styling
aaronchan32 May 12, 2024
831fdf3
feat: add logic to check for no students and refactor filter
aaronchan32 May 13, 2024
a93c0f6
feat: add shadows using overflow clip
aaronchan32 May 13, 2024
a6d57f7
fix: fix styling for search filter
aaronchan32 May 13, 2024
aa876d4
fix: fix small style inconsistencies
aaronchan32 May 13, 2024
bbaae26
fix: update poppins font url to use https
aaronchan32 May 13, 2024
372b974
fix: fix modal close button styling to be more consistent
aaronchan32 May 14, 2024
1498994
fix: fix escape key overriding dialog close
aaronchan32 May 14, 2024
e078081
Squashed commit of the following:
aaronchan32 May 20, 2024
1c59338
Merge branch 'main' into feature/aaronchan32/progress-notes
adhi0331 May 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 161 additions & 0 deletions backend/src/controllers/progressNote.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import { NextFunction, Request, Response } from "express";
import { validationResult } from "express-validator";

import { ValidationError } from "../errors";
import ProgressNote from "../models/progressNote";
import StudentModel from "../models/student";
import UserModel from "../models/user";
import validationErrorParser from "../util/validationErrorParser";

import {
CreateProgressNoteRequestBody,
DeleteProgressNoteRequestBody,
EditProgressNoteRequestBody,
ExistingProgressNoteType,
ProgressNoteType,
} from "./types/progressNoteTypes";
import { LoginUserRequestBody } from "./types/userTypes";

export const createProgressNote = async (
req: Request<Record<string, never>, Record<string, never>, CreateProgressNoteRequestBody>,
res: Response,
next: NextFunction,
) => {
try {
const { uid, studentId } = req.body;

const user = await UserModel.findById(uid);
if (!user) {
throw ValidationError.USER_NOT_FOUND;
}

const student = await StudentModel.findById(studentId);
if (!student) {
throw ValidationError.STUDENT_NOT_FOUND;
}

const errors = validationResult(req);
validationErrorParser(errors);

const newProgressNote = {
...req.body,
lastEditedBy: user.name,
userId: uid,
} as ProgressNoteType;

const createdProgressNote = await ProgressNote.create(newProgressNote);

// Add the progress note to the student
await StudentModel.findOneAndUpdate(
{ _id: newProgressNote.studentId },
{ $push: { progressNotes: createdProgressNote._id } },
);

res.status(201).json(createdProgressNote);
} catch (error) {
next(error);
}
};

export const editProgressNote = async (
req: Request<Record<string, never>, Record<string, never>, EditProgressNoteRequestBody>,
res: Response,
next: NextFunction,
) => {
try {
const { uid } = req.body;

const user = await UserModel.findById(uid);
if (!user) {
throw ValidationError.USER_NOT_FOUND;
}

if (user.accountType !== "admin") {
throw ValidationError.UNAUTHORIZED_USER;
}

const errors = validationResult(req);
validationErrorParser(errors);

const newProgressNote = {
...req.body,
lastEditedBy: user.name,
userId: uid,
} as ExistingProgressNoteType;

const editedProgressNote = await ProgressNote.findOneAndUpdate(
{ _id: newProgressNote._id },
newProgressNote,
{ new: true }, //returns updated document
);

if (!editedProgressNote) {
throw ValidationError.PROGRESS_NOTE_NOT_FOUND;
}

res.status(200).json(editedProgressNote);
} catch (error) {
next(error);
}
};

export const deleteProgressNote = async (
req: Request<Record<string, never>, Record<string, never>, DeleteProgressNoteRequestBody>,
res: Response,
next: NextFunction,
) => {
try {
const { noteId, studentId, uid } = req.body;

const user = await UserModel.findById(uid);
if (!user) {
throw ValidationError.USER_NOT_FOUND;
}

if (user.accountType !== "admin") {
throw ValidationError.UNAUTHORIZED_USER;
}

const errors = validationResult(req);
validationErrorParser(errors);

const deletedProgressNote = await ProgressNote.findOneAndDelete({ _id: noteId });

if (!deletedProgressNote) {
throw ValidationError.PROGRESS_NOTE_NOT_FOUND;
}

const student = await StudentModel.findOneAndUpdate(
{ _id: studentId },
{ $pull: { progressNotes: noteId } },
);

if (!student) {
throw ValidationError.STUDENT_NOT_FOUND;
}

res.status(200).json(deletedProgressNote);
} catch (error) {
next(error);
}
};

export const getAllProgressNotes = async (
req: Request<Record<string, never>, Record<string, never>, LoginUserRequestBody>,
res: Response,
next: NextFunction,
) => {
try {
const { uid } = req.body;
const user = await UserModel.findById(uid);
if (!user) {
throw ValidationError.USER_NOT_FOUND;
}

const allNotes = await ProgressNote.find();

res.status(200).json(allNotes);
} catch (error) {
next(error);
}
};
37 changes: 37 additions & 0 deletions backend/src/controllers/types/progressNoteTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Schema } from "mongoose";

export type ProgressNoteType = {
studentId: Schema.Types.ObjectId;
userId: string;
lastEditedBy: string;
dateLastUpdated: Date;
content: string;
};

export type ExistingProgressNoteType = {
_id: Schema.Types.ObjectId;
userId: string;
lastEditedBy: string;
dateLastUpdated: Date;
content: string;
};

export type CreateProgressNoteRequestBody = {
studentId: Schema.Types.ObjectId;
uid: string;
dateLastUpdated: Date;
content: string;
};

export type EditProgressNoteRequestBody = {
_id: Schema.Types.ObjectId;
uid: string;
dateLastUpdated: Date;
content: string;
};

export type DeleteProgressNoteRequestBody = {
uid: string;
noteId: Schema.Types.ObjectId;
studentId: Schema.Types.ObjectId;
};
7 changes: 7 additions & 0 deletions backend/src/controllers/types/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Request } from "express";

export type UserId = {
uid: string;
};

export type UserIdRequestBody = Request & UserId;
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Request } from "express";

import { UserId } from "./types";

export type CreateUserRequestBody = {
name: string;
accountType: "admin" | "team";
Expand All @@ -11,13 +13,7 @@ export type LoginUserRequestBody = {
uid: string;
};

type UserId = {
userId: string;
};

export type UserIdRequest = Request & UserId;

export type EditNameRequestBody = {
export type EditNameRequestBody = UserId & {
newName: string;
};

Expand All @@ -42,7 +38,6 @@ export type SaveImageRequest = {
};
};

export type EditPhotoRequest = Request &
UserId & {
rawBody?: Buffer;
};
export type EditPhotoRequestBody = Request<Record<string, never>, Record<string, never>, UserId> & {
rawBody?: Buffer;
};
Loading
Loading