1
1
"use client" ;
2
2
import React , { useState } from "react" ;
3
- // import {
4
- // Dialog,
5
- // DialogContent,
6
- // DialogTrigger,
7
- // DialogTitle
8
- // } from "@/components/ui/dialog";
9
3
import { ChevronLeft , ChevronRight } from "lucide-react" ;
10
4
import { motion , AnimatePresence } from "framer-motion" ;
11
5
import Link from "next/link" ;
12
6
import json from "./team.json" ;
13
7
import { Button } from "@/components/ui/button" ;
14
8
import { Mail } from "lucide-react" ;
15
- import { TwitterLogoIcon , LinkedInLogoIcon , GitHubLogoIcon , InstagramLogoIcon } from "@radix-ui/react-icons" ;
9
+ import { TwitterLogoIcon , LinkedInLogoIcon , GitHubLogoIcon , InstagramLogoIcon } from "@radix-ui/react-icons" ;
16
10
import Footer from "../Footer/page" ;
17
11
import NavBar from "../NavBar/page" ;
18
12
import { useIsMobile } from "@/hooks/use-mobile" ;
19
13
20
14
const Team = ( ) => {
21
15
const teamArray = json . teamArray ;
22
16
const isMobile = useIsMobile ( ) ;
23
-
17
+
24
18
const Gen = [
25
19
{ label : "President" , key : "p" } ,
26
20
{ label : "Alumni" , key : "a" } ,
@@ -31,7 +25,7 @@ const Team = () => {
31
25
] ;
32
26
33
27
const [ selectedGen , setSelectedGen ] = useState ( "p" ) ;
34
-
28
+
35
29
// Navigate to prev/next generation
36
30
const navigateGeneration = ( direction : 'prev' | 'next' ) => {
37
31
const currentIndex = Gen . findIndex ( g => g . key === selectedGen ) ;
@@ -46,34 +40,36 @@ const Team = () => {
46
40
47
41
return (
48
42
< div className = "flex flex-col min-h-screen bg-gray-100 dark:bg-neutral-800" >
49
- < NavBar />
50
- { /* Mobile Floating Generation Selector */ } < AnimatePresence >
43
+ < NavBar />
44
+ { /* Mobile Floating Generation Selector */ }
45
+ < AnimatePresence >
51
46
{ isMobile && (
52
- < motion . div
47
+ < motion . div
53
48
className = "fixed top-24 left-0 right-0 z-40 flex justify-center pointer-events-auto"
54
49
initial = { { y : - 50 , opacity : 0 } }
55
50
animate = { { y : 0 , opacity : 1 } }
56
51
exit = { { y : - 50 , opacity : 0 } }
57
52
transition = { { type : "spring" , stiffness : 300 , damping : 25 } }
58
- > < motion . div
53
+ >
54
+ < motion . div
59
55
className = "flex items-center gap-3 bg-black/50 border border-white/10 backdrop-blur-lg py-3 px-5 rounded-full shadow-lg"
60
56
whileHover = { { scale : 1.02 } }
61
57
>
62
- < Button
63
- variant = "ghost"
58
+ < Button
59
+ variant = "ghost"
64
60
size = "sm"
65
61
className = "text-white/70 hover:text-white h-8 w-8 p-0 flex items-center justify-center"
66
62
onClick = { ( ) => navigateGeneration ( 'prev' ) }
67
63
>
68
64
< ChevronLeft className = "h-5 w-5" />
69
65
</ Button >
70
-
66
+
71
67
< span className = "text-white font-medium px-3 min-w-[100px] text-center" >
72
68
{ Gen . find ( g => g . key === selectedGen ) ?. label }
73
69
</ span >
74
-
75
- < Button
76
- variant = "ghost"
70
+
71
+ < Button
72
+ variant = "ghost"
77
73
size = "sm"
78
74
className = "text-white/70 hover:text-white h-8 w-8 p-0 flex items-center justify-center"
79
75
onClick = { ( ) => navigateGeneration ( 'next' ) }
@@ -83,14 +79,15 @@ const Team = () => {
83
79
</ motion . div >
84
80
</ motion . div >
85
81
) }
86
- </ AnimatePresence > { /* Main Content Area */ }
82
+ </ AnimatePresence >
83
+ { /* Main Content Area */ }
87
84
< div className = "flex flex-1 pt-24 md:pt-0" >
88
85
{ /* Desktop Sidebar */ }
89
86
< div className = "hidden md:flex w-64 bg-white dark:bg-neutral-900 p-6 flex-col border-r dark:border-neutral-700 mt-24" >
90
87
< div className = "mt-8 space-y-3" >
91
88
{ Gen . map ( ( gen ) => (
92
- < Button
93
- key = { gen . key }
89
+ < Button
90
+ key = { gen . key }
94
91
variant = { selectedGen === gen . key ? "default" : "ghost" }
95
92
onClick = { ( ) => setSelectedGen ( gen . key ) }
96
93
className = "w-full justify-start h-10 text-base"
@@ -99,94 +96,117 @@ const Team = () => {
99
96
</ Button >
100
97
) ) }
101
98
</ div >
102
- </ div > { /* Team Members Grid */ }
99
+ </ div >
100
+ { /* Team Members Grid */ }
103
101
< div className = "flex-1 p-4 md:p-8 overflow-y-auto sm:mt-20 md:mt-24 lg:mt-28" >
104
102
< div className = "grid grid-cols-1 sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8 pt-6" >
105
- { teamArray . filter ( member => member . gen === selectedGen ) . map ( member => ( < div
106
- key = { member . name }
107
- className = "flex flex-col items-center text-center gap-5 bg-white dark:bg-neutral-900 p-6 md:p-8 rounded-xl shadow-md hover:shadow-lg transition-shadow"
108
- >
109
- < img
110
- src = { member . image }
111
- alt = { member . name }
112
- className = "h-36 w-36 rounded-full object-cover border-4 border-gray-200 dark:border-neutral-700"
113
- /> < div >
114
- < h3 className = "text-xl md:text-2xl font-bold text-gray-800 dark:text-gray-200" >
115
- { member . name }
116
- </ h3 >
117
- { member . role && (
118
- < p className = "text-sm md:text-base text-gray-600 dark:text-gray-400 mt-2" >
119
- { member . role }
120
- </ p >
121
- ) }
122
- < div className = "mt-5 flex justify-center gap-4" >
123
- { member . tw && (
124
- < Button
125
- variant = "outline"
126
- size = "icon"
127
- asChild
128
- className = "text-blue-500 hover:bg-blue-500"
129
- >
130
- < Link href = { member . tw } target = "_blank" rel = "noopener noreferrer" >
131
- < TwitterLogoIcon className = "h-5 w-5" />
132
- </ Link >
133
- </ Button >
134
- ) }
135
- { member . li && (
136
- < Button
137
- variant = "outline"
138
- size = "icon"
139
- asChild
140
- className = "text-indigo-500 hover:bg-indigo-500"
141
- >
142
- < Link href = { member . li } target = "_blank" rel = "noopener noreferrer" >
143
- < LinkedInLogoIcon className = "h-5 w-5" />
144
- </ Link >
145
- </ Button >
146
- ) }
147
- { member . gh && (
148
- < Button
149
- variant = "outline"
150
- size = "icon"
151
- asChild
152
- className = "text-indigo-500 hover:bg-black-500"
153
- >
154
- < Link href = { member . gh } target = "_blank" rel = "noopener noreferrer" >
155
- < GitHubLogoIcon className = "h-5 w-5" />
156
- </ Link >
157
- </ Button >
158
- ) }
159
- { member . ig && (
160
- < Button
161
- variant = "outline"
162
- size = "icon"
163
- asChild
164
- className = "text-indigo-500 hover:bg-red-500"
165
- >
166
- < Link href = { member . ig } target = "_blank" rel = "noopener noreferrer" >
167
- < InstagramLogoIcon className = "h-5 w-5" />
168
- </ Link >
169
- </ Button >
170
- ) }
171
- { member . em && (
172
- < Button
173
- variant = "outline"
174
- size = "icon"
175
- asChild
176
- className = "text-pink-500 hover:bg-pink-500"
177
- >
178
- < Link href = { `mailto:${ member . em } ` } target = "_blank" rel = "noopener noreferrer" >
179
- < Mail className = "h-5 w-5" />
180
- </ Link >
181
- </ Button >
103
+ { teamArray
104
+ . filter ( member => member . gen === selectedGen )
105
+ . map ( ( member , idx ) => (
106
+ < motion . div
107
+ key = { member . name }
108
+ className = "flex flex-col items-center text-center gap-5 bg-white dark:bg-neutral-900 p-6 md:p-8 rounded-xl shadow-md hover:shadow-lg transition-shadow"
109
+ initial = { { opacity : 0 , y : 40 , scale : 0.95 } }
110
+ animate = { { opacity : 1 , y : 0 , scale : 1 } }
111
+ transition = { {
112
+ delay : idx * 0.08 ,
113
+ duration : 0.5 ,
114
+ type : "spring" ,
115
+ stiffness : 120 ,
116
+ } }
117
+ whileHover = { {
118
+ scale : 1.05 ,
119
+ boxShadow : "0 8px 32px 0 rgba(0,0,0,0.18)" ,
120
+ } }
121
+ whileTap = { { scale : 0.97 } }
122
+ layout
123
+ >
124
+ < motion . img
125
+ src = { member . image }
126
+ alt = { member . name }
127
+ className = "h-36 w-36 rounded-full object-cover border-4 border-gray-200 dark:border-neutral-700"
128
+ initial = { { scale : 0.9 , opacity : 0 } }
129
+ animate = { { scale : 1 , opacity : 1 } }
130
+ transition = { { delay : idx * 0.08 + 0.2 , type : "spring" , stiffness : 180 } }
131
+ whileHover = { { scale : 1.12 , boxShadow : "0 4px 24px 0 rgba(0,0,0,0.18)" } }
132
+ />
133
+ < div >
134
+ < h3 className = "text-xl md:text-2xl font-bold text-gray-800 dark:text-gray-200" >
135
+ { member . name }
136
+ </ h3 >
137
+ { member . role && (
138
+ < p className = "text-sm md:text-base text-gray-600 dark:text-gray-400 mt-2" >
139
+ { member . role }
140
+ </ p >
182
141
) }
142
+ < div className = "mt-5 flex justify-center gap-4" >
143
+ { member . tw && (
144
+ < Button
145
+ variant = "outline"
146
+ size = "icon"
147
+ asChild
148
+ className = "text-blue-500 hover:bg-blue-500"
149
+ >
150
+ < Link href = { member . tw } target = "_blank" rel = "noopener noreferrer" >
151
+ < TwitterLogoIcon className = "h-5 w-5" />
152
+ </ Link >
153
+ </ Button >
154
+ ) }
155
+ { member . li && (
156
+ < Button
157
+ variant = "outline"
158
+ size = "icon"
159
+ asChild
160
+ className = "text-indigo-500 hover:bg-indigo-500"
161
+ >
162
+ < Link href = { member . li } target = "_blank" rel = "noopener noreferrer" >
163
+ < LinkedInLogoIcon className = "h-5 w-5" />
164
+ </ Link >
165
+ </ Button >
166
+ ) }
167
+ { member . gh && (
168
+ < Button
169
+ variant = "outline"
170
+ size = "icon"
171
+ asChild
172
+ className = "text-indigo-500 hover:bg-black-500"
173
+ >
174
+ < Link href = { member . gh } target = "_blank" rel = "noopener noreferrer" >
175
+ < GitHubLogoIcon className = "h-5 w-5" />
176
+ </ Link >
177
+ </ Button >
178
+ ) }
179
+ { member . ig && (
180
+ < Button
181
+ variant = "outline"
182
+ size = "icon"
183
+ asChild
184
+ className = "text-indigo-500 hover:bg-red-500"
185
+ >
186
+ < Link href = { member . ig } target = "_blank" rel = "noopener noreferrer" >
187
+ < InstagramLogoIcon className = "h-5 w-5" />
188
+ </ Link >
189
+ </ Button >
190
+ ) }
191
+ { member . em && (
192
+ < Button
193
+ variant = "outline"
194
+ size = "icon"
195
+ asChild
196
+ className = "text-pink-500 hover:bg-pink-500"
197
+ >
198
+ < Link href = { `mailto:${ member . em } ` } target = "_blank" rel = "noopener noreferrer" >
199
+ < Mail className = "h-5 w-5" />
200
+ </ Link >
201
+ </ Button >
202
+ ) }
203
+ </ div >
183
204
</ div >
184
- </ div >
185
- </ div >
186
- ) ) }
205
+ </ motion . div >
206
+ ) ) }
187
207
</ div >
188
- </ div > </ div >
189
-
208
+ </ div >
209
+ </ div >
190
210
{ /* Footer */ }
191
211
< Footer />
192
212
</ div >
0 commit comments