From 4fc0be9071b6c7ac74f001f91ea513f93138b9f3 Mon Sep 17 00:00:00 2001 From: mukeshs Date: Tue, 5 May 2026 11:55:20 +0530 Subject: [PATCH] Professor category --- src/components/faculty/TeamListing.tsx | 194 ++++++----- src/components/faculty/TeamMemberDetail.tsx | 340 +++++++++++++------- 2 files changed, 346 insertions(+), 188 deletions(-) diff --git a/src/components/faculty/TeamListing.tsx b/src/components/faculty/TeamListing.tsx index a3e10c5..d041d39 100644 --- a/src/components/faculty/TeamListing.tsx +++ b/src/components/faculty/TeamListing.tsx @@ -9,7 +9,10 @@ interface TeamListingProps { onMemberClick?: (member: TeamMember) => void; } -const TeamListing: React.FC = ({ +const GUIDES_FRIENDS_PATRONS_CATEGORIES = ['GUIDES', 'FRIENDS', 'PATRONS']; +const NON_CLICKABLE_CATEGORIES = ['TRAINEE_FELLOW', 'SUPPORT_TEAM', 'GUIDES', 'FRIENDS', 'PATRONS']; + +const TeamListing: React.FC = ({ title = "Our Team", onMemberClick }) => { @@ -35,25 +38,36 @@ const TeamListing: React.FC = ({ loadFacultyData(); }, []); - // Filter members by category and status - const facultyMembers = teamMembers.filter(member => + // Active faculty members only + const facultyMembers = teamMembers.filter(member => member.category === 'FACULTY' && member.status !== 'RETIRED' ); - const supportTeam = teamMembers.filter(member => + + // Active support team only + const supportTeam = teamMembers.filter(member => member.category === 'SUPPORT_TEAM' && member.status !== 'RETIRED' ); - const traineesAndFellows = teamMembers.filter(member => + + // Active trainees and fellows only + const traineesAndFellows = teamMembers.filter(member => member.category === 'TRAINEE_FELLOW' && member.status !== 'RETIRED' ); - const retiredStaff = teamMembers.filter(member => - member.status === 'RETIRED' + + // Guides, Friends, Patrons — all three categories in one section + const guidesFriendsPatrons = teamMembers.filter(member => + GUIDES_FRIENDS_PATRONS_CATEGORIES.includes(member.category) && member.status !== 'RETIRED' + ); + + // Alumni = RETIRED (any category) + RESIGNED (any status) + const alumniStaff = teamMembers.filter(member => + member.status === 'RETIRED' || member.category === 'RESIGNED' ); const handleMemberClick = (member: TeamMember) => { if (onMemberClick) { onMemberClick(member); } else { - window.location.href = `/faculty/${member.id}`; + window.location.href = `/faculty/${member.professorId}`; } }; @@ -73,8 +87,8 @@ const TeamListing: React.FC = ({

{error}

-
)} - - {/* Show message if all categories are empty but we have data */} - {teamMembers.length > 0 && facultyMembers.length === 0 && supportTeam.length === 0 && traineesAndFellows.length === 0 && retiredStaff.length === 0 && ( -
-
-

- No Categorized Faculty Available -

-

- Faculty members need to be assigned to categories. Please contact administration. -

-
-
- )}
); }; diff --git a/src/components/faculty/TeamMemberDetail.tsx b/src/components/faculty/TeamMemberDetail.tsx index e2c9234..cfe46ec 100644 --- a/src/components/faculty/TeamMemberDetail.tsx +++ b/src/components/faculty/TeamMemberDetail.tsx @@ -1,9 +1,9 @@ 'use client' import React, { useState, useEffect } from 'react'; import Link from 'next/link'; -import { - Phone, - Mail, +import { + Phone, + Mail, Share, ChevronRight, Check, @@ -16,6 +16,8 @@ interface TeamMemberDetailProps { memberData?: TeamMember; } +const GUIDES_FRIENDS_PATRONS_CATEGORIES = ['GUIDES', 'FRIENDS', 'PATRONS']; + const TeamMemberDetail: React.FC = ({ memberId, memberData }) => { const [member, setMember] = useState(memberData || null); const [loading, setLoading] = useState(!memberData); @@ -25,7 +27,7 @@ const TeamMemberDetail: React.FC = ({ memberId, memberDat useEffect(() => { const loadMemberData = async () => { - if (memberData) return; // Already have data + if (memberData) return; try { setLoading(true); @@ -62,8 +64,8 @@ const TeamMemberDetail: React.FC = ({ memberId, memberDat

{error || 'Faculty member not found'}

- Back to Faculty @@ -75,56 +77,87 @@ const TeamMemberDetail: React.FC = ({ memberId, memberDat const isTrainee = member.category === 'TRAINEE_FELLOW'; const isRetired = member.status === 'RETIRED'; - + const isResigned = member.category === 'RESIGNED'; + const isGuidesFriendsPatrons = GUIDES_FRIENDS_PATRONS_CATEGORIES.includes(member.category); + // Check if image URL is valid and not a default placeholder - const hasValidImage = member.image && - member.image.trim() !== '' && - !member.image.includes('default-avatar') && - !member.image.includes('placeholder.') && - !member.image.includes('robot') && - // Only filter if URL ENDS with /profile-image (backend default endpoint) - !(member.image.endsWith('/profile-image') || - member.image.includes('/profile-image?') || - member.image === 'https://via.placeholder.com/400'); + const hasValidImage = + member.image && + member.image.trim() !== '' && + !member.image.includes('default-avatar') && + !member.image.includes('placeholder.') && + !member.image.includes('robot') && + !( + member.image.endsWith('/profile-image') || + member.image.includes('/profile-image?') || + member.image === 'https://via.placeholder.com/400' + ); - const shouldShowImage = !isTrainee && hasValidImage && !imageError; + const shouldShowImage = !isTrainee && !isGuidesFriendsPatrons && hasValidImage && !imageError; - // Create a comprehensive description from the member's details const getFullDescription = () => { - return member.description || `${member.name} is a dedicated member of our ${isTrainee ? 'trainee program' : 'faculty'} with expertise in ${member.specialty?.toLowerCase() || 'medical practice'}. They bring valuable experience in ${isTrainee ? 'clinical training' : 'surgical education'}, patient care, and clinical research to Christian Medical College, Vellore.`; + return ( + member.description || + `${member.name} is a dedicated member of our ${isTrainee ? 'trainee program' : 'faculty'} with expertise in ${member.specialty?.toLowerCase() || 'medical practice'}. They bring valuable experience in ${isTrainee ? 'clinical training' : 'surgical education'}, patient care, and clinical research to Christian Medical College, Vellore.` + ); }; - // Parse phone numbers if multiple are provided const getFormattedPhone = () => { if (!member.phone || member.phone === 'Not available') { return 'Contact through main office'; } - return member.phone.includes(',') - ? member.phone.split(',').map(p => p.trim()).join(' / ') + return member.phone.includes(',') + ? member.phone + .split(',') + .map((p) => p.trim()) + .join(' / ') : member.phone; }; - const handleImageError = (e: React.SyntheticEvent) => { - console.error('Image failed to load:', member.image); + const handleImageError = () => { setImageError(true); }; + // Determine status badge config + const getStatusBadge = () => { + if (isRetired) { + return { label: 'RETIRED', bg: '#dc2626' }; + } + if (isResigned) { + return { label: 'RESIGNED', bg: '#6b7280' }; + } + if (isTrainee) { + return { label: 'Trainee / Fellow', bg: '#374151' }; + } + if (isGuidesFriendsPatrons) { + const labels: Record = { + GUIDES: 'Guide', + FRIENDS: 'Friend', + PATRONS: 'Patron', + }; + return { label: labels[member.category] || member.category, bg: '#012068' }; + } + return null; + }; + + const statusBadge = getStatusBadge(); + return (
{/* Breadcrumb Section */}
- + {/* Page Header */}
-
+

{member.name}

- {isTrainee && ( - - Trainee/Fellow - - )} - {isRetired && ( - - RETIRED + {statusBadge && ( + + {statusBadge.label} )}

- {member.designation || member.position} {member.experience && `with ${member.experience} of experience`} at CMC Vellore + {member.designation || member.position}{' '} + {member.experience && `with ${member.experience} of experience`} at CMC Vellore

@@ -169,112 +201,143 @@ const TeamMemberDetail: React.FC = ({ memberId, memberDat {/* Profile Image or Avatar */}
{shouldShowImage ? ( - {member.name} ) : ( -
- - +
)}
- + {/* Profile Info */}
-
{member.designation || member.position}
-

{member.name}

+

+ {member.name} +

- +

- {member.specialty || `${member.name} is a dedicated ${isTrainee ? 'trainee' : 'faculty member'} at CMC Vellore.`} + {member.specialty || + `${member.name} is a dedicated ${isTrainee ? 'trainee' : 'faculty member'} at CMC Vellore.`}

- +
- +
-
Phone
-
{getFormattedPhone()}
+
+ Phone +
+
+ {getFormattedPhone()} +
- + - + {member.experience && (
-
-
Experience
-
{member.experience}
+
+ Experience +
+
+ {member.experience} +
)} {member.department && (
-
-
Department
-
{member.department}
+
+ Department +
+
+ {member.department} +
)} {member.officeLocation && (
-
-
Office Location
-
{member.officeLocation}
+
+ Office Location +
+
+ {member.officeLocation} +
)}
- + {/* Social Share */}
-