+ {/* Header section with profile cards & VS floating circle */}
+
+
+ {/* Floating VS middle divider */}
+
+ {t('dashboard.compare.vs')}
+
+
+ {/* User 1 profile card */}
+
+ {u1Profile.isPro && (
+
+ {t('dashboard.profile.pro')}
+
+ )}
+
+
+
+
+ {u1Profile.avatarUrl ? (
+ // eslint-disable-next-line @next/next/no-img-element
+

+ ) : (
+
+ {u1Profile.username.substring(0, 2).toUpperCase()}
+
+ )}
+
+
+
+ {u1Profile.name || u1Profile.username}
+
+
@{u1Profile.username}
+
+
+
+
+ {t('dashboard.compare.developer_score')}: {u1Profile.developerScore}
+
+
+
+
+
+ {u1Profile.bio && (
+
+ {u1Profile.bio}
+
+ )}
+
+
+ {u1Profile.location && (
+
+ {u1Profile.location}
+
+ )}
+ {u1Profile.joinedDate && (
+
+ {u1Profile.joinedDate}
+
+ )}
+
+
+
+
+
+
+ {u1Profile.stats?.repositories || 0}
+
+ {t('dashboard.profile.repos')}
+
+
+
+ {u1Profile.stats?.followers || 0}
+
+ {t('dashboard.profile.followers')}
+
+
+
+ {u1Stats.totalContributions || 0}
+
+ {t('dashboard.stats.contributions')}
+
+
+
+
+ {/* User 2 profile card */}
+
+ {u2Profile.isPro && (
+
+ {t('dashboard.profile.pro')}
+
+ )}
+
+
+
+
+ {u2Profile.avatarUrl ? (
+ // eslint-disable-next-line @next/next/no-img-element
+

+ ) : (
+
+ {u2Profile.username.substring(0, 2).toUpperCase()}
+
+ )}
+
+
+
+ {u2Profile.name || u2Profile.username}
+
+
@{u2Profile.username}
+
+
+
+
+ {t('dashboard.compare.developer_score')}: {u2Profile.developerScore}
+
+
+
+
+
+ {u2Profile.bio && (
+
+ {u2Profile.bio}
+
+ )}
+
+
+ {u2Profile.location && (
+
+ {u2Profile.location}
+
+ )}
+ {u2Profile.joinedDate && (
+
+ {u2Profile.joinedDate}
+
+ )}
+
+
+
+
+
+
+ {u2Profile.stats?.repositories || 0}
+
+ {t('dashboard.profile.repos')}
+
+
+
+ {u2Profile.stats?.followers || 0}
+
+ {t('dashboard.profile.followers')}
+
+
+
+ {u2Stats.totalContributions || 0}
+
+ {t('dashboard.stats.contributions')}
+
+
+
+
+
+ {/* Contribution Comparison Section */}
+
+
+
+ {t('dashboard.compare.contribution_comparison.title')}
+
+
+ {t('dashboard.compare.contribution_comparison.subtitle')}
+
+
+
+ {monthlyData.length === 0 ? (
+
+ {t('dashboard.compare.contribution_comparison.no_data')}
+
+ ) : (
+
+ {/* Visual Bar Chart */}
+
+ {monthlyData.map((data, idx) => {
+ const u1Pct = (data.user1 / maxMonthlyVal) * 100;
+ const u2Pct = (data.user2 / maxMonthlyVal) * 100;
+
+ return (
+
+
+ {/* Hover Stats Tooltip */}
+
+
{data.label}
+
@{u1Profile.username}: {data.user1}
+
@{u2Profile.username}: {data.user2}
+
+
+ {/* The double bar */}
+
+ {/* User 1 bar (emerald) */}
+
+
+ {/* User 2 bar (indigo) */}
+
+
+
+ {/* Month label */}
+
+ {data.label.split(' ')[0]}
+
+
+ );
+ })}
+
+
+ {/* Quick legend with totals */}
+
+
+
+
+ {t('dashboard.compare.contribution_comparison.user_total', {
+ name: `@${u1Profile.username}`,
+ count: u1Stats.totalContributions.toLocaleString()
+ })}
+
+
+
+ {t('dashboard.compare.contribution_comparison.user_total', {
+ name: `@${u2Profile.username}`,
+ count: u2Stats.totalContributions.toLocaleString()
+ })}
+
+
+
+
+ )}
+
+
+ {/* Language Breakdown Section */}
+
+
+
+ {t('dashboard.compare.language_comparison.title')}
+
+
+ {t('dashboard.compare.language_comparison.subtitle')}
+
+
+
+ {combinedLanguages.length === 0 ? (
+
+ {t('dashboard.compare.language_comparison.no_data')}
+
+ ) : (
+
+ {combinedLanguages.map((lang) => (
+
+ {/* User 1 language percentage */}
+
+
+ {lang.user1Pct.toFixed(1)}%
+
+
+
+
+ {/* Center language badge */}
+
+
+
+ {lang.name}
+
+
+
+ {/* User 2 language percentage */}
+
+
+
+ {lang.user2Pct.toFixed(1)}%
+
+
+
+ ))}
+
+ )}
+
+
+ {/* Achievement Comparison Section */}
+
+
+
+
+ {t('dashboard.compare.achievement_comparison.title')}
+
+
+ {t('dashboard.compare.achievement_comparison.subtitle')}
+
+
+
+
+ {mergedAchievements.length === 0 ? (
+
+ {t('dashboard.compare.achievement_comparison.no_data')}
+
+ ) : (
+
+
+ @{u1Profile.username}
+ {t('dashboard.achievements.title')}
+ @{u2Profile.username}
+
+
+
+ {visibleAchievements.map((item) => {
+ const isUnlocked1 = item.user1?.isUnlocked || false;
+ const isUnlocked2 = item.user2?.isUnlocked || false;
+
+ // Let's decide how to display who unlocked it
+ let unlockedBy = t('dashboard.compare.achievement_comparison.neither');
+ if (isUnlocked1 && isUnlocked2) {
+ unlockedBy = t('dashboard.compare.achievement_comparison.both');
+ } else if (isUnlocked1) {
+ unlockedBy = `@${u1Profile.username}`;
+ } else if (isUnlocked2) {
+ unlockedBy = `@${u2Profile.username}`;
+ }
+
+ return (
+
+ {/* User 1 Badge */}
+
+ {isUnlocked1 ? (
+
+
+ {t('dashboard.compare.achievement_comparison.unlocked')}
+
+ ) : (
+
+
+ {t('dashboard.compare.achievement_comparison.locked')}
+
+ )}
+
+
+ {/* Achievement Details */}
+
+
+ {item.type === 'streak' ? (
+
+ ) : item.type === 'behavior' ? (
+
+ ) : (
+
+ )}
+
+ {item.title}
+
+
+
+ {item.description}
+
+
+ {t('dashboard.compare.achievement_comparison.unlocked_by')}: {unlockedBy}
+
+
+
+ {/* User 2 Badge */}
+
+ {isUnlocked2 ? (
+
+
+ {t('dashboard.compare.achievement_comparison.unlocked')}
+
+ ) : (
+
+
+ {t('dashboard.compare.achievement_comparison.locked')}
+
+ )}
+
+
+ );
+ })}
+
+
+ {mergedAchievements.length > 4 && (
+
+ )}
+
+ )}
+
+
+ {/* Repository Comparison Section */}
+
+
+
+ {t('dashboard.compare.repository_comparison.title')}
+
+
+ {t('dashboard.compare.repository_comparison.subtitle')}
+
+
+
+ {u1TopRepos.length === 0 && u2TopRepos.length === 0 ? (
+
+ {t('dashboard.compare.repository_comparison.no_data')}
+
+ ) : (
+
+ {Array.from({ length: maxRepoRank }).map((_, rankIdx) => {
+ const repo1 = u1TopRepos[rankIdx];
+ const repo2 = u2TopRepos[rankIdx];
+
+ // If neither has a repository at this rank, don't render it
+ if (!repo1 && !repo2) return null;
+
+ // Highlighting winners for individual stats
+ const scoreWinner = repo1 && repo2 ? (repo1.score > repo2.score ? 'user1' : repo1.score < repo2.score ? 'user2' : 'tie') : null;
+ const commitsWinner = repo1 && repo2 ? (repo1.commits > repo2.commits ? 'user1' : repo1.commits < repo2.commits ? 'user2' : 'tie') : null;
+ const starsWinner = repo1 && repo2 ? (repo1.stars > repo2.stars ? 'user1' : repo1.stars < repo2.stars ? 'user2' : 'tie') : null;
+ const forksWinner = repo1 && repo2 ? (repo1.forks > repo2.forks ? 'user1' : repo1.forks < repo2.forks ? 'user2' : 'tie') : null;
+
+ return (
+
+ {/* Repo 1 details (Left) */}
+
+ {repo1 ? (
+
+
+
+ {repo1.name}
+
+ {repo1.language.name !== 'Unknown' && (
+
+
+ {repo1.language.name}
+
+ )}
+
+
+
+
+ {repo1.description && (
+
+ {repo1.description}
+
+ )}
+
+
+
+ {t('dashboard.compare.repository_comparison.commits')}
+
+ {repo1.commits}
+
+
+
+ {t('dashboard.compare.repository_comparison.stars')}
+
+ {repo1.stars}
+
+
+
+ {t('dashboard.compare.repository_comparison.forks')}
+
+ {repo1.forks}
+
+
+
+ {t('dashboard.compare.repository_comparison.impact_score')}
+
+ {repo1.score}
+
+
+
+
+ ) : (
+
+ N/A
+
+ )}
+
+
+ {/* Central Rank Indicator */}
+
+
+ {t('dashboard.compare.repository_comparison.rank')}
+
+
+ #{rankIdx + 1}
+
+
+
+ {/* Repo 2 details (Right) */}
+
+ {repo2 ? (
+
+
+
+
+
+ {repo2.language.name !== 'Unknown' && (
+
+
+ {repo2.language.name}
+
+ )}
+
+ {repo2.name}
+
+
+ {repo2.description && (
+
+ {repo2.description}
+
+ )}
+
+
+
+ {t('dashboard.compare.repository_comparison.commits')}
+
+ {repo2.commits}
+
+
+
+ {t('dashboard.compare.repository_comparison.stars')}
+
+ {repo2.stars}
+
+
+
+ {t('dashboard.compare.repository_comparison.forks')}
+
+ {repo2.forks}
+
+
+
+ {t('dashboard.compare.repository_comparison.impact_score')}
+
+ {repo2.score}
+
+
+
+
+ ) : (
+
+ N/A
+
+ )}
+
+
+ );
+ })}
+
+ )}
+
+
+ );
+}
diff --git a/components/dashboard/RepositoryImpactAnalyzer.test.tsx b/components/dashboard/RepositoryImpactAnalyzer.test.tsx
new file mode 100644
index 000000000..4c1459db5
--- /dev/null
+++ b/components/dashboard/RepositoryImpactAnalyzer.test.tsx
@@ -0,0 +1,163 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import { render, screen } from '@testing-library/react';
+import { describe, expect, it, vi } from 'vitest';
+import RepositoryImpactAnalyzer, { formatAge } from './RepositoryImpactAnalyzer';
+
+// Mock framer-motion to render clean HTML containers for testing
+vi.mock('framer-motion', () => ({
+ motion: {
+ div: ({ children, className, style, ...props }: any) => {
+ delete props.initial;
+ delete props.animate;
+ delete props.whileInView;
+ delete props.viewport;
+ delete props.transition;
+ return (
+