From 4a689a9de5a643ea610c3d0dea188664a3a7adee Mon Sep 17 00:00:00 2001 From: GitHub Ace Date: Tue, 3 Mar 2026 19:15:07 +0000 Subject: [PATCH] feat: add time window selector for stories --- bun.lock | 1 + src/App.tsx | 46 +++++++++++++++++++++++++++++++--------------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/bun.lock b/bun.lock index 838a47c..1775e5d 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "calmhn", diff --git a/src/App.tsx b/src/App.tsx index 77b045d..21b7b9f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -21,10 +21,18 @@ interface HNStory { descendants?: number } +const TIME_WINDOWS = [ + { label: '2 weeks', days: 14 }, + { label: '1 month', days: 30 }, + { label: '3 months', days: 90 }, + { label: '6 months', days: 180 }, +] + function App() { const [stories, setStories] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) + const [timeWindow, setTimeWindow] = useState(90) useEffect(() => { const fetchTopStories = async () => { @@ -32,21 +40,18 @@ function App() { setLoading(true) setError(null) - // Calculate timestamp for three months ago - const threeMonthsAgo = Math.floor(Date.now() / 1000) - (90 * 24 * 60 * 60) + const since = Math.floor(Date.now() / 1000) - (timeWindow * 24 * 60 * 60) - // Fetch top stories from last three months using Algolia const response = await fetch( - `https://hn.algolia.com/api/v1/search?tags=story&numericFilters=created_at_i>${threeMonthsAgo}&hitsPerPage=30` + `https://hn.algolia.com/api/v1/search?tags=story&numericFilters=created_at_i>${since}&hitsPerPage=30` ) if (!response.ok) throw new Error('Failed to fetch stories') const data = await response.json() const algoliaStories: AlgoliaStory[] = data.hits - // Convert Algolia format to our HNStory format const convertedStories: HNStory[] = algoliaStories - .filter(story => story.title && story.points) // Filter out stories without title or points + .filter(story => story.title && story.points) .map(story => ({ id: parseInt(story.objectID), title: story.title, @@ -56,7 +61,7 @@ function App() { time: story.created_at_i, descendants: story.num_comments })) - .sort((a, b) => b.score - a.score) // Sort by score descending + .sort((a, b) => b.score - a.score) setStories(convertedStories) } catch (err) { @@ -67,7 +72,7 @@ function App() { } fetchTopStories() - }, []) + }, [timeWindow]) const formatTime = (timestamp: number) => { const now = Date.now() / 1000 @@ -112,13 +117,24 @@ function App() {
-
-

- Calm HN -

-

- Top stories from the last three months -

+
+
+

+ Calm HN +

+

+ Top stories from the last {TIME_WINDOWS.find(w => w.days === timeWindow)?.label} +

+
+