diff --git a/src/pages/ComparePage.jsx b/src/pages/ComparePage.jsx index 1a1f7ec..fb67067 100644 --- a/src/pages/ComparePage.jsx +++ b/src/pages/ComparePage.jsx @@ -1,7 +1,22 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useMemo } from 'react'; import { useApp } from '@/context/AppContext'; import { getRepo, getContributors, getCommunityProfile, searchRepos } from '@/api/github'; -import { FiPlus, FiX, FiSearch, FiStar, FiGitBranch, FiAlertCircle, FiShield, FiUsers, FiClock, FiTrash2, FiBookmark, FiCheck } from 'react-icons/fi'; +import { + FiPlus, + FiX, + FiSearch, + FiStar, + FiGitBranch, + FiAlertCircle, + FiShield, + FiUsers, + FiClock, + FiTrash2, + FiCopy, + FiShare2, + FiBookmark, + FiCheck, +} from "react-icons/fi"; import { formatNumber } from '@/utils/format'; function formatDate(d) { @@ -47,6 +62,23 @@ export default function ComparePage() { loadAll(); }, [compareList]); + useEffect(() => { + const params = new URLSearchParams(window.location.search); + + const repos = params.get("repos"); + + if (!repos) return; + + repos.split(",").forEach(async(fullName) => { + const [owner, repo] = fullName.split("/"); + + try{ + const repository = await getRepo(owner, repo); + addToCompare(repository); + } catch (_) {} + }); + }, [addToCompare]); + const handleSearch = async (e) => { e.preventDefault(); if (!searchQuery.trim()) return; @@ -79,6 +111,47 @@ export default function ComparePage() { { key: 'created', label: 'Created', icon: , getValue: (d) => formatDate(d?.repo?.created_at) }, ]; + const markdownTable = useMemo(() => { + if (compareList.length === 0) return ""; + + let md = "| Metric |"; + + compareList.forEach(repo => { + md += ` ${repo.name} |`; + }); + + md += "\n|---|"; + compareList.forEach(() => { + md += "---|"; + }); + + COMPARE_METRICS.forEach(metric => { + md += `\n| ${metric.label} |`; + + compareList.forEach(repo => { + md += ` ${metric.getValue(repoData[repo.full_name])} |`; + }); + }); + + return md; +}, [compareList, repoData]); + +const copyMarkdown = async () => { + await navigator.clipboard.writeText(markdownTable); + alert("Markdown copied!"); +}; + +const shareComparison = async () => { + const repos = compareList.map(r => r.full_name).join(","); + + const url = + `${window.location.origin}/compare?repos=${encodeURIComponent(repos)}`; + + await navigator.clipboard.writeText(url); + + alert("Shareable link copied!"); +}; + return (
@@ -174,6 +247,26 @@ export default function ComparePage() { )}
)} + +
+ + + +
+ {/* Comparison Table */} {compareList.length > 0 && Object.keys(repoData).length > 0 && !loading && (