From fa3c43ea2a21f1a19c77880877ec56f6ce89489b Mon Sep 17 00:00:00 2001 From: cthotti Date: Fri, 1 May 2026 10:17:58 -0700 Subject: [PATCH 1/7] resolving some merge conflicts --- .../src/components/connect/AlumniTile.tsx | 81 +- frontend/src/pages/Alumni.tsx | 680 +++++----- frontend/src/pages/Connect.tsx | 127 +- frontend/src/pages/Profile.tsx | 1137 ++++++++--------- 4 files changed, 1065 insertions(+), 960 deletions(-) diff --git a/frontend/src/components/connect/AlumniTile.tsx b/frontend/src/components/connect/AlumniTile.tsx index 8cfe19d..3c76cd9 100644 --- a/frontend/src/components/connect/AlumniTile.tsx +++ b/frontend/src/components/connect/AlumniTile.tsx @@ -21,11 +21,25 @@ const AlumniTile: React.FC = ({ data }) => { }; return ( -
navigate(`/alumni/${data._id}`)} - className="bg-white rounded-lg overflow-visible h-auto transition border border-gray-300 shadow-sm hover:shadow-md"> - {/* Card header with avatar and name */} -
-
+
navigate(`/alumni/${data._id}`)} + className=" + bg-zinc-900/80 + backdrop-blur + rounded-xl + overflow-visible + h-auto + border + border-zinc-800 + shadow-lg + transition + hover:shadow-indigo-500/10 + hover:border-zinc-700 + " + > + {/* Card header */} +
+
{data.profilePicture ? ( = ({ data }) => { className="w-full h-full object-cover" /> ) : ( - {data.name.charAt(0)} + + {data.name.charAt(0)} + )}
-

{data.name}

+

+ {data.name} +

- {/* Card body with user details */} + {/* Card body */}
- -
+ +
{data.email} @@ -56,37 +74,60 @@ const AlumniTile: React.FC = ({ data }) => {
- -
+ +
{data.company ? ( {data.company.name} ) : ( - Not specified + Not specified )}
- -
- {data.position ? data.position : Not specified} + +
+ {data.position ? ( + data.position + ) : ( + Not specified + )}
+ {/* Animated button */}
+ = ({ data }) => { ); }; -export default AlumniTile; \ No newline at end of file +export default AlumniTile; diff --git a/frontend/src/pages/Alumni.tsx b/frontend/src/pages/Alumni.tsx index 92d20be..5220267 100644 --- a/frontend/src/pages/Alumni.tsx +++ b/frontend/src/pages/Alumni.tsx @@ -2,9 +2,10 @@ import React, { useCallback, useEffect, useState, useRef } from "react"; import { useParams, useNavigate } from "react-router-dom"; import { FaArrowLeft, - FaLinkedin + FaLinkedin, + FaRobot } from "react-icons/fa"; -import { LuMail, LuBuilding2, LuBriefcase, LuWand } from "react-icons/lu"; +import { LuMail, LuBuilding2, LuBriefcase, LuWand, LuSparkles } from "react-icons/lu"; import { FiPhone } from "react-icons/fi"; import { FaRegCopy } from "react-icons/fa"; import { generateEmail } from "../api/email"; @@ -17,20 +18,22 @@ import { ProgressSpinner } from "primereact/progressspinner"; import { Similarity } from "../types/Similarity"; import {Toast} from "primereact/toast"; import { parseErrorResponse } from "../utils/errorHandler"; +import "../styles/Animations.css"; const AlumniProfile: React.FC = () => { const { id } = useParams<{ id: string }>(); const toast = useRef(null); - console.log("route param id: ", id); const navigate = useNavigate(); const [alumni, setAlumni] = useState(null); const [loading, setLoading] = useState(true); - const { user} = useAuth(); + const [error] = useState(null); + const { user } = useAuth(); const [similarities, setSimilarities] = useState(null); const [similaritySummary, setSimilaritySummary] = useState(null); const [similarityLoading, setSimilarityLoading] = useState(false); + const [showSimilarities, setShowSimilarities] = useState(false); // Email Generation State const [isEmailModalOpen, setIsEmailModalOpen] = useState(false); @@ -88,6 +91,7 @@ const AlumniProfile: React.FC = () => { summary: "Error", detail: "Failed to fetch alumni: " + parseErrorResponse(result.error), }); + console.log(error); } }) .catch((error: unknown) => toast.current?.show({ @@ -96,351 +100,405 @@ const AlumniProfile: React.FC = () => { detail: "Failed to fetch alumni: " + parseErrorResponse(error), })) .finally(() => setLoading(false)); - }, [id]); + }, [id, error]); - // Initial company fetch - useEffect(() => { + useEffect(() => { handleAlumniUpdate(); }, [handleAlumniUpdate]); const resolveUserId = (): string | null => { - if (user) { - return user._id ?? null; - } - return null; - }; - - const fetchSimilarities = async () => { - if (!id) return; + if (user) { + return user._id ?? null; + } + return null; + }; - const userId = resolveUserId(); - if (!userId) { - return; - } + const fetchSimilarities = async () => { + if (!id) return; - try { - setSimilarityLoading(true); - const res = await getSimilarities(userId, id); + const userId = resolveUserId(); + if (!userId) { + return; + } - if (!res.success) { - throw new Error("Failed to fetch similarities"); - } + try { + setSimilarityLoading(true); + const res = await getSimilarities(userId, id); - setSimilarities(res.data.similarities); - setSimilaritySummary(res.data.summary); - } finally { - setSimilarityLoading(false); + if (!res.success) { + throw new Error("Failed to fetch similarities"); } - }; - - if (!alumni) + setSimilarities(res.data.similarities); + setSimilaritySummary(res.data.summary); + setShowSimilarities(true); + } catch (err) { + console.error(err); + } finally { + setSimilarityLoading(false); + } + }; + + if (loading) { return ( -
- Alumni not found. +
+
); + } + + if (!alumni) { + return ( +
+

Alumni not found.

+
+ ); + } return ( -
- {!alumni ? ( -
- Alumni not found. +
+ {/* Top Bar */} +
+ + + +
+ +
+ {/* Profile Header */} +
+
+ {/* Profile Picture */} +
+ {alumni.profilePicture ? ( + {alumni.name} + ) : ( +
+ {alumni.name + .split(" ") + .map((n) => n[0]) + .join("") + .toUpperCase()} +
+ )} +
+ + {/* Basic Info */} +
+

{alumni.name}

+
+
+
+ Email +
+

{alumni.email}

+
+
+
+ Phone +
+

{alumni.phoneNumber || Not provided}

+
+
+ + {/* LinkedIn */} +
+
+ LinkedIn +
+ {alumni.linkedIn ? ( + + View Profile → + + ) : ( +
+ Not provided +
+ )} +
+
+
- ) : ( - <> - {/* Display Spinner While Loading */} - {loading && ( -
- + + {/* Professional Information */} +
+

+
+ Professional Information +

+
+
+
+ Company +
+
+ {alumni.company?.name || Not specified} +
+
+ +
+
+ Position +
+
+ {alumni.position || Not specified} +
+
+
+
+ + {/* Organizations */} +
+

+
+ Organizations +

+ {Array.isArray(alumni.organizations) && alumni.organizations.length > 0 ? ( +
+ {alumni.organizations.map((organization, index) => ( + + {organization.charAt(0).toUpperCase() + organization.slice(1).toLowerCase()} + + ))} +
+ ) : ( +
+ Not specified
)} - {/* When Finished Loading */} - {!loading && ( -
-
- {/* Back Button to Exit Profile */} -
+ + {/* Specializations */} +
+

+
+ Specializations +

+ {Array.isArray(alumni.specializations) && alumni.specializations.length > 0 ? ( +
+ {alumni.specializations.map((specialization, index) => ( + - - Back to Connect - -
-
-
-
- {/* Left Column - Profile Image */} -
-
- {alumni.profilePicture ? ( - {alumni.name} - ) : ( -
- {alumni.name - .split(" ") - .map((n) => n[0]) - .join("") - .toUpperCase()} -
- )} -
-
+ {specialization.charAt(0).toUpperCase() + specialization.slice(1).toLowerCase()} + + ))} +
+ ) : ( +
+ Not specified +
+ )} +
- {/* Right Column - User Information */} -
- {/* Basic Information */} -
-
-

- Basic Information -

- -
-
-
- -

{alumni.name}

-
-
- -

{alumni.email}

-
- -
- -

- {alumni.phoneNumber || "Not provided"} -

-
-
-
+ {/* Skills */} +
+

+
+ Technical Skills +

+ {Array.isArray(alumni.skills) && alumni.skills.length > 0 ? ( +
+ {alumni.skills.map((skill, index) => ( + + {skill.charAt(0).toUpperCase() + skill.slice(1).toLowerCase()} + + ))} +
+ ) : ( +
+ Not specified +
+ )} +
- {/* LinkedIn */} -
- - {alumni.linkedIn ? ( - - {alumni.linkedIn} - - ) : ( -

Not provided

- )} -
+ {/* Hobbies */} +
+

+
+ Hobbies & Interests +

+ {Array.isArray(alumni.hobbies) && alumni.hobbies.length > 0 ? ( +
+ {alumni.hobbies.map((hobby, index) => ( + + {hobby.charAt(0).toUpperCase() + hobby.slice(1).toLowerCase()} + + ))} +
+ ) : ( +
+ Not specified +
+ )} +
+ + {/* AI Insights */} +
+
+

+
+ AI Insights +

+ +
+ {showSimilarities && similarities && ( +
+
+ + AI-Generated Insights +
- {/* Alumni-specific Information */} +
+
+
+
+
+ +

+ Common Ground +

+ +
+ {similarities.map((sim, idx) => ( +
+
-
-

- Professional Information -

-
-
- -

- {alumni.company?.name || "Not specified"} -

-
- -
- -

- {alumni.position || "Not specified"} -

-
-
-
-
- - {Array.isArray(alumni.organizations) && alumni.organizations.length > 0 ? ( -
- {alumni.organizations.map((organization, index) => ( - - {organization.charAt(0).toUpperCase() + organization.slice(1).toLowerCase()} - - ))} -
- ) : ( -

Not specified

- )} -
- -
- - {Array.isArray(alumni.specializations) && alumni.specializations.length > 0 ? ( -
- {alumni.specializations.map((specialization, index) => ( - - {specialization.charAt(0).toUpperCase() + specialization.slice(1).toLowerCase()} - - ))} -
- ) : ( -

Not specified

- )} -
- -
- - {Array.isArray(alumni.hobbies) && alumni.hobbies.length > 0 ? ( -
- {alumni.hobbies.map((hobby, index) => ( - - {hobby.charAt(0).toUpperCase() + hobby.slice(1).toLowerCase()} - - ))} -
- ) : ( -

Not specified

- )} -
- -
- - {Array.isArray(alumni.skills) && alumni.skills.length > 0 ? ( -
- {alumni.skills.map((skill, index) => ( - - {skill.charAt(0).toUpperCase() + skill.slice(1).toLowerCase()} - - ))} -
- ) : ( -

Not specified

- )} -
- - {/* Similarities section */} -
- - - {similarities && ( -
-

- Similarities -

-
    - {similarities.map((sim, idx) => ( -
  • - {sim.category}:{" "} - {sim.description} -
  • - ))} -
- - {similaritySummary && ( -

{similaritySummary}

- )} -
- )} -
-
+ {sim.category} + {sim.description} +
+ ))} +
- + {similaritySummary && ( +
+

+ "{similaritySummary}" +

-
+ )}
)} - - )} + + {!showSimilarities && !similarityLoading && ( +
+
+ +
+

+ Click "Find Match" to discover what you have in common with this alumni +

+
+ )} +
+
{/* Email Generation Modal */} setIsEmailModalOpen(false)} - className="w-full max-w-2xl p-6 rounded-xl" + className="w-full max-w-2xl p-6 rounded-xl bg-[#1e2433] border border-[#2d3748]" useOverlay >
-

- +

+ Personalize Email

-

+

Generate a personalized outreach email to {alumni?.name} based on your shared interests.

- +
- + setPurpose(e.target.value)} placeholder="e.g. Ask for resume advice" - className="w-full p-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 outline-none" + className="w-full p-2 bg-[#141920] border border-[#2d3748] rounded-lg text-[#e8eaed] placeholder-[#6b7280] focus:ring-2 focus:ring-[#ec4899] focus:border-[#ec4899] outline-none" />
@@ -462,21 +520,21 @@ const AlumniProfile: React.FC = () => { {generatedEmail && ( -
+
- Generated Draft + Generated Draft