From a68c4947300ecdaeeeeb3cade382b43b9a44a8a4 Mon Sep 17 00:00:00 2001 From: Shiva Shankara Vara Prasad Date: Fri, 25 Sep 2026 15:21:55 +0530 Subject: [PATCH 1/4] Add explicit college TPO directory verification state --- backend/routes/tpo.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/routes/tpo.js b/backend/routes/tpo.js index e9f5458a..372bf8c4 100644 --- a/backend/routes/tpo.js +++ b/backend/routes/tpo.js @@ -618,7 +618,7 @@ router.get("/college-directory", requireRole("student"), async (req, res) => { try { const education = req.userDoc.education || {}; if (!education.emailVerified) { - return res.status(403).json({ error: "Verify your college email to view your college TPO directory." }); + return res.status(403).json({\n error: "Verify your college email to view your college TPO directory.",\n code: "COLLEGE_EMAIL_UNVERIFIED",\n }); } let college = null; From 62485be2c32de2de0a5543275b746785ed729b5f Mon Sep 17 00:00:00 2001 From: Shiva Shankara Vara Prasad Date: Fri, 25 Sep 2026 15:22:11 +0530 Subject: [PATCH 2/4] Add college email verification onboarding state --- src/pages/CollegeTpoDirectoryPage.jsx | 41 +++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/pages/CollegeTpoDirectoryPage.jsx b/src/pages/CollegeTpoDirectoryPage.jsx index 21d9f685..4e5a18b2 100644 --- a/src/pages/CollegeTpoDirectoryPage.jsx +++ b/src/pages/CollegeTpoDirectoryPage.jsx @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import { Mail, ShieldCheck, Users } from "lucide-react"; +import { ArrowRight, Mail, ShieldCheck, Users } from "lucide-react"; import DashboardLayout from "../layouts/DashboardLayout"; import { apiFetch } from "../services/api"; @@ -7,15 +7,26 @@ export default function CollegeTpoDirectoryPage() { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); + const [verificationRequired, setVerificationRequired] = useState(false); useEffect(() => { let cancelled = false; apiFetch("/api/tpo/college-directory") .then((result) => { - if (!cancelled) setData(result); + if (!cancelled) { + setData(result); + setVerificationRequired(false); + } }) .catch((err) => { - if (!cancelled) setError(err.message || "Failed to load your college TPOs."); + if (!cancelled) { + const isCollegeEmailUnverified = + err?.status === 403 && err?.body?.code === "COLLEGE_EMAIL_UNVERIFIED"; + setVerificationRequired(isCollegeEmailUnverified); + if (!isCollegeEmailUnverified) { + setError(err.message || "Failed to load your college TPOs."); + } + } }) .finally(() => { if (!cancelled) setLoading(false); @@ -38,6 +49,30 @@ export default function CollegeTpoDirectoryPage() {
+ ) : verificationRequired ? ( +
+
+
+
+

+ Verify your college email +

+

+ If you are a college student, verify your college email from your Profile page. +

+

+ Once your college email is verified, all verified TPOs from your college will be displayed here. +

+ + Go to Profile + +
+
) : error ? (

TPO directory unavailable

From 8e2a560915372e24bb8b7e89f09cd669e0dc6eee Mon Sep 17 00:00:00 2001 From: Shiva Shankara Vara Prasad Date: Fri, 25 Sep 2026 15:22:36 +0530 Subject: [PATCH 3/4] Add college faculty TPO invitation action --- src/pages/CollegeTpoDirectoryPage.jsx | 28 ++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/pages/CollegeTpoDirectoryPage.jsx b/src/pages/CollegeTpoDirectoryPage.jsx index 4e5a18b2..f03eb674 100644 --- a/src/pages/CollegeTpoDirectoryPage.jsx +++ b/src/pages/CollegeTpoDirectoryPage.jsx @@ -1,7 +1,8 @@ import { useEffect, useState } from "react"; -import { ArrowRight, Mail, ShieldCheck, Users } from "lucide-react"; +import { ArrowRight, Mail, Share2, ShieldCheck, Users } from "lucide-react"; import DashboardLayout from "../layouts/DashboardLayout"; import { apiFetch } from "../services/api"; +import { share } from "../utils/share"; export default function CollegeTpoDirectoryPage() { const [data, setData] = useState(null); @@ -34,6 +35,20 @@ export default function CollegeTpoDirectoryPage() { return () => { cancelled = true; }; }, []); + const handleInviteFaculty = async () => { + if (!data?.college?.name) return; + + try { + await share({ + title: "Join Code Club as a TPO", + text: `Join Code Club as a Training & Placement Officer for ${data.college.name} and help your students prepare for placements.`, + url: `${window.location.origin}/tpo/signup`, + }); + } catch { + // Share/clipboard failures should not turn the directory into an error state. + } + }; + return (
@@ -99,6 +114,17 @@ export default function CollegeTpoDirectoryPage() {

Your institution does not currently have a verified TPO on Code Club.

+

+ Connect with your college placement authority and invite a faculty member to join Code Club as a Training & Placement Officer on behalf of your college. +

+
) : (
From 7ed28f309715dfabe863a2d9426eff2ef0a6af45 Mon Sep 17 00:00:00 2001 From: Shiva Shankara Vara Prasad Date: Fri, 25 Sep 2026 15:43:21 +0530 Subject: [PATCH 4/4] Fix malformed TPO directory response syntax --- backend/routes/tpo.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/routes/tpo.js b/backend/routes/tpo.js index 372bf8c4..c6f54af1 100644 --- a/backend/routes/tpo.js +++ b/backend/routes/tpo.js @@ -618,7 +618,10 @@ router.get("/college-directory", requireRole("student"), async (req, res) => { try { const education = req.userDoc.education || {}; if (!education.emailVerified) { - return res.status(403).json({\n error: "Verify your college email to view your college TPO directory.",\n code: "COLLEGE_EMAIL_UNVERIFIED",\n }); + return res.status(403).json({ + error: "Verify your college email to view your college TPO directory.", + code: "COLLEGE_EMAIL_UNVERIFIED", + }); } let college = null;