From 98e62c49c4f5e078f54b6d7c73a25ee3e52c87da Mon Sep 17 00:00:00 2001 From: sajeetharan Date: Mon, 17 Aug 2026 10:19:52 +0530 Subject: [PATCH] fix: open search results and revise OSS worth --- app/page.jsx | 1 + components/DetailPanel.jsx | 31 +++++---- components/Leaderboard.jsx | 8 +-- components/SearchBar.jsx | 31 +++++---- docs/prd/oss-worth.md | 131 ++++++++++++++----------------------- lib/format.js | 9 +++ lib/oss-worth.js | 53 ++++++--------- styles/main.css | 53 +++++++++++++-- tests/oss-worth.test.js | 59 ++++++++--------- 9 files changed, 192 insertions(+), 184 deletions(-) diff --git a/app/page.jsx b/app/page.jsx index 6b490b2..409cd10 100644 --- a/app/page.jsx +++ b/app/page.jsx @@ -447,6 +447,7 @@ export default function Home() { developers={developers} onResults={handleSearch} onReset={handleResetFilter} + onSelectDeveloper={handleSelectDev} onGenerateCard={handleGenerateCard} onSearchState={handleTourSearchState} onOpenCardFeature={handleOpenCardFeature} diff --git a/components/DetailPanel.jsx b/components/DetailPanel.jsx index e0fd001..4a16982 100644 --- a/components/DetailPanel.jsx +++ b/components/DetailPanel.jsx @@ -4,7 +4,7 @@ import React, { useEffect, useRef, useState } from 'react'; import Link from 'next/link'; import { track } from '@vercel/analytics'; import * as d3 from 'd3'; -import { formatNum, formatRelativeTime, isStaleData } from '../lib/format.js'; +import { formatNum, formatRelativeTime, formatUsd, isStaleData } from '../lib/format.js'; import { DIMENSIONS, SCORE_METHODOLOGY } from '../lib/scoring.js'; import { SOCIAL_PREVIEW_VERSION } from '../lib/site.js'; import { classifyAgent } from '../lib/agent-class.js'; @@ -417,35 +417,40 @@ function OssWorthSection({ worth }) { Public contribution footprint

OSS Worth

- - {formatNum(worth.totalCredits)} OSC - +
+ + {formatNum(worth.totalCredits)} OSC + + + {formatUsd(worth.totalDollarValue, true)} estimated + +

- Fictional OSS Credits celebrate public contributions. They are not compensation, skill, employability, or financial value. + A playful estimate based on public activity, not compensation, skill, employability, or market value. 10 OSC equals $1 in this estimate.

- - + +
How this is calculated -

Inputs are log-normalized against fixed reference caps. Formula {worth.formulaVersion}.

+

GitHub follows GitEstimate: contributions × $0.50 + followers × $0.10 + stars × $0.30. Stack Overflow is calculated separately using answers × $0.50 + reputation × $0.10 + badges × $0.30. Formula {worth.formulaVersion}.

); } -function WorthCard({ platform, allocation, worth }) { +function WorthCard({ platform, worth }) { const platformClass = platform === 'GitHub' ? 'github' : 'stackoverflow'; return (
{platform} - {allocation} + Independent value
- - {formatNum(worth.credits)} / {formatNum(worth.maxCredits)} OSC + + {formatUsd(worth.dollarValue, true)} · {formatNum(worth.credits)} OSC {!worth.available ? (

No linked Stack Overflow profile

@@ -455,7 +460,7 @@ function WorthCard({ platform, allocation, worth }) {
  • {dimension.label} - {Math.round(dimension.weight * 100)}% · cap {formatNum(dimension.cap)} + {formatUsd(dimension.dollarsPerUnit)} each · {formatUsd(dimension.dollarValue, true)} {formatNum(dimension.sourceValue)}
  • diff --git a/components/Leaderboard.jsx b/components/Leaderboard.jsx index 32b14df..736ac28 100644 --- a/components/Leaderboard.jsx +++ b/components/Leaderboard.jsx @@ -1,7 +1,7 @@ 'use client'; import React, { useMemo, useRef, useState, useEffect, useCallback } from 'react'; -import { formatNum } from '../lib/format.js'; +import { formatNum, formatUsd } from '../lib/format.js'; import { extractCountry, normalizeCountry, countryKey } from '../lib/country.js'; import { SCORE_METHODOLOGY } from '../lib/scoring.js'; import { compareOssWorth } from '../lib/oss-worth.js'; @@ -262,10 +262,10 @@ export default function Leaderboard({ {dev.soReputation ? ● {formatNum(dev.soReputation)} : null} - OSC {formatNum(dev.ossWorth?.totalCredits || 0)} + OSC {formatNum(dev.ossWorth?.totalCredits || 0)} · {formatUsd(dev.ossWorth?.totalDollarValue || 0, true)} diff --git a/components/SearchBar.jsx b/components/SearchBar.jsx index 00bf3e5..082a468 100644 --- a/components/SearchBar.jsx +++ b/components/SearchBar.jsx @@ -25,7 +25,7 @@ const SAMPLES_BY_MODE = { ], }; -export default function SearchBar({ developers, onResults, onReset, onGenerateCard, onSearchState, onOpenCardFeature, onOpenCompareFeature, compareCount = 0 }) { +export default function SearchBar({ developers, onResults, onReset, onSelectDeveloper, onGenerateCard, onSearchState, onOpenCardFeature, onOpenCompareFeature, compareCount = 0 }) { const [query, setQuery] = useState(''); const [mode, setMode] = useState('text'); const [topN, setTopN] = useState(50); @@ -230,18 +230,25 @@ export default function SearchBar({ developers, onResults, onReset, onGenerateCa {singleResult && (
    - -
    - - {singleResult.name || singleResult.login} - - - - @{singleResult.login} - {singleResult.globalRank ? ` · Global #${singleResult.globalRank}` : ''} +
    - +