11import React , { useState , useEffect } from "react" ;
22import { ArrowRight , Award , Users , BookOpen , Calendar , CheckCircle , AlertCircle } from "lucide-react" ;
33import { MotionDiv , MotionSection , MotionH2 , MotionP } from '../common/MotionWrapper' ;
4+ import { useNavigate } from "react-router-dom" ;
45
56const BASE_URL = import . meta. env . VITE_API_BASE_URL || 'https://api.openlearn.org.in' ;
67
@@ -30,45 +31,56 @@ const fetchCohortsStructure = async () => {
3031 }
3132} ;
3233
33- const LeagueCard = ( { league } ) => {
34+ const LeagueCard = ( { league, accentColor } ) => {
3435 const weeks = league . weeks || [ ] ;
36+
3537 return (
3638 < MotionDiv
37- className = "group relative rounded-2xl p-8 h-full bg-gradient-to-br from- white to-gray-50 border border -gray-200 shadow-lg hover:shadow-2xl "
39+ className = "group relative rounded-2xl p-6 md:p- 8 h-full bg-white border-2 border-gray-100 shadow-sm hover:shadow-lg transition-all duration-300 "
3840 initial = { { opacity : 0 , y : 50 } }
3941 whileInView = { { opacity : 1 , y : 0 } }
4042 viewport = { { once : true , amount : 0.3 } }
4143 transition = { { duration : 0.6 , ease : "easeOut" } }
4244 whileHover = { {
43- scale : 1.05 ,
44- y : - 10 ,
45+ y : - 5 ,
46+ borderColor : '#FFDE59' ,
4547 transition : { duration : 0.3 }
4648 } }
4749 >
4850 { /* League Status Badge */ }
49- < div className = "absolute -top-4 right-4 bg-gradient-to-r from-green-400 to-emerald-500 text-white px-4 py-2 rounded-full text-xs font-semibold shadow-md " >
51+ < div className = "absolute -top-3 right-4 bg-[#FFDE59] text-black px-4 py-2 rounded-full text-xs font-bold " >
5052 < div className = "flex items-center" >
51- < div className = "w-2 h-2 bg-white rounded-full mr-2 animate-pulse" > </ div >
53+ < div className = "w-2 h-2 bg-black rounded-full mr-2 animate-pulse" > </ div >
5254 Ongoing
5355 </ div >
5456 </ div >
5557
5658 { /* League Icon & Title */ }
5759 < MotionDiv
58- className = "flex items-center mb-6"
60+ className = "mb-6"
5961 initial = { { opacity : 0 , x : - 20 } }
6062 whileInView = { { opacity : 1 , x : 0 } }
6163 viewport = { { once : true } }
6264 transition = { { duration : 0.5 , delay : 0.2 } }
6365 >
64- < h3 className = "text-2xl font-bold transition-colors duration-300 text-gray-800 group-hover:text-gray-900" >
65- { league . name }
66- </ h3 >
66+ < div className = "flex items-center mb-3" >
67+ < div
68+ className = "w-12 h-12 rounded-xl flex items-center justify-center mr-4"
69+ style = { { backgroundColor : `${ accentColor } 15` } }
70+ >
71+ < BookOpen size = { 24 } style = { { color : accentColor } } />
72+ </ div >
73+ < div >
74+ < h3 className = "text-xl md:text-2xl font-bold text-gray-900 group-hover:text-gray-800 transition-colors duration-300" >
75+ { league . name }
76+ </ h3 >
77+ </ div >
78+ </ div >
6779 </ MotionDiv >
6880
6981 { /* League Description */ }
7082 < MotionP
71- className = "mb-6 leading-relaxed text-gray-600"
83+ className = "mb-6 leading-relaxed text-gray-600 text-sm md:text-base "
7284 initial = { { opacity : 0 } }
7385 whileInView = { { opacity : 1 } }
7486 viewport = { { once : true } }
@@ -79,7 +91,7 @@ const LeagueCard = ({ league }) => {
7991
8092 { /* Week Count Badge */ }
8193 < MotionDiv
82- className = "mb-6 inline-flex items-center px-4 py-2 rounded-lg text-sm font-medium bg-blue -50 text-blue -700 border border-blue -200"
94+ className = "mb-6 inline-flex items-center px-4 py-2 rounded-lg text-sm font-medium bg-gray -50 text-gray -700 border border-gray -200"
8395 initial = { { opacity : 0 , scale : 0.8 } }
8496 whileInView = { { opacity : 1 , scale : 1 } }
8597 viewport = { { once : true } }
@@ -103,48 +115,54 @@ const LeagueCard = ({ league }) => {
103115 } }
104116 >
105117 < h4 className = "text-sm font-semibold mb-3 text-gray-700" >
106- Whats going on :
118+ What's Going to be Covered :
107119 </ h4 >
108- < div className = "space-y-2 max-h-48 overflow-y-auto" >
120+ < div className = "space-y-2 max-h-48 overflow-y-auto custom-scrollbar " >
109121 { weeks
110122 . sort ( ( a , b ) => a . order - b . order )
123+ . slice ( 0 , 3 ) // Show only first 5 weeks to prevent overflow
111124 . map ( ( week , index ) => (
112125 < MotionDiv
113126 key = { week . id }
114- className = "flex items-start text-sm group/week text-gray-600"
127+ className = "flex items-start text-sm group/week text-gray-600 hover:text-gray-800 transition-colors duration-200 "
115128 initial = { { opacity : 0 , x : - 20 } }
116129 whileInView = { { opacity : 1 , x : 0 } }
117130 viewport = { { once : true } }
118131 transition = { { duration : 0.3 , delay : 0.1 * index } }
119- whileHover = { { x : 5 } }
132+ whileHover = { { x : 3 } }
120133 >
121- < div className = "w-2 h-2 rounded-full mt-2 mr-3 flex-shrink-0 bg-blue-400 " />
134+ < CheckCircle size = { 14 } className = "mt-1 mr-3 flex-shrink-0 text-[#FFDE59] " />
122135 < div className = "flex-1" >
123- < span className = "font-medium text-gray-700 " >
136+ < span className = "font-medium" >
124137 { week . name }
125138 </ span >
126139 </ div >
127140 </ MotionDiv >
128141 ) ) }
142+ { weeks . length > 3 && (
143+ < div className = "text-xs text-gray-500 italic" >
144+ +{ weeks . length - 3 } more weeks...
145+ </ div >
146+ ) }
129147 </ div >
130148 </ MotionDiv >
131149 ) }
132150
133151 { /* League Stats */ }
134152 < MotionDiv
135- className = "flex items-center justify-between pt-4 border-t border-gray-200 "
153+ className = "flex items-center justify-between pt-4 border-t border-gray-100 "
136154 initial = { { opacity : 0 , y : 20 } }
137155 whileInView = { { opacity : 1 , y : 0 } }
138156 viewport = { { once : true } }
139157 transition = { { duration : 0.5 , delay : 0.6 } }
140158 >
141159 < div className = "flex items-center text-sm" >
142160 < Users size = { 16 } className = "mr-2 text-gray-500" />
143- < span className = "text-gray-600" > Join League </ span >
161+ < span className = "text-gray-600 font-medium" > Community </ span >
144162 </ div >
145163 < div className = "flex items-center text-sm" >
146- < Award size = { 16 } className = "mr-2 text-blue-500 " />
147- < span className = "text-blue-600 " > Certificate</ span >
164+ < Award size = { 16 } className = "mr-2 text-[#FFDE59] " />
165+ < span className = "text-gray-700 font-medium " > Certificate</ span >
148166 </ div >
149167 </ MotionDiv >
150168 </ MotionDiv >
@@ -155,6 +173,7 @@ const Cohort = () => {
155173 const [ cohortsData , setCohortsData ] = useState ( null ) ;
156174 const [ loading , setLoading ] = useState ( true ) ;
157175 const [ error , setError ] = useState ( null ) ;
176+ const navigate = useNavigate ( ) ;
158177
159178 useEffect ( ( ) => {
160179 console . log ( '🔄 Cohort component mounted - starting data fetch...' ) ;
@@ -195,14 +214,17 @@ const Cohort = () => {
195214 return (
196215 < MotionSection
197216 id = "cohort"
198- className = "py-20 pb -24 bg-gradient-to-br from-slate-50 via- white to-blue-50 "
217+ className = "py-16 md:py- 20 lg:py -24 bg-white"
199218 initial = { { opacity : 0 } }
200219 animate = { { opacity : 1 } }
201220 >
202- < div className = "container mx-auto px-6 text-center" >
203- < div className = "flex items-center justify-center space-x-2" >
204- < div className = "w-8 h-8 border-4 border-blue-500 border-t-transparent rounded-full animate-spin" > </ div >
205- < span className = "text-gray-600" > Loading learning paths...</ span >
221+ < div className = "container mx-auto px-4 md:px-6 text-center" >
222+ < div className = "max-w-md mx-auto" >
223+ < div className = "flex items-center justify-center mb-4" >
224+ < div className = "w-12 h-12 border-4 border-[#FFDE59] border-t-transparent rounded-full animate-spin" > </ div >
225+ </ div >
226+ < h3 className = "text-xl font-semibold text-gray-800 mb-2" > Loading Learning Paths</ h3 >
227+ < p className = "text-gray-600" > Fetching the latest learning opportunities for you...</ p >
206228 </ div >
207229 </ div >
208230 </ MotionSection >
@@ -215,21 +237,26 @@ const Cohort = () => {
215237 return (
216238 < MotionSection
217239 id = "cohort"
218- className = "py-20 pb -24 bg-gradient-to-br from-slate-50 via- white to-blue-50 "
240+ className = "py-16 md:py- 20 lg:py -24 bg-white"
219241 initial = { { opacity : 0 } }
220242 animate = { { opacity : 1 } }
221243 >
222- < div className = "container mx-auto px-6 text-center" >
223- < div className = "flex items-center justify-center space-x-2 text-red-600" >
224- < AlertCircle size = { 24 } />
225- < span > Failed to load learning paths: { error } </ span >
226- </ div >
227- < div className = "mt-4" >
244+ < div className = "container mx-auto px-4 md:px-6 text-center" >
245+ < div className = "max-w-md mx-auto bg-red-50 border border-red-200 rounded-2xl p-8" >
246+ < div className = "flex items-center justify-center mb-4" >
247+ < div className = "w-16 h-16 bg-red-100 rounded-full flex items-center justify-center" >
248+ < AlertCircle size = { 32 } className = "text-red-600" />
249+ </ div >
250+ </ div >
251+ < h3 className = "text-xl font-semibold text-red-800 mb-2" > Oops! Something went wrong</ h3 >
252+ < p className = "text-red-600 mb-6" >
253+ We couldn't load the learning paths. Please try again.
254+ </ p >
228255 < button
229256 onClick = { ( ) => window . location . reload ( ) }
230- className = "px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 "
257+ className = "bg-red-600 hover: bg-red-700 text-white font-semibold py-3 px-6 rounded-xl transition-colors duration-300 "
231258 >
232- Retry
259+ Try Again
233260 </ button >
234261 </ div >
235262 </ div >
@@ -246,12 +273,22 @@ const Cohort = () => {
246273 return (
247274 < MotionSection
248275 id = "cohort"
249- className = "py-20 pb -24 bg-gradient-to-br from-slate-50 via- white to-blue-50 "
276+ className = "py-16 md:py- 20 lg:py -24 bg-white"
250277 initial = { { opacity : 0 } }
251278 animate = { { opacity : 1 } }
252279 >
253- < div className = "container mx-auto px-6 text-center" >
254- < div className = "text-gray-600" > No active cohorts available at the moment.</ div >
280+ < div className = "container mx-auto px-4 md:px-6 text-center" >
281+ < div className = "max-w-md mx-auto bg-gray-50 border border-gray-200 rounded-2xl p-8" >
282+ < div className = "flex items-center justify-center mb-4" >
283+ < div className = "w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center" >
284+ < BookOpen size = { 32 } className = "text-gray-400" />
285+ </ div >
286+ </ div >
287+ < h3 className = "text-xl font-semibold text-gray-800 mb-2" > No Active Cohorts</ h3 >
288+ < p className = "text-gray-600" >
289+ We're preparing exciting learning opportunities. Check back soon!
290+ </ p >
291+ </ div >
255292 </ div >
256293 </ MotionSection >
257294 ) ;
@@ -277,7 +314,7 @@ const Cohort = () => {
277314 return (
278315 < MotionSection
279316 id = "cohort"
280- className = "py-20 pb -24 bg-gradient-to-br from-slate-50 via- white to-blue-50 relative overflow-hidden"
317+ className = "py-16 md:py- 20 lg:py -24 bg-white relative overflow-hidden"
281318 initial = "hidden"
282319 whileInView = "visible"
283320 viewport = { { once : true , amount : 0.1 } }
@@ -292,16 +329,26 @@ const Cohort = () => {
292329 }
293330 } }
294331 >
295- { /* Background decorations */ }
296- < div className = "absolute inset-0 overflow-hidden" >
297- < div className = "absolute -top-40 -right-40 w-80 h-80 bg-gradient-to-br from-blue-100 to-purple-100 rounded-full opacity-50 blur-3xl" > </ div >
298- < div className = "absolute -bottom-40 -left-40 w-80 h-80 bg-gradient-to-br from-green-100 to-blue-100 rounded-full opacity-50 blur-3xl" > </ div >
332+ { /* Background Pattern */ }
333+ < div className = "absolute inset-0 opacity-[0.02]" >
334+ < svg width = "100%" height = "100%" xmlns = "http://www.w3.org/2000/svg" >
335+ < pattern id = "grid" x = "0" y = "0" width = "40" height = "40" patternUnits = "userSpaceOnUse" >
336+ < path d = "M 40 0 L 0 0 0 40" fill = "none" stroke = "#000000" strokeWidth = "1" />
337+ </ pattern >
338+ < rect x = "0" y = "0" width = "100%" height = "100%" fill = "url(#grid)" />
339+ </ svg >
340+ </ div >
341+
342+ { /* Decorative Elements */ }
343+ < div className = "absolute inset-0 overflow-hidden pointer-events-none" >
344+ < div className = "absolute -top-40 -right-40 w-80 h-80 bg-[#FFDE59] rounded-full opacity-5 blur-3xl" > </ div >
345+ < div className = "absolute -bottom-40 -left-40 w-80 h-80 bg-gray-900 rounded-full opacity-5 blur-3xl" > </ div >
299346 </ div >
300347
301- < div className = "container mx-auto px-6 relative z-10" >
348+ < div className = "container mx-auto px-4 md:px- 6 relative z-10" >
302349 { /* Header Section */ }
303350 < MotionDiv
304- className = "text-center mb-20 max-w-4xl mx-auto"
351+ className = "text-center mb-16 md:mb- 20 max-w-4xl mx-auto"
305352 variants = { {
306353 hidden : { opacity : 1 , y : 30 } ,
307354 visible : {
@@ -315,30 +362,30 @@ const Cohort = () => {
315362 } }
316363 >
317364 < MotionH2
318- className = "text-5xl font-bold mb-6 bg-gradient-to-r from- gray-800 via-gray- 900 to-gray-800 bg-clip-text text-transparent "
365+ className = "text-3xl md:text-4xl lg:text- 5xl font-bold mb-6 text- gray-900"
319366 >
320367 { cohort . name } – Learning Leagues
321368 </ MotionH2 >
322369
323370 < MotionP
324- className = "text-xl text-gray-600 mb-8 leading-relaxed"
371+ className = "text-lg md:text- xl text-gray-600 mb-8 leading-relaxed max-w-3xl mx-auto "
325372 >
326373 { cohort . description }
327374 </ MotionP >
328375
329- { /* Stats */ }
330- < MotionDiv className = "flex items-center justify-center flex-wrap gap-4 text-sm" >
331- < div className = "flex items-center space-x-2 bg-white px-4 py-2 rounded-full shadow-md" >
332- < BookOpen size = { 16 } className = "text-blue-500" />
333- < span className = "font-medium" > { leagues . length } League{ leagues . length !== 1 ? 's' : '' } </ span >
376+ { /* Enhanced Stats */ }
377+ < MotionDiv className = "flex items-center justify-center flex-wrap gap-4 md:gap-6" >
378+ < div className = "flex cursor-pointer items-center space-x-2 bg-gray-50 hover:bg-[#FFDE59] transition-colors duration-300 px-4 md:px-6 py-3 rounded-full border border-gray-200 group" >
379+ < BookOpen size = { 18 } className = "text-gray-700 group-hover:text-black transition-colors duration-300" />
380+ < span className = "font-semibold text-gray-800 group-hover:text-black transition-colors duration-300" >
381+ { leagues . length } Learning League{ leagues . length !== 1 ? 's' : '' }
382+ </ span >
334383 </ div >
335- < div className = "flex items-center space-x-2 bg-white px-4 py-2 rounded-full shadow-md" >
336- < Calendar size = { 16 } className = "text-green-500" />
337- < span className = "font-medium" > { totalWeeks } Total Weeks</ span >
338- </ div >
339- < div className = "flex items-center space-x-2 bg-white px-4 py-2 rounded-full shadow-md" >
340- < CheckCircle size = { 16 } className = "text-purple-500" />
341- < span className = "font-medium" > Certificates Available</ span >
384+ < div className = "flex cursor-pointer items-center space-x-2 bg-gray-50 hover:bg-[#FFDE59] transition-colors duration-300 px-4 md:px-6 py-3 rounded-full border border-gray-200 group" >
385+ < Award size = { 18 } className = "text-gray-700 group-hover:text-black transition-colors duration-300" />
386+ < span className = "font-semibold text-gray-800 group-hover:text-black transition-colors duration-300" >
387+ Certificates Available
388+ </ span >
342389 </ div >
343390 </ MotionDiv >
344391 </ MotionDiv >
@@ -347,11 +394,11 @@ const Cohort = () => {
347394 < MotionDiv className = "relative max-w-7xl mx-auto" >
348395 { /* Leagues Grid */ }
349396 < MotionDiv
350- className = { `grid gap-12 ${
397+ className = { `grid gap-8 md:gap- 12 ${
351398 leagues . length === 1
352399 ? 'max-w-2xl mx-auto'
353400 : leagues . length === 2
354- ? 'lg:grid-cols-2 lg:gap-20 '
401+ ? 'lg:grid-cols-2 lg:gap-16 '
355402 : 'lg:grid-cols-2 xl:grid-cols-3'
356403 } `}
357404 >
@@ -361,8 +408,8 @@ const Cohort = () => {
361408 return (
362409 < MotionDiv
363410 key = { league . id }
364- initial = { { opacity : 0 , x : index % 2 === 0 ? - 50 : 50 } }
365- whileInView = { { opacity : 1 , x : 0 } }
411+ initial = { { opacity : 0 , y : 50 } }
412+ whileInView = { { opacity : 1 , y : 0 } }
366413 viewport = { { once : true } }
367414 transition = { { duration : 0.6 , delay : index * 0.2 } }
368415 >
@@ -375,6 +422,32 @@ const Cohort = () => {
375422 } ) }
376423 </ MotionDiv >
377424 </ MotionDiv >
425+
426+ { /* Bottom CTA Section */ }
427+ < MotionDiv
428+ className = "text-center mt-16 md:mt-20"
429+ initial = { { opacity : 0 , y : 30 } }
430+ whileInView = { { opacity : 1 , y : 0 } }
431+ viewport = { { once : true } }
432+ transition = { { duration : 0.6 , delay : 0.5 } }
433+ >
434+ < div className = "bg-gray-50 rounded-2xl p-8 md:p-12 border border-gray-200 max-w-4xl mx-auto" >
435+ < h3 className = "text-2xl md:text-3xl font-bold text-gray-900 mb-4" >
436+ Ready to Start Your Learning Journey?
437+ </ h3 >
438+ < p className = "text-gray-600 mb-6 text-lg" >
439+ Join thousands of learners and start building skills that matter.
440+ </ p >
441+ < button
442+ className = "bg-[#FFDE59] hover:bg-yellow-400 text-black font-bold py-4 px-8 rounded-xl transition-all duration-300 transform hover:scale-105"
443+ onClick = { ( ) => {
444+ navigate ( '/signin' ) ;
445+ } }
446+ >
447+ Get Started Today
448+ </ button >
449+ </ div >
450+ </ MotionDiv >
378451 </ div >
379452 </ MotionSection >
380453 ) ;
0 commit comments