diff --git a/src/backend/routers/case_manager.ts b/src/backend/routers/case_manager.ts
index 84c38f33..30f7f883 100644
--- a/src/backend/routers/case_manager.ts
+++ b/src/backend/routers/case_manager.ts
@@ -77,6 +77,48 @@ export const case_manager = router({
.executeTakeFirstOrThrow();
}),
+ /**
+ * Edits the given student in the CM's roster. Throws an error if the student was not found in the db.
+ */
+ editStudent: authenticatedProcedure
+ .input(
+ z.object({
+ student_id: z.string(),
+ first_name: z.string(),
+ last_name: z.string(),
+ email: z.string().email(),
+ grade: z.number(),
+ })
+ )
+ .mutation(async (req) => {
+ const { student_id, first_name, last_name, email, grade } = req.input;
+ const { userId } = req.ctx.auth; // case manager id
+
+ // Check if the student exists and if the case manager is assigned to the student
+ const existingStudent = req.ctx.db
+ .selectFrom("student")
+ .selectAll()
+ .where("student_id", "=", student_id)
+ .where("assigned_case_manager_id", "=", userId);
+
+ if (!existingStudent) {
+ throw new Error("Student not found");
+ }
+
+ // Update the student's information
+ return await req.ctx.db
+ .updateTable("student")
+ .set({
+ first_name,
+ last_name,
+ email: email.toLowerCase(),
+ grade,
+ })
+ .where("student_id", "=", student_id)
+ .returningAll()
+ .executeTakeFirstOrThrow();
+ }),
+
/**
* Removes the case manager associated with this student.
*/
diff --git a/src/backend/routers/para.ts b/src/backend/routers/para.ts
index 309696ba..c5e735af 100644
--- a/src/backend/routers/para.ts
+++ b/src/backend/routers/para.ts
@@ -48,6 +48,8 @@ export const para = router({
.selectAll()
.executeTakeFirst();
+ const caseManagerName = req.ctx.auth.session.user?.name ?? "";
+
if (!paraData) {
paraData = await req.ctx.db
.insertInto("user")
@@ -66,10 +68,10 @@ export const para = router({
to: email,
subject: "Para-professional email confirmation",
text: "Email confirmation",
- html: "
Email confirmation
Please confirm your email by going to the following link: no link yet
",
+ html: `
Dear ${first_name},
Welcome to the data collection team for SFUSD.EDU!
I am writing to invite you to join our data collection efforts for our students. We are using an online platform called Project Compass to track and monitor student progress, and your participation is crucial to the success of this initiative.
To access Project Compass and begin collecting data, please follow these steps:
Once logged in, navigate to the dashboard where you would see the student goals page
By clicking on the data collection button, you will be directed to the instructions outlining the necessary steps for data collection. Simply follow the provided instructions and enter the required data points accurately.
If you encounter any difficulties or have any questions, please feel free to reach out to me. I am here to assist you throughout the process and ensure a smooth data collection experience. Your dedication and contribution will make a meaningful impact on our students' educational journeys.
Thank you,
${caseManagerName} Case Manager
`,
});
- // TODO: when site is deployed, add url to html above
- // to do elsewhere: add "email_verified_at" timestamp when para first signs in with their email address (entered into db by cm)
+ // TODO: when site is deployed, add new url to html above
+ // TODO elsewhere: add "email_verified_at" timestamp when para first signs in with their email address (entered into db by cm)
}
return paraData;
diff --git a/src/backend/trpc.ts b/src/backend/trpc.ts
index ba33f371..d4184cc9 100644
--- a/src/backend/trpc.ts
+++ b/src/backend/trpc.ts
@@ -2,6 +2,7 @@ import { TRPCError, initTRPC } from "@trpc/server";
import { createContext } from "./context";
import superjson from "superjson";
+// initialize tRPC exactly once per application:
export const t = initTRPC.context().create({
// SuperJSON allows us to transparently use, e.g., standard Date/Map/Sets
// over the wire between the server and client.
@@ -34,6 +35,7 @@ const isAdmin = t.middleware(({ next, ctx }) => {
});
});
+// Define and export the tRPC router
export const router = t.router;
export const authenticatedProcedure = t.procedure.use(isAuthenticated);
export const adminProcedure = t.procedure.use(isAuthenticated).use(isAdmin);
diff --git a/src/components/iep/Iep.tsx b/src/components/iep/Iep.tsx
index 4245bc9b..447040e3 100644
--- a/src/components/iep/Iep.tsx
+++ b/src/components/iep/Iep.tsx
@@ -5,10 +5,11 @@ import $input from "@/styles/Input.module.css";
import Box from "@mui/material/Box";
import Container from "@mui/material/Container";
import List from "@mui/material/List";
+import Stack from "@mui/material/Stack";
import Image from "next/image";
import noGoals from "../../public/img/no-goals-icon.png";
-import $Iep from "./Iep.module.css";
import $Image from "../../styles/Image.module.css";
+import $Iep from "./Iep.module.css";
interface IepProps {
iep_id: string;
@@ -42,7 +43,7 @@ const Iep = ({ iep_id }: IepProps) => {
}
return (
- <>
+
-
- {/* // TODO: Extract 'Archive Student' to 'Edit' and 'Return to Student List' somewhere */}
-
-
+ Edit
+
+ )}
+
+ {/* Save and Cancel buttons only to be shown when view state is set to EDIT */}
+ {viewState === VIEW_STATES.EDIT && (
+
+
+ Cancel
+
+
+ Save
+
+
+ )}
+
+ {/* if view state is "EDIT" then show the edit version of the student page */}
+ {viewState === VIEW_STATES.EDIT &&