22
33import { useEffect , useState } from 'react' ;
44import { useRouter } from 'next/navigation' ;
5- import { Card , CardContent , CardDescription , CardHeader , CardTitle } from '@/components/ui/card' ;
6- import { Button } from '@/components/ui/button' ;
7- import { Badge } from '@/components/ui/badge' ;
8- import { Plus , Users , Shield , ArrowRight } from 'lucide-react' ;
9- import { toast } from 'sonner' ;
5+ import useSWR from 'swr' ;
6+ import Navbar from '@/components/navbar' ;
7+ import Footer from '@/components/footer' ;
108import { ErrorBoundary } from '@/components/error-boundary' ;
11- import { Loading } from '@/components/ui/loading ' ;
9+ import { useSession } from '@/lib/session ' ;
1210
1311interface Team {
1412 id : string ;
@@ -23,123 +21,158 @@ interface Team {
2321
2422function TeamsListContent ( ) {
2523 const router = useRouter ( ) ;
26- const [ teams , setTeams ] = useState < Team [ ] > ( [ ] ) ;
27- const [ isLoading , setIsLoading ] = useState ( true ) ;
24+ const { user } = useSession ( ) ;
2825
29- useEffect ( ( ) => {
30- fetchTeams ( ) ;
31- } , [ ] ) ;
32-
33- const fetchTeams = async ( ) => {
34- try {
35- const response = await fetch ( '/api/teams' ) ;
36- if ( ! response . ok ) throw new Error ( 'Failed to fetch teams' ) ;
37- const data = await response . json ( ) ;
38- setTeams ( data . teams || [ ] ) ;
39- } catch ( error ) {
40- toast . error ( 'Failed to load teams' ) ;
41- console . error ( 'Error fetching teams:' , error ) ;
42- } finally {
43- setIsLoading ( false ) ;
44- }
45- } ;
26+ const { data, error, isLoading } = useSWR < { teams : Team [ ] } > (
27+ '/api/teams' ,
28+ ( url ) => fetch ( url , { credentials : 'include' } ) . then ( r => r . json ( ) ) ,
29+ { refreshInterval : 30000 }
30+ ) ;
4631
47- const getRoleBadge = ( role : string ) => {
48- switch ( role ) {
49- case 'admin' :
50- return < Badge variant = "default" className = "bg-red-500" > < Shield className = "w-3 h-3 mr-1" /> Admin</ Badge > ;
51- case 'lead' :
52- return < Badge variant = "default" className = "bg-blue-500" > < Shield className = "w-3 h-3 mr-1" /> Lead</ Badge > ;
53- default :
54- return < Badge variant = "secondary" > < Users className = "w-3 h-3 mr-1" /> Developer</ Badge > ;
55- }
56- } ;
32+ const teams = data ?. teams || [ ] ;
5733
5834 if ( isLoading ) {
59- return < Loading message = "Loading teams..." /> ;
35+ return (
36+ < div className = "min-h-screen bg-[#09090B] flex flex-col items-center justify-center font-mono text-emerald-500 animate-pulse" >
37+ < span className = "text-xl tracking-[0.5em] uppercase mb-4" > Loading_Teams</ span >
38+ < div className = "w-48 h-1 bg-stone-900 rounded-full overflow-hidden" >
39+ < div className = "h-full bg-emerald-500 animate-[loading_2s_infinite]" style = { { width : '40%' } } />
40+ </ div >
41+ </ div >
42+ ) ;
6043 }
6144
62- return (
63- < div className = "container mx-auto py-8 px-4" >
64- < div className = "flex items-center justify-between mb-8" >
65- < div >
66- < h1 className = "text-3xl font-bold tracking-tight" > Teams</ h1 >
67- < p className = "text-muted-foreground mt-1" >
68- Manage your teams and collaborate with your organization
69- </ p >
45+ if ( error ) {
46+ return (
47+ < div className = "min-h-screen bg-[#09090B] flex flex-col items-center justify-center p-6 text-center grainy" >
48+ < div className = "w-16 h-16 bg-red-500/10 text-red-500 rounded-2xl flex items-center justify-center mb-8 pulse-glow border border-red-500/20" >
49+ < svg className = "w-8 h-8" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
50+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 1.5 } d = "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
51+ </ svg >
7052 </ div >
71- < Button onClick = { ( ) => router . push ( '/dashboard/teams/new' ) } >
72- < Plus className = "w-4 h-4 mr-2" />
73- Create Team
74- </ Button >
53+ < h2 className = "text-3xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-red-500 to-amber-500 mb-4 uppercase tracking-tighter" > Connection Fault</ h2 >
54+ < p className = "text-stone-500 max-w-sm font-light mb-12 leading-relaxed" > Failed to load team registry</ p >
7555 </ div >
56+ ) ;
57+ }
7658
77- { teams . length === 0 ? (
78- < Card >
79- < CardContent className = "flex flex-col items-center justify-center py-12" >
80- < Users className = "w-12 h-12 text-muted-foreground mb-4" />
81- < h3 className = "text-lg font-semibold mb-2" > No teams yet</ h3 >
82- < p className = "text-muted-foreground text-center max-w-sm mb-4" >
83- Create a team to start collaborating with your organization and share quality insights
59+ const getRoleBadge = ( role : string ) => {
60+ const styles = {
61+ admin : 'bg-red-500/10 text-red-500 border-red-500/20' ,
62+ lead : 'bg-blue-500/10 text-blue-400 border-blue-500/20' ,
63+ developer : 'bg-stone-800 text-stone-400 border-stone-700'
64+ } ;
65+ const labels = { admin : 'Admin' , lead : 'Lead' , developer : 'Developer' } ;
66+ return (
67+ < span className = { `px-3 py-1 rounded-full text-[10px] font-bold uppercase tracking-wider border ${ styles [ role as keyof typeof styles ] } ` } >
68+ { labels [ role as keyof typeof labels ] }
69+ </ span >
70+ ) ;
71+ } ;
72+
73+ return (
74+ < div className = "min-h-screen bg-[#09090B] text-[#FAFAFA] grainy" >
75+ < Navbar />
76+
77+ < main className = "max-w-7xl mx-auto px-6 pt-40 pb-24" >
78+ { /* HEADER */ }
79+ < div className = "mb-16 flex flex-col md:flex-row md:items-end justify-between gap-8" >
80+ < div >
81+ < div className = "flex items-center gap-4 mb-4" >
82+ < h1 className = "text-4xl md:text-6xl font-bold tracking-tighter uppercase" > Team_Registry</ h1 >
83+ < span className = "px-3 py-1 rounded-full text-[10px] font-bold uppercase tracking-wider bg-emerald-500/10 text-emerald-400 border border-emerald-500/20" >
84+ { teams . length } Teams
85+ </ span >
86+ </ div >
87+ < p className = "text-stone-500 font-light text-lg" >
88+ Manage your organization workspaces and collaborate with your team
89+ </ p >
90+ </ div >
91+ < button
92+ onClick = { ( ) => router . push ( '/dashboard/teams/new' ) }
93+ className = "px-10 py-4 bg-white text-black rounded-full font-bold uppercase tracking-widest text-xs hover:bg-emerald-400 hover:text-white transition-all shadow-2xl shadow-white/5 active:scale-95 flex items-center gap-2"
94+ >
95+ < svg className = "w-4 h-4" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
96+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M12 4v16m8-8H4" />
97+ </ svg >
98+ Create Team
99+ </ button >
100+ </ div >
101+
102+ { teams . length === 0 ? (
103+ < div className = "glass-panel p-20 rounded-3xl text-center relative overflow-hidden" >
104+ < div className = "absolute top-0 left-1/2 -translate-x-1/2 w-64 h-64 bg-emerald-500/10 blur-[100px] -z-10" />
105+ < div className = "w-20 h-20 mx-auto mb-8 rounded-2xl bg-stone-900 border border-stone-800 flex items-center justify-center" >
106+ < svg className = "w-10 h-10 text-stone-600" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
107+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 1.5 } d = "M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
108+ </ svg >
109+ </ div >
110+ < h3 className = "text-3xl font-bold mb-6 tracking-tight uppercase" > No Teams Found</ h3 >
111+ < p className = "text-stone-500 font-light max-w-md mx-auto mb-10 leading-relaxed" >
112+ Create a team to start collaborating with your organization and share quality insights across repositories
84113 </ p >
85- < Button onClick = { ( ) => router . push ( '/dashboard/teams/new' ) } >
86- < Plus className = "w-4 h-4 mr-2" />
87- Create Your First Team
88- </ Button >
89- </ CardContent >
90- </ Card >
91- ) : (
92- < div className = "grid gap-4 md:grid-cols-2 lg:grid-cols-3" >
93- { teams . map ( ( team ) => (
94- < Card
95- key = { team . id }
96- className = "cursor-pointer hover:shadow-md transition-shadow"
97- onClick = { ( ) => router . push ( `/dashboard/teams/${ team . id } ` ) }
114+ < button
115+ onClick = { ( ) => router . push ( '/dashboard/teams/new' ) }
116+ className = "px-12 py-4 bg-white text-black rounded-full font-bold uppercase tracking-widest text-xs hover:bg-emerald-400 hover:text-white transition-all shadow-2xl shadow-emerald-500/10"
98117 >
99- < CardHeader className = "pb-3" >
100- < div className = "flex items-start justify-between" >
101- < div className = "flex items-center gap-3" >
118+ Initialize First Team
119+ </ button >
120+ </ div >
121+ ) : (
122+ < div className = "grid gap-6 md:grid-cols-2 lg:grid-cols-3" >
123+ { teams . map ( ( team ) => (
124+ < div
125+ key = { team . id }
126+ className = "glass-panel rounded-3xl p-8 cursor-pointer hover:border-emerald-500/30 transition-all group"
127+ onClick = { ( ) => router . push ( `/dashboard/teams/${ team . id } ` ) }
128+ >
129+ < div className = "flex items-start justify-between mb-6" >
130+ < div className = "flex items-center gap-4" >
102131 { team . avatar_url ? (
103- < img
104- src = { team . avatar_url }
132+ < img
133+ src = { team . avatar_url }
105134 alt = { team . name }
106- className = "w-10 h-10 rounded-full object-cover"
135+ className = "w-14 h-14 rounded-2xl object-cover border border-stone-800 "
107136 />
108137 ) : (
109- < div className = "w-10 h-10 rounded-full bg-primary /10 flex items-center justify-center" >
110- < span className = "text-lg font-semibold text-primary " >
138+ < div className = "w-14 h-14 rounded-2xl bg-emerald-500 /10 border border-emerald-500/20 flex items-center justify-center" >
139+ < span className = "text-2xl font-bold text-emerald-400 " >
111140 { team . name . charAt ( 0 ) . toUpperCase ( ) }
112141 </ span >
113142 </ div >
114143 ) }
115144 < div >
116- < CardTitle className = "text-lg " > { team . name } </ CardTitle >
117- < CardDescription className = "text-xs " > @{ team . slug } </ CardDescription >
145+ < h3 className = "text-xl font-bold group-hover:text-emerald-400 transition-colors " > { team . name } </ h3 >
146+ < p className = "text-[10px] font-mono text-stone-500 uppercase tracking-wider " > @{ team . slug } </ p >
118147 </ div >
119148 </ div >
120149 { getRoleBadge ( team . role ) }
121150 </ div >
122- </ CardHeader >
123- < CardContent >
151+
124152 { team . description && (
125- < p className = "text-sm text-muted-foreground mb-3 line-clamp-2" >
153+ < p className = "text-sm text-stone-400 font-light mb-6 line-clamp-2 leading-relaxed " >
126154 { team . description }
127155 </ p >
128156 ) }
129- < div className = "flex items-center justify-between" >
130- < div className = "flex items-center gap-2 text-sm text-muted-foreground" >
131- < Users className = "w-4 h-4" />
132- < span > { team . member_count } members</ span >
157+
158+ < div className = "flex items-center justify-between pt-6 border-t border-stone-800/50" >
159+ < div className = "flex items-center gap-3 text-sm text-stone-500" >
160+ < svg className = "w-4 h-4" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
161+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 1.5 } d = "M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
162+ </ svg >
163+ < span className = "font-mono" > { team . member_count } members</ span >
133164 </ div >
134- < Button variant = "ghost" size = "sm" className = " gap-1">
135- View < ArrowRight className = "w-4 h-4" / >
136- </ Button >
165+ < span className = "text-[10px] font-bold uppercase tracking-widest text-emerald-400 flex items-center gap-1">
166+ View < svg className = "w-3 h-3" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" > < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M9 5l7 7-7 7" /> </ svg >
167+ </ span >
137168 </ div >
138- </ CardContent >
139- </ Card >
140- ) ) }
141- </ div >
142- ) }
169+ </ div >
170+ ) ) }
171+ </ div >
172+ ) }
173+ </ main >
174+
175+ < Footer />
143176 </ div >
144177 ) ;
145178}
0 commit comments