diff --git a/src/components/ActivityHeatmap.jsx b/src/components/ActivityHeatmap.jsx index 7c1414b..69f6923 100644 --- a/src/components/ActivityHeatmap.jsx +++ b/src/components/ActivityHeatmap.jsx @@ -9,31 +9,42 @@ const ActivityHeatmap = () => { useEffect(() => { const fetchData = async () => { - try { - // 1. Fetch GitHub Data (using proxy) - const githubRes = await fetch('https://github-contributions-api.jogruber.de/v4/MatissJurevics'); - const githubJson = await githubRes.json(); + // Initialize default empty data + let githubData = { contributions: [] }; + let giteaData = []; - // 2. Fetch Gitea Data - const giteaRes = await fetch('/api/gitea/api/v1/users/Matiss/heatmap'); - const giteaJson = await giteaRes.json(); // Array of { timestamp, contributions } + try { + // 1. Fetch GitHub Data (Safe Fetch) + try { + const githubRes = await fetch('https://github-contributions-api.jogruber.de/v4/MatissJurevics'); + if (githubRes.ok) { + githubData = await githubRes.json(); + } else { + console.warn("GitHub API fetch failed:", githubRes.status); + } + } catch (e) { + console.warn("GitHub API error:", e); + } + + // 2. Fetch Gitea Data (Safe Fetch) + try { + const giteaRes = await fetch('/api/gitea/api/v1/users/Matiss/heatmap'); + if (giteaRes.ok) { + giteaData = await giteaRes.json(); + } else { + console.warn("Gitea API fetch failed:", giteaRes.status); + } + } catch (e) { + console.warn("Gitea API error:", e); + } // 3. Process & Merge const processData = () => { const merged = new Map(); - - // Initialize with GitHub data (usually last year) - // The proxy returns 'contributions' array for the last year usually? - // Actually correct structure from jogruber api is { total: {}, contributions: [ { date, count, level } ] } - // But let's check what it returns specifically or handle 'years' object. - // Usually structure val: { yearly: [] , total: {} } - - // Let's rely on standard logic: get last 365 days. const today = new Date(); const oneYearAgo = new Date(); oneYearAgo.setDate(today.getDate() - 365); - // Helper to normalize date string YYYY-MM-DD const toKey = (date) => date.toISOString().split('T')[0]; // Initialize map with empty days @@ -42,11 +53,8 @@ const ActivityHeatmap = () => { } // Fill GitHub - // The API usually returns 'contributions' list. - // If structure is complex, we might need adjustments, but let's assume flat list available or extractable. - // Actually, jogruber V4 returns: { total: {}, contributions: [ { date, count, level } ... ] } - if (githubJson.contributions) { - githubJson.contributions.forEach(day => { + if (githubData && githubData.contributions) { + githubData.contributions.forEach(day => { if (merged.has(day.date)) { const curr = merged.get(day.date); curr.github = day.count; @@ -56,9 +64,8 @@ const ActivityHeatmap = () => { } // Fill Gitea - // Gitea heatmap endpoint returns array of { timestamp: unix_timestamp, contributions: count } - if (Array.isArray(giteaJson)) { - giteaJson.forEach(item => { + if (Array.isArray(giteaData)) { + giteaData.forEach(item => { const d = new Date(item.timestamp * 1000); const key = toKey(d); if (merged.has(key)) { @@ -75,8 +82,8 @@ const ActivityHeatmap = () => { const processed = processData(); setData(processed); } catch (err) { - console.error("Error fetching activity:", err); - setError(err.message); + console.error("Critical error in ActivityHeatmap:", err); + // setError(err.message); // Suppress global error to show partial data } finally { setLoading(false); } @@ -95,7 +102,7 @@ const ActivityHeatmap = () => { svg.selectAll("*").remove(); const g = svg.append("g") - .attr("transform", `translate(${width / 2}, ${height / 4})`); // Center top-ish + .attr("transform", `translate(220, 100)`); // Moved up to prevent cutoff // Isometric projection // x grid runs diagonally right-down, y grid runs diagonally left-down @@ -238,22 +245,23 @@ const ActivityHeatmap = () => { if (error) { return ( -
- DATA FLUX ERROR +
+
DATA FLUX ERROR
+
{error}
); } return (

@@ -268,7 +276,12 @@ const ActivityHeatmap = () => {

- + ); }; diff --git a/src/components/GitSection.jsx b/src/components/GitSection.jsx new file mode 100644 index 0000000..67e536b --- /dev/null +++ b/src/components/GitSection.jsx @@ -0,0 +1,47 @@ +import React from 'react'; +import GithubHistory from './GithubHistory'; +import ActivityHeatmap from './ActivityHeatmap'; + +const GitSection = () => { + return ( +
+
+ {/* Left: Github History List */} +
+ +
+ + {/* Right: Activity Heatmap 3D */} +
+ +
+
+
+ ); +}; + +export default GitSection; diff --git a/src/components/GithubHistory.jsx b/src/components/GithubHistory.jsx index 3780a50..83b8698 100644 --- a/src/components/GithubHistory.jsx +++ b/src/components/GithubHistory.jsx @@ -62,13 +62,13 @@ const GithubHistory = () => { return (
{ const [activeTab, setActiveTab] = useState('location'); @@ -34,12 +33,12 @@ const InfoTabs = () => { Where Am I? -
{/* Content Area */}
{activeTab === 'location' && } - {activeTab === 'github' && } - {activeTab === 'activity' && } + {activeTab === 'git' && }
); diff --git a/vite.config.js b/vite.config.js index 45b8799..9114c28 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,4 +1,4 @@ -import { defineConfig } from 'vite' +import { defineConfig } from 'vite' // HMR Trigger import react from '@vitejs/plugin-react' // https://vite.dev/config/