Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
89 changes: 66 additions & 23 deletions src/components/Team.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useRef } from "react";
import teamMembers from "../config/teammate";
import { FaLinkedin } from "react-icons/fa6";
import { useNavigate } from "react-router";
Expand All @@ -8,6 +9,7 @@ import "swiper/css/pagination";

const TeamSlider = () => {
const navigate = useNavigate();
const swiperRef = useRef(null);

const uniqueTeamMembers = Array.from(
new Map(teamMembers.map((member) => [member.name, member])).values(),
Expand All @@ -21,8 +23,63 @@ const TeamSlider = () => {
window.scrollTo(0, 0);
};

// Called every frame while Swiper scrolls — updates each slide's scale
const handleProgress = (swiper) => {
swiper.slides.forEach((slide) => {
const inner = slide.querySelector(".team-card-inner");
if (!inner) return;

// progress: how far this slide is from the center of the viewport (0 = centered)
const progress = slide.progress; // provided by Swiper per-slide
// clamp to -1 … 1 so far-away slides don't go tiny
const clamped = Math.max(-1, Math.min(1, progress));
// scale: 1 when centered, 0.82 at the edges
const scale = 1 - Math.abs(clamped) * 0.18;
const opacity = 1 - Math.abs(clamped) * 0.35;

inner.style.transform = `scale(${scale})`;
inner.style.opacity = opacity;
});
};

// Run once after init so initial positions are applied before first interaction
const handleSetTranslate = (swiper) => {
handleProgress(swiper);
};

return (
<section className="relative bg-white dark:bg-slate-900 px-4 sm:px-6 md:px-10 lg:px-16 py-16 sm:py-20">
<section className="relative bg-white dark:bg-slate-900 px-4 sm:px-6 md:px-10 lg:px-16 py-16 sm:py-20 overflow-hidden">
<style>{`
.team-card-inner {
transition: transform 0.4s cubic-bezier(0.34, 1.2, 0.64, 1),
opacity 0.4s ease;
will-change: transform, opacity;
transform-origin: center center;
}

.team-swiper .swiper-pagination {
position: relative !important;
margin-top: 2rem;
}

.team-swiper .swiper-pagination-bullet {
width: 12px;
height: 12px;
background: #e5e7eb;
opacity: 1;
transition: all 0.3s ease;
}

.team-swiper .swiper-pagination-bullet-active {
background: #021640;
transform: scale(1.2);
}

.dark .team-swiper .swiper-pagination-bullet-active {
background: #2563eb;
}
`}</style>

<div className="max-w-7xl mx-auto">
{/* Header Section */}
<div className="text-center mb-16">
Expand All @@ -48,9 +105,15 @@ const TeamSlider = () => {

{/* Team Carousel */}
<Swiper
ref={swiperRef}
modules={[Autoplay, Pagination]}
spaceBetween={32}
slidesPerView={1}
centeredSlides={true}
watchSlidesProgress={true}
onProgress={handleProgress}
onSetTranslate={handleSetTranslate}
onSwiper={handleSetTranslate}
autoplay={{
delay: 3000,
disableOnInteraction: false,
Expand All @@ -77,7 +140,8 @@ const TeamSlider = () => {
>
{displayMembers.map((member, index) => (
<SwiperSlide key={index}>
<div className="bg-white dark:bg-[#13233F] dark:border-slate-700 border border border-gray-200 hover:border-[#021640]/30 rounded-xl shadow-md hover:shadow-lg transition-all duration-300 hover:-translate-y-1 group overflow-hidden h-full">
{/* team-card-inner is what gets scaled */}
<div className="team-card-inner relative bg-white dark:bg-[#13233F] dark:border-slate-700 border border-gray-200 hover:border-[#021640]/30 rounded-xl shadow-md hover:shadow-lg group overflow-hidden h-full">
{/* Image */}
<div className="relative overflow-hidden">
<img
Expand Down Expand Up @@ -130,27 +194,6 @@ const TeamSlider = () => {
</SwiperSlide>
))}
</Swiper>

{/* Custom Pagination Styles */}
<style jsx global>{`
.team-swiper .swiper-pagination {
position: relative !important;
margin-top: 2rem;
}

.team-swiper .swiper-pagination-bullet {
width: 12px;
height: 12px;
background: #e5e7eb;
opacity: 1;
transition: all 0.3s ease;
}

.team-swiper .swiper-pagination-bullet-active {
background: #021640;
transform: scale(1.2);
}
`}</style>
</div>
</section>
);
Expand Down
14 changes: 7 additions & 7 deletions src/pages/team/TeamPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ const TeamMemberImage = ({ src, alt }) => {
};

return (
<div className="relative">
<div className="relative bg-white dark:bg-slate-100 p-3 pb-2 shadow-[0_6px_18px_rgba(2,22,64,0.12)] border border-gray-200 dark:border-slate-300">
{/* Loading skeleton */}
{isLoading && (
<div className="absolute inset-0 bg-gray-200 animate-pulse rounded-t-xl"></div>
<div className="absolute inset-3 bg-gray-200 animate-pulse rounded-none"></div>
)}

{/* Actual image */}
Expand All @@ -43,7 +43,7 @@ const TeamMemberImage = ({ src, alt }) => {
"https://via.placeholder.com/300x300?text=Photo+Coming+Soon"
}
alt={alt}
className={`w-full h-64 object-cover transition-transform duration-300 group-hover:scale-105 ${
className={`w-full h-64 object-cover object-center rounded-none border-[8px] border-white shadow-[inset_0_0_0_1px_rgba(0,0,0,0.04)] transition-transform duration-300 group-hover:scale-105 ${
isLoading ? "opacity-0" : "opacity-100"
}`}
onLoad={handleImageLoad}
Expand Down Expand Up @@ -214,7 +214,7 @@ const TeamPage = () => {
>
{filteredMembers.map((member, index) => (
<SwiperSlide key={index}>
<div className="bg-white dark:bg-[#13233F] dark:border-slate-700 border border-gray-200 hover:border-[#021640]/30 dark:hover:shadow-[0_16px_35px_rgba(11,32,68,0.35)] rounded-xl shadow-md hover:shadow-lg transition-all duration-300 hover:-translate-y-1 group overflow-hidden h-full">
<div className="bg-[#fdfdf8] dark:bg-[#13233F] border border-gray-300 dark:border-slate-700 rounded-[10px] shadow-[0_10px_24px_rgba(2,22,64,0.16)] transition-all duration-300 hover:-translate-y-2 group overflow-hidden h-full">
{/* Image */}
<div className="relative overflow-hidden">
<TeamMemberImage src={member.img} alt={member.name} />
Expand All @@ -229,7 +229,7 @@ const TeamPage = () => {
</div>

{/* Content */}
<div className="p-6 space-y-4">
<div className="p-6 pt-4 space-y-4 bg-[#fdfdf8] dark:bg-[#13233F]">
<div className="text-center">
<h3 className="font-bold text-lg dark:text-white text-[#021640] leading-tight mb-2">
{member.name || "Full Name"}
Expand Down Expand Up @@ -274,7 +274,7 @@ const TeamPage = () => {
{filteredMembers.map((member, index) => (
<div
key={index}
className="bg-white dark:bg-[#13233F] dark:border-slate-700 border border-gray-200 hover:border-[#021640]/30 dark:hover:shadow-[0_16px_35px_rgba(11,32,68,0.35)] rounded-xl shadow-md hover:shadow-lg transition-all duration-300 hover:-translate-y-1 group overflow-hidden"
className="bg-[#fdfdf8] dark:bg-[#13233F] border border-gray-300 dark:border-slate-700 rounded-[10px] shadow-[0_10px_24px_rgba(2,22,64,0.16)] transition-all duration-300 hover:-translate-y-2 group overflow-hidden"
style={{
animationDelay: `${index * 100}ms`,
}}
Expand All @@ -293,7 +293,7 @@ const TeamPage = () => {
</div>

{/* Content */}
<div className="p-6 space-y-4">
<div className="p-6 pt-4 space-y-4 bg-[#fdfdf8] dark:bg-[#13233F]">
<div className="text-center">
<h3 className="font-bold text-lg dark:text-white text-[#021640] leading-tight mb-2">
{member.name || "Full Name"}
Expand Down