Skip to content

panayotovip/github-dashboard

 
 

Repository files navigation

GitHub Dashboard

Stop hunting for cool repos. Start discovering them.

Filter GitHub's trending landscape by language, license, stars, topics, and more. Bookmark gems, organize collections, ignore noise. All client-side — your data stays yours.

GitHub Dashboard screenshot

React 19 TypeScript 6 Vite 7 Tailwind CSS 3 TanStack Query 5 GitHub REST + GraphQL Created with OpenCode


Features

📈 Trending Feed

Discover repositories updated in the last 24 hours, 7 days, or 30 days sorted by stars — no GitHub trending page needed.

  • ⏱️ Time range selector: Today / This Week / This Month
  • ⏱️ 30 days is the upper limit because GitHub has no official trending API. Beyond a month, pushed:>YYYY-MM-DD stars:>50 sort:stars returns the all-time most-starred repos (React, Vue, etc.) every time — the "trending" signal disappears. Shorter windows surface repos actively gaining traction.

  • ♾️ Infinite scroll pagination via IntersectionObserver
  • 📱 Fully responsive: 1 column (mobile), 2 columns (tablet), 3 columns (desktop)

✨ Sorting

Sort Description
Most Starred Descending by stargazer count
🍴 Most Forked Descending by fork count
🔀 Most Open PRs Open pull request count (GraphQL)
🐛 Most Open Issues Open issue count
🕐 Recently Updated Last push date descending
Best Match GitHub relevance ranking

🔍 Filters

Filter How it works
Language Multi-select from curated list, maps to API query
License Dropdown: All, Open Source Only, No License, or specific (MIT, Apache-2.0, GPL-3.0, etc.)
Topic tags Free-text chip input → topic:<tag> in query
Min Stars Number input in sort bar — filter by minimum star count
Archived Show/hide archived repos (hidden by default)
Forks Show/hide forked repos (hidden by default)
README Lang All Languages / English Only (client-side detection, requires PAT)

🧠 Developer-Centric Filters

Ten purpose-built filters applied client-side for detection that GitHub search qualifiers can't express:

Filter Icon What it finds
Beginner-friendly 🌱 Low complexity, learning-oriented
Good First Issue 🎯 Repos with labeled good-first-issues
Actively Maintained 🔧 Recent commits, active contributors
Solo Project 👤 Single/small-team maintained
Production Ready 🚀 Stable, licensed, widely used
AI/ML 🤖 Machine learning, LLMs, neural networks
Indie Project 🎨 Small, creative, independent projects
New & Exploding 💥 Recently created projects with stars
Low Competition 💎 Undiscovered gems with quality signals
Enterprise 🏢 Large-scale, cloud-native, infrastructure

👤 Personalization

All data stored in localStorage — no backend required.

  • 🔖 Bookmarks — save repos for later with one click
  • 📂 Collections — organize repos into custom groups
  • 👁️ Followed Topics — recommendations based on followed topics
  • 🚫 Ignore List — hide repos matching unwanted topics/languages
  • 🔗 Shareable URLs — every filter/sort combo is uniquely bookmarkable

🎨 UI & Accessibility

  • 🌙 Dark mode by default with light toggle (persisted, respects system preference)
  • 🗂️ Collapsible sidebar with all filters — hamburger menu on mobile, sticky on desktop
  • ⌨️ Full keyboard navigation and ARIA labels
  • 💀 Skeleton loading states (never a blank screen)
  • ⚠️ Error states with retry buttons and rate-limit countdowns
  • 🗳️ Empty states with reset-filters CTAs

Tech Stack

Layer Choice
Framework React 19 + Vite 7
Language TypeScript 6
Styling Tailwind CSS 3
Data Fetching TanStack Query 5 with infinite scroll
Routing React Router 7
Virtualization TanStack Virtual 3
Dates date-fns 4
Testing Vitest 4 + React Testing Library + MSW 2
Linting ESLint 10 with typescript-eslint

Project Structure

src/
├── components/
│   ├── RepoCard.tsx               # Individual repo display card
│   ├── RepoGrid.tsx               # Grid layout with infinite scroll
│   ├── FilterSidebar.tsx          # Collapsible sidebar with all filters
│   ├── SearchInput.tsx            # Debounced keyword search
│   ├── LanguageBadge.tsx          # Color-coded language indicator
│   ├── LicenseBadge.tsx           # Open source / proprietary badge
│   ├── LicenseLegend.tsx          # License legend panel
│   ├── BookmarksPanel.tsx         # Saved repos modal
│   ├── CollectionsPanel.tsx       # Collection manager modal
│   ├── FollowedTopicsManager.tsx  # Topic following modal
│   └── IgnoreListManager.tsx      # Ignore list modal
├── hooks/
│   ├── useRepos.ts                # TanStack Query infinite data hook
│   ├── useFilters.ts              # URL-synced filter state
│   ├── useSort.ts                 # URL-synced sort state
│   ├── usePersonalization.ts      # localStorage personalization hook
│   └── useTheme.ts                # Dark/light mode hook
├── lib/
│   ├── github.ts                  # REST + GraphQL API client
│   ├── utils.ts                   # Formatting helpers
│   ├── constants.ts               # Options, licenses, dev filters
│   ├── developerFilters.ts        # Client-side filter evaluation
│   ├── readmeLanguage.ts          # English README detection
│   └── userPreferences.ts         # localStorage CRUD
├── pages/
│   ├── Home.tsx                   # Main trending feed
│   └── Settings.tsx               # PAT input, preferences
├── types/
│   └── github.ts                  # API response types
├── __mocks__/
│   └── handlers.ts                # MSW handlers for testing
└── __tests__/                     # Unit + component tests

Getting Started

Prerequisites

  • Node.js >= 20
  • npm >= 9

Install

git clone <repo-url>
cd github-dashboard
npm install

Development

npm run dev

Opens at http://localhost:5173.

Build

npm run build

Output goes to dist/.

Preview production build

npm run preview

GitHub API & Authentication

The app uses both REST (search) and GraphQL (enrichment) APIs. Most features work without authentication, but providing a GitHub Personal Access Token unlocks the full experience.

Settings page

What a PAT unlocks

Without PAT With PAT
60 requests/hour (Core API) 5,000 requests/hour (Core API)
10 requests/minute (Search API) 30 requests/minute (Search API)
Basic search results only Enriched repo data (PR/issue counts, languages)
No README language detection English README detection enabled

How to get one

  1. Go to GitHub Settings → Developer settings → Personal access tokens → Fine-grained tokens
  2. Give it a name, set expiration, and select "Only select repositories" (or no repo access — the token only reads public data)
  3. No scopes needed for public data; add Metadata: Read if prompted
  4. Copy the token and paste it in the app's Settings page (/settings)

The token is stored in localStorage and sent only to GitHub API endpoints.

⚠️ Never commit tokens to source control. .env.local is gitignored.


Testing

69 tests covering utility functions, component rendering, filter logic, and language detection.

# Run all tests
npm test

# Watch mode
npm run test:watch

# Run a single test file
npx vitest run src/__tests__/utils.test.ts

# Type-check without emitting
npm run typecheck

# Lint
npm run lint

Test stack

Tool Purpose
Vitest 4 Test runner
React Testing Library Component testing
MSW 2 API mocking (REST + GQL)
jsdom DOM environment

Scripts

Command Action
npm run dev Start dev server
npm run build Type-check + build
npm run preview Preview production build
npm test Run all tests
npm run test:watch Tests in watch mode
npm run typecheck TypeScript type check
npm run lint ESLint

Support This Project ⭐

If you find GitHub Dashboard useful, consider giving it a star on GitHub — it helps others discover it.

Star this repo

Star History

Star History Chart


License

MIT

About

Filter GitHub's trending landscape by language, license, stars, topics, and more. Bookmark gems, organize collections, ignore noise. All client-side — your data stays yours.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 98.6%
  • Other 1.4%