diff --git a/scripts/smoke-test.mjs b/scripts/smoke-test.mjs index a9df592..6d78e6b 100644 --- a/scripts/smoke-test.mjs +++ b/scripts/smoke-test.mjs @@ -81,8 +81,14 @@ try { await page.getByLabel('Complexity').selectOption('High'); await settle(); assert.equal(await page.locator('.list-row').count(), 2); + await page.getByLabel('Complexity').selectOption('Any'); + await page.getByLabel('Bounty').selectOption('$250–$750'); + await settle(); + assert.equal(await page.locator('.list-row').count(), 3); + assert.equal(await page.getByRole('button', { name: /Filters/ }).locator('.pipcount').innerText(), '1'); await page.getByRole('button', { name: 'Reset' }).click(); await settle(); + assert.equal(await page.getByLabel('Bounty').inputValue(), 'Any'); assert.equal(await page.locator('.list-row').count(), 7); // ------------------------------------------------------- contributor apply diff --git a/src/pages/explore.tsx b/src/pages/explore.tsx index 484866e..e761233 100644 --- a/src/pages/explore.tsx +++ b/src/pages/explore.tsx @@ -17,6 +17,7 @@ const TABS = [ const SORTS = ['Newest', 'Bounty', 'Title'] as const; const LEVELS: (Complexity | 'Any')[] = ['Any', 'Trivial', 'Medium', 'High']; +const BOUNTIES = ['Any', 'Under $250', '$250–$750', 'Over $750'] as const; export function Explore({ tab }: { tab: Tab }) { const { state } = useApp(); @@ -24,6 +25,7 @@ export function Explore({ tab }: { tab: Tab }) { const [params, setParams] = useSearchParams(); const [q, setQ] = useState(params.get('q') ?? ''); const [level, setLevel] = useState('Any'); + const [bounty, setBounty] = useState<(typeof BOUNTIES)[number]>('Any'); const [lang, setLang] = useState('Any'); const [sort, setSort] = useState<(typeof SORTS)[number]>('Newest'); const [filtersOpen, setFiltersOpen] = useState(false); @@ -50,6 +52,9 @@ export function Explore({ tab }: { tab: Tab }) { const repo = accepted.find(r => r.id === issue.repoId); if (!repo) return false; if (level !== 'Any' && issue.complexity !== level) return false; + if (bounty === 'Under $250' && issue.bounty >= 250) return false; + if (bounty === '$250–$750' && (issue.bounty < 250 || issue.bounty > 750)) return false; + if (bounty === 'Over $750' && issue.bounty <= 750) return false; if (lang !== 'Any' && !repo.languages.includes(lang)) return false; return `${issue.title} ${issue.id} ${repoName(repo)}`.toLowerCase().includes(needle); }); @@ -57,7 +62,7 @@ export function Explore({ tab }: { tab: Tab }) { sort === 'Bounty' ? b.bounty - a.bounty : sort === 'Title' ? a.title.localeCompare(b.title) : b.created.localeCompare(a.created)); - }, [state.issues, accepted, level, lang, needle, sort]); + }, [state.issues, accepted, level, bounty, lang, needle, sort]); const repos = useMemo( () => accepted.filter(r => @@ -73,7 +78,7 @@ export function Explore({ tab }: { tab: Tab }) { .map(o => ({ org: o, repos: accepted.filter(r => r.org === o) })); }, [accepted, needle]); - const activeFilters = (level !== 'Any' ? 1 : 0) + (lang !== 'Any' ? 1 : 0); + const activeFilters = (level !== 'Any' ? 1 : 0) + (lang !== 'Any' ? 1 : 0) + (bounty !== 'Any' ? 1 : 0); const count = tab === 'issues' ? issues.length : tab === 'repos' ? repos.length : orgs.length; return ( @@ -132,13 +137,22 @@ export function Explore({ tab }: { tab: Tab }) { >
{tab === 'issues' && ( - + <> + + + )} )} -