@@ -16,6 +16,9 @@ import {
1616 Calendar ,
1717 Trophy ,
1818 Loader2 ,
19+ Moon ,
20+ Sun ,
21+ Coffee ,
1922} from 'lucide-react' ;
2023
2124/* ── types ────────────────────────────────────────────────────────────── */
@@ -41,6 +44,7 @@ interface UserStats {
4144 currentStreak : number ;
4245 peakStreak : number ;
4346 totalContributions : number ;
47+ codingHabit ?: string ;
4448}
4549
4650interface LanguageData {
@@ -389,6 +393,111 @@ function CompareSkeleton() {
389393 ) ;
390394}
391395
396+ /* ── helper: coding habit showdown ────────────────────────────────────── */
397+
398+ function CodingHabitCard ( {
399+ username,
400+ habit,
401+ side,
402+ } : {
403+ username : string ;
404+ habit ?: string ;
405+ side : 'left' | 'right' ;
406+ } ) {
407+ const isNight = habit === 'Night Owl' ;
408+ const isEarly = habit === 'Early Bird' ;
409+
410+ const icon = isNight ? (
411+ < Moon size = { 24 } className = "text-purple-400" />
412+ ) : isEarly ? (
413+ < Sun size = { 24 } className = "text-amber-400" />
414+ ) : (
415+ < Coffee size = { 24 } className = "text-teal-400" />
416+ ) ;
417+ const bgClass = isNight
418+ ? 'bg-gradient-to-br from-indigo-950 to-purple-950 border-purple-500/30'
419+ : isEarly
420+ ? 'bg-gradient-to-br from-amber-900/40 to-orange-900/40 border-orange-500/30'
421+ : 'bg-gradient-to-br from-teal-900/40 to-emerald-900/40 border-teal-500/30' ;
422+
423+ const glowClass = isNight
424+ ? 'shadow-[0_0_15px_rgba(168,85,247,0.15)]'
425+ : isEarly
426+ ? 'shadow-[0_0_15px_rgba(245,158,11,0.15)]'
427+ : 'shadow-[0_0_15px_rgba(20,184,166,0.15)]' ;
428+
429+ return (
430+ < motion . div
431+ initial = { { opacity : 0 , x : side === 'left' ? - 20 : 20 } }
432+ whileInView = { { opacity : 1 , x : 0 } }
433+ viewport = { { once : true } }
434+ whileHover = { { scale : 1.02 } }
435+ className = { `relative overflow-hidden p-6 rounded-2xl border ${ bgClass } ${ glowClass } transition-all duration-300 flex flex-col items-center justify-center text-center h-full min-h-[140px]` }
436+ >
437+ < motion . div
438+ animate = { { y : [ 0 , - 5 , 0 ] } }
439+ transition = { { duration : 4 , repeat : Infinity , ease : 'easeInOut' } }
440+ className = "mb-3 z-10"
441+ >
442+ { icon }
443+ </ motion . div >
444+ < h4 className = "text-xs font-bold uppercase tracking-widest text-white/70 mb-1 z-10" >
445+ @{ username }
446+ </ h4 >
447+ < h3 className = "text-xl font-black tracking-tight text-white z-10" > { habit || 'Unknown' } </ h3 >
448+
449+ { /* Decorative background elements */ }
450+ { isNight && (
451+ < motion . div
452+ animate = { { opacity : [ 0.3 , 0.7 , 0.3 ] } }
453+ transition = { { duration : 3 , repeat : Infinity } }
454+ className = "absolute top-4 right-6 text-purple-300/20 text-xs"
455+ >
456+ ★
457+ </ motion . div >
458+ ) }
459+ { isEarly && (
460+ < motion . div
461+ animate = { { rotate : 360 } }
462+ transition = { { duration : 20 , repeat : Infinity , ease : 'linear' } }
463+ className = "absolute -bottom-6 -right-6 text-amber-500/10"
464+ >
465+ < Sun size = { 80 } />
466+ </ motion . div >
467+ ) }
468+ </ motion . div >
469+ ) ;
470+ }
471+
472+ function CodingHabitShowdown ( { user1, user2 } : { user1 : CompareUserData ; user2 : CompareUserData } ) {
473+ return (
474+ < div >
475+ < h2 className = "text-xs text-[#A1A1AA] uppercase tracking-widest font-medium mb-4" >
476+ Coding Habits
477+ </ h2 >
478+ < div className = "grid grid-cols-1 md:grid-cols-2 gap-6 relative" >
479+ < CodingHabitCard
480+ username = { user1 . profile . username }
481+ habit = { user1 . stats . codingHabit }
482+ side = "left"
483+ />
484+
485+ < div className = "hidden md:flex absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-10" >
486+ < div className = "w-8 h-8 rounded-full bg-white dark:bg-[#0a0a0a] border-2 border-black/10 dark:border-[rgba(255,255,255,0.08)] flex items-center justify-center shadow-xl" >
487+ < span className = "text-[10px] font-bold text-[#A1A1AA] tracking-wider" > VS</ span >
488+ </ div >
489+ </ div >
490+
491+ < CodingHabitCard
492+ username = { user2 . profile . username }
493+ habit = { user2 . stats . codingHabit }
494+ side = "right"
495+ />
496+ </ div >
497+ </ div >
498+ ) ;
499+ }
500+
392501/* ── main component ───────────────────────────────────────────────────── */
393502
394503export default function CompareClient ( ) {
@@ -662,6 +771,9 @@ export default function CompareClient() {
662771 </ div >
663772 </ div >
664773
774+ { /* Coding Habits Showdown */ }
775+ < CodingHabitShowdown user1 = { d1 } user2 = { d2 } />
776+
665777 { /* Language Comparison */ }
666778 < LanguageComparison
667779 langsA = { d1 . languages }
0 commit comments