Skip to content

feat: add issues tracking page with filters and sorting#273

Open
isauravanand wants to merge 3 commits into
GitMetricsLab:mainfrom
isauravanand:feature/track-issues
Open

feat: add issues tracking page with filters and sorting#273
isauravanand wants to merge 3 commits into
GitMetricsLab:mainfrom
isauravanand:feature/track-issues

Conversation

@isauravanand
Copy link
Copy Markdown

@isauravanand isauravanand commented May 16, 2026

Related Issue


Description

This PR introduces a new Issues Tracking Page (/issues) that allows users to explore open GitHub issues directly from the platform.

Features Implemented

  • Integrated the GitHub Search API to dynamically fetch and display open issues

  • Added filtering options based on:

    • Programming Languages (JavaScript, Python, Go, etc.)
    • Labels/Tags (good first issue, bug, etc.)
  • Implemented sorting functionality for:

    • Newest Issues
    • Oldest Issues
  • Added /issues route integration in both desktop and mobile Navbar components

  • Improved code quality by:

    • Fixing strict TypeScript typings (SelectChangeEvent)
    • Removing unused imports
    • Ensuring clean build and lint compatibility

How Has This Been Tested?

  • Tested the feature locally using the Vite development server
  • Verified GitHub API requests and query parameter handling
  • Confirmed filters and sorting work correctly
  • Tested API error handling (including rate-limit scenarios)
  • Verified responsive UI behavior across different screen sizes
  • Ensured there are no TypeScript or ESLint errors in modified files

Screenshots

image

Type of Change

  • Bug fix
  • New feature
  • Code style update
  • Breaking change
  • Documentation update

Summary by CodeRabbit

  • New Features

    • Added an Issues page to browse, filter and paginate GitHub issues with sorting and rate-limit-aware error handling.
    • Added navigation link to the Issues page in desktop and mobile menus.
  • Refactor

    • Redesigned responsive navbar with animated mobile menu, updated theme toggle and explicit login/signup links.

Review Change Stack

@netlify
Copy link
Copy Markdown

netlify Bot commented May 16, 2026

Deploy Preview for github-spy ready!

Name Link
🔨 Latest commit 42e1219
🔍 Latest deploy log https://app.netlify.com/projects/github-spy/deploys/6a09d7d04fc28f00084217ac
😎 Deploy Preview https://deploy-preview-273--github-spy.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e9c4cc05-423e-4bfc-a170-2e189dd7b6b5

📥 Commits

Reviewing files that changed from the base of the PR and between 3dbd9ba and 24f04a3.

📒 Files selected for processing (1)
  • src/components/Navbar.tsx

📝 Walkthrough

Walkthrough

Adds a new Issues page that queries GitHub Issues Search, provides language/label/sort filters with pagination, registers a /issues route, and adds "Issues" links in the desktop and mobile navbar (mobile menu collapses on navigation).

Changes

Issues Page Feature

Layer / File(s) Summary
Issues page component with API fetching and state management
src/pages/Issues/Issues.tsx
Issues component manages state for pagination, filters, loading/error status, builds GitHub search queries, handles API failures including 403, and renders filter controls plus a paginated MUI table of issue results.
Route registration
src/Routes/Router.tsx
Router imports Issues and registers a new Route for path /issues.
Navbar desktop & mobile links and mobile menu behavior
src/components/Navbar.tsx
Navbar refactor uses NavLink active styling, adds an Issues link to desktop and mobile navigation, replaces mobile toggle with icon controls and an animated panel, and collapses the mobile menu on navigation via onClick={() => setIsOpen(false)}.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant IssuesComponent
  participant GitHubAPI
  participant UITable

  User->>IssuesComponent: selects filters or changes page
  IssuesComponent->>GitHubAPI: fetch /search/issues?q={query}&page={n}
  GitHubAPI-->>IssuesComponent: returns items + total_count / error
  IssuesComponent->>UITable: update render (rows + pagination)
  UITable-->>User: display results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

gssoc25

Poem

🐰 A curious rabbit hops to the code,
New Issues appear on a paginated road.
Filters, links, and a menu that slides,
From GitHub’s issues the data now glides.
Hooray — the tracker grows, and the rabbit hides!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the primary change: adding a new issues tracking page with filters and sorting functionality.
Description check ✅ Passed The PR description comprehensively covers all required template sections including related issue, detailed feature implementation, testing methodology, screenshots, and type of change selection.
Linked Issues check ✅ Passed All requirements from issue #55 are met: GitHub issues search API integration [#55], language filtering [#55], label/tag filtering [#55], and newest/oldest sorting [#55].
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #55 requirements: Issues page component, routing, navbar integration, filters, sorting, and TypeScript/code quality improvements are all on-topic.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch feature/track-issues

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 Thank you @isauravanand for your contribution. Please make sure your PR follows https://github.com/GitMetricsLab/github_tracker/blob/main/CONTRIBUTING.md#-pull-request-guidelines

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/pages/Issues/Issues.tsx`:
- Around line 50-90: fetchIssues can race when multiple requests are in-flight;
create an AbortController ref (e.g., abortControllerRef) and before starting a
new fetch in fetchIssues abort any existing controller, then create a new
controller and pass its signal to fetch; in the catch block ignore abort errors
(check err.name === 'AbortError' or err instanceof DOMException) and only
setError for real failures; also abort any pending request in the useEffect
cleanup (return () => abortControllerRef.current?.abort()) so stale responses
never overwrite newer state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f6d52a1d-61db-4469-baea-c94533ed0b45

📥 Commits

Reviewing files that changed from the base of the PR and between 7a15543 and 3dbd9ba.

📒 Files selected for processing (3)
  • src/Routes/Router.tsx
  • src/components/Navbar.tsx
  • src/pages/Issues/Issues.tsx

Comment on lines +50 to +90
const fetchIssues = useCallback(async (currentPage: number, currentLanguage: string, currentTag: string, currentOrder: string) => {
setLoading(true);
setError("");

try {
let q = "is:issue is:open";
if (currentLanguage) {
q += ` language:${currentLanguage}`;
}
if (currentTag) {
q += ` label:"${currentTag}"`;
}

const response = await fetch(
`https://api.github.com/search/issues?q=${encodeURIComponent(q)}&sort=created&order=${currentOrder}&per_page=${ROWS_PER_PAGE}&page=${currentPage + 1}`
);

if (!response.ok) {
if (response.status === 403) {
throw new Error("GitHub API rate limit exceeded.");
}
throw new Error("Failed to fetch data");
}

const data = await response.json();
setIssues(data.items);
setTotalIssues(data.total_count > 1000 ? 1000 : data.total_count); // GitHub limits search results to 1000
} catch (err: unknown) {
if (err instanceof Error) {
setError(err.message || "Failed to fetch issues");
} else {
setError("Failed to fetch issues");
}
} finally {
setLoading(false);
}
}, []);

useEffect(() => {
fetchIssues(page, language, tag, sortOrder);
}, [page, language, tag, sortOrder, fetchIssues]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether request cancellation is implemented for Issues fetching.
rg -n --type=tsx -e 'AbortController' -e 'controller\.abort' -e 'signal' -e 'fetchIssues\(' src/pages/Issues/Issues.tsx

Repository: GitMetricsLab/github_tracker

Length of output: 100


🏁 Script executed:

fd -i "issues.tsx" -o -i "issues.ts"

Repository: GitMetricsLab/github_tracker

Length of output: 189


🏁 Script executed:

fd -type f "Issues" src/pages/

Repository: GitMetricsLab/github_tracker

Length of output: 243


🏁 Script executed:

find src/pages/ -name "*Issues*" -type f

Repository: GitMetricsLab/github_tracker

Length of output: 100


🏁 Script executed:

cat src/pages/Issues/Issues.tsx

Repository: GitMetricsLab/github_tracker

Length of output: 7909


Prevent stale results from out-of-order fetch responses.

Multiple in-flight requests can race here; an older response can arrive last and overwrite the latest filter/page state. This happens because rapid filter/page/sort changes trigger new fetchIssues calls via the dependency array [page, language, tag, sortOrder, fetchIssues] without canceling the previous request.

💡 Suggested fix (abort previous request + ignore abort errors)
-  const fetchIssues = useCallback(async (currentPage: number, currentLanguage: string, currentTag: string, currentOrder: string) => {
+  const fetchIssues = useCallback(
+    async (
+      currentPage: number,
+      currentLanguage: string,
+      currentTag: string,
+      currentOrder: string,
+      signal: AbortSignal
+    ) => {
     setLoading(true);
     setError("");
@@
-      const response = await fetch(
-        `https://api.github.com/search/issues?q=${encodeURIComponent(q)}&sort=created&order=${currentOrder}&per_page=${ROWS_PER_PAGE}&page=${currentPage + 1}`
-      );
+      const response = await fetch(
+        `https://api.github.com/search/issues?q=${encodeURIComponent(q)}&sort=created&order=${currentOrder}&per_page=${ROWS_PER_PAGE}&page=${currentPage + 1}`,
+        { signal }
+      );
@@
       const data = await response.json();
+      if (signal.aborted) return;
       setIssues(data.items);
       setTotalIssues(data.total_count > 1000 ? 1000 : data.total_count); // GitHub limits search results to 1000
     } catch (err: unknown) {
+      if (err instanceof DOMException && err.name === "AbortError") return;
       if (err instanceof Error) {
         setError(err.message || "Failed to fetch issues");
       } else {
         setError("Failed to fetch issues");
       }
     } finally {
       setLoading(false);
     }
-  }, []);
+  }, []);
@@
-  useEffect(() => {
-    fetchIssues(page, language, tag, sortOrder);
-  }, [page, language, tag, sortOrder, fetchIssues]);
+  useEffect(() => {
+    const controller = new AbortController();
+    fetchIssues(page, language, tag, sortOrder, controller.signal);
+    return () => controller.abort();
+  }, [page, language, tag, sortOrder, fetchIssues]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const fetchIssues = useCallback(async (currentPage: number, currentLanguage: string, currentTag: string, currentOrder: string) => {
setLoading(true);
setError("");
try {
let q = "is:issue is:open";
if (currentLanguage) {
q += ` language:${currentLanguage}`;
}
if (currentTag) {
q += ` label:"${currentTag}"`;
}
const response = await fetch(
`https://api.github.com/search/issues?q=${encodeURIComponent(q)}&sort=created&order=${currentOrder}&per_page=${ROWS_PER_PAGE}&page=${currentPage + 1}`
);
if (!response.ok) {
if (response.status === 403) {
throw new Error("GitHub API rate limit exceeded.");
}
throw new Error("Failed to fetch data");
}
const data = await response.json();
setIssues(data.items);
setTotalIssues(data.total_count > 1000 ? 1000 : data.total_count); // GitHub limits search results to 1000
} catch (err: unknown) {
if (err instanceof Error) {
setError(err.message || "Failed to fetch issues");
} else {
setError("Failed to fetch issues");
}
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
fetchIssues(page, language, tag, sortOrder);
}, [page, language, tag, sortOrder, fetchIssues]);
const fetchIssues = useCallback(
async (
currentPage: number,
currentLanguage: string,
currentTag: string,
currentOrder: string,
signal: AbortSignal
) => {
setLoading(true);
setError("");
try {
let q = "is:issue is:open";
if (currentLanguage) {
q += ` language:${currentLanguage}`;
}
if (currentTag) {
q += ` label:"${currentTag}"`;
}
const response = await fetch(
`https://api.github.com/search/issues?q=${encodeURIComponent(q)}&sort=created&order=${currentOrder}&per_page=${ROWS_PER_PAGE}&page=${currentPage + 1}`,
{ signal }
);
if (!response.ok) {
if (response.status === 403) {
throw new Error("GitHub API rate limit exceeded.");
}
throw new Error("Failed to fetch data");
}
const data = await response.json();
if (signal.aborted) return;
setIssues(data.items);
setTotalIssues(data.total_count > 1000 ? 1000 : data.total_count); // GitHub limits search results to 1000
} catch (err: unknown) {
if (err instanceof DOMException && err.name === "AbortError") return;
if (err instanceof Error) {
setError(err.message || "Failed to fetch issues");
} else {
setError("Failed to fetch issues");
}
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
const controller = new AbortController();
fetchIssues(page, language, tag, sortOrder, controller.signal);
return () => controller.abort();
}, [page, language, tag, sortOrder, fetchIssues]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/Issues/Issues.tsx` around lines 50 - 90, fetchIssues can race when
multiple requests are in-flight; create an AbortController ref (e.g.,
abortControllerRef) and before starting a new fetch in fetchIssues abort any
existing controller, then create a new controller and pass its signal to fetch;
in the catch block ignore abort errors (check err.name === 'AbortError' or err
instanceof DOMException) and only setError for real failures; also abort any
pending request in the useEffect cleanup (return () =>
abortControllerRef.current?.abort()) so stale responses never overwrite newer
state.

@mehul-m-prajapati
Copy link
Copy Markdown
Collaborator

@isauravanand : pls resolve conflicts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🚀 Feature: Add a page to track all github issues with filters of programming language, labels

2 participants