Add GitHub organization search feature GitHub org search feature#60
Add GitHub organization search feature GitHub org search feature#60coderpurohit wants to merge 5 commits into
Conversation
|
Warning Review limit reached
More reviews will be available in 30 minutes and 56 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThis PR implements a complete GitHub organization explorer application. It adds a type contract and API service layer for fetching organizations, introduces SearchBar and OrgCard React components, integrates state management and orchestration in the App component, applies comprehensive styling, and sets up React Router for the application entry point. ChangesOrganization Search Application
Sequence DiagramssequenceDiagram
participant User
participant SearchBar
participant App
participant fetchOrganization
participant GitHubAPI
participant OrgCard
User->>SearchBar: enter organization name and submit
SearchBar->>App: onSearch(orgName)
App->>App: clear error, setLoading(true)
App->>fetchOrganization: fetchOrganization(orgName)
fetchOrganization->>GitHubAPI: GET /orgs/{orgName}
alt Organization Found
GitHubAPI-->>fetchOrganization: 200 + organization data
fetchOrganization-->>App: GitHubOrg
App->>App: setOrganization(data), setLoading(false)
App->>OrgCard: render with organization
OrgCard-->>User: display avatar, login, description, stats
else Not Found or Rate Limited
GitHubAPI-->>fetchOrganization: 404 or 403
fetchOrganization-->>App: Error
App->>App: setOrganization(null), setError(message), setLoading(false)
App-->>User: display error message
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 13
🤖 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/App.css`:
- Line 9: Stylelint is flagging extra empty lines before CSS declarations in
App.css (e.g., the rule containing "display: flex;" and other declarations at
the lines referenced); fix by removing the blank lines that precede each
declaration so declarations immediately follow their selector or previous
property, or run stylelint --fix to auto-correct; update the selectors/rules
that include "display: flex;" and the other noted declarations so they conform
to the project's Stylelint formatting rules.
In `@src/App.tsx`:
- Line 38: Hardcoded user-facing strings in the App component (the
<h1>OrgExplorer</h1>, the "Loading..." text and the error messages shown in
render) must be moved to i18n resource keys and referenced from code; replace
the literal strings in App (the h1 element and wherever loading/error messages
are rendered) with calls to your localization API (e.g.,
useTranslation()/t('...') or a getString('...') helper) using clear keys like
title.orgExplorer, loading.message, and error.fetchFailed, and add those keys
with appropriate values to the locale resource file(s); update any imports
(e.g., import { useTranslation } from 'react-i18next' or your project
equivalent) and ensure the component uses the translation function to render the
strings.
- Around line 28-30: The catch block swallows the thrown error; update it to
accept and use the error parameter (e.g., catch (err)) so you can log the full
error and provide a more informative message via setError and preserve state
with setOrganization(null); specifically, in the block that currently calls
setOrganization(null) and setError('Organization not found'), change it to
capture the error object, call console.error or a logger with err (or
err.message), and setError to include a clearer diagnostic (e.g., include
err.message or a mapped user-facing message) while still calling
setOrganization(null).
In `@src/components/orgcard.tsx`:
- Line 20: The hardcoded user-facing labels in the OrgCard component (e.g., the
JSX lines rendering "Followers:", "Public Repositories:" and "Visit GitHub
Profile") must be externalized for i18n; replace those literal strings in the
OrgCard (component/function name: OrgCard or OrganizationCard where it renders
organization.followers, organization.public_repos and the GitHub link) with
lookups to the localization resource (e.g., import a locale/strings object or
use the app's t() translator) and update the JSX to use those keys (followers,
publicRepositories, visitGitHubProfile), ensuring the organization props remain
unchanged.
- Around line 10-14: The img element rendering organization.avatar_url is
missing a height attribute which can cause layout shift; update the OrgCard
component (the JSX containing <img src={organization.avatar_url}
alt={organization.login} width={120} />) to include a matching height attribute
(or explicit aspect-ratio-preserving dimensions) so width and height are both
set (or computed from known avatar dimensions) to prevent CLS.
- Line 18: The organization description may be null/undefined and currently
renders literal "null"/"undefined"; update the OrgCard component in
src/components/orgcard.tsx to guard rendering of organization.description (the
organization object and its description property) and provide a fallback string
or omit the element—e.g., conditionally render the <p> only when
organization.description is truthy or render organization.description ?? 'No
description provided'—so the UI never shows "null" or "undefined".
In `@src/components/serachbar.tsx`:
- Line 25: The hardcoded user-facing strings in the SearchBar component
(placeholder="Enter GitHub organization" and the button label) must be
externalized for i18n; add a localization resource/constant (or use
react-i18next) and replace the literal placeholder and button text in the
serachbar.tsx component with references to those localized keys (e.g.,
t('search.placeholder') or LOCAL_STRINGS.SEARCH_PLACEHOLDER) and ensure the
component imports and uses the localization helper (hook or constants) so both
the input placeholder and the button label are driven from the resource file.
- Around line 1-35: The component file has a typo in its filename
("serachbar.tsx"); rename the file to "searchbar.tsx" so the module name matches
the exported component SearchBar, and update the import statement in App.tsx
that currently imports SearchBar to reference the corrected filename; ensure any
other imports/exports referencing "serachbar" are updated to "searchbar" to
avoid module resolution errors.
In `@src/main.tsx`:
- Around line 10-12: Remove the unused BrowserRouter wrapper around App: delete
the BrowserRouter element and its import from main.tsx so App is rendered
directly (remove any "BrowserRouter" import and JSX). Also remove the
react-router-dom dependency from the project manifest and lockfile (uninstall
react-router-dom with your package manager and update package.json/package-lock
or yarn.lock accordingly) to avoid unused dependency warnings.
In `@src/services/githubapi.ts`:
- Line 11: The hardcoded user-facing error string "Organization not found" must
be externalized for i18n: replace the inline throw new Error('Organization not
found') in src/services/githubapi.ts with a throw new Error(...) that uses your
localization/resource lookup (e.g., call the project's i18n translate function
or import the errors resource and use a key like errors.organizationNotFound);
ensure you import the localization helper at the top (e.g., i18n or t) and
reference the resource key instead of the literal string, and update any unit
tests or callers that assert on this exact message to use the localized key or
compare error codes where appropriate.
- Around line 10-12: Replace the generic error thrown when response.ok is false
with explicit handling of response.status in the fetch/org call: inspect
response.status from the code block that contains the `if (!response.ok)` check
and throw distinct errors/messages for 404 (throw "Organization not found"), 429
(throw "Rate limited by GitHub" and surface retry info/Retry-After header),
401/403 (throw "Authentication/permission error" with status), and 5xx (throw
"GitHub server error" including status); keep a fallback that includes status
and response text for any other unexpected codes so debugging has full context.
- Line 7: The orgName is interpolated directly into the GitHub API URL; update
the interpolation to pass orgName through encodeURIComponent to defensively
escape any unexpected characters (i.e., replace occurrences of
`https://api.github.com/orgs/${orgName}` with a version that uses
`encodeURIComponent(orgName)`), ensuring the URL-building code in
src/services/githubapi.ts uses the encoded orgName wherever that template string
or the orgName variable is used.
In `@src/types/github.ts`:
- Line 4: The GitHub organization type marks the description property as
non-nullable; update the declaration for the description field from string to
allow null (e.g., change the description property in the type/interface that
currently reads "description" to accept string | null) so the API contract
matches GitHub's "string or null" behavior and downstream consumers handle null
values correctly.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: da1499f7-b2ce-42c1-855c-cf8b0d15d4ef
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (9)
package.jsonsrc/App.csssrc/App.tsxsrc/components/orgcard.tsxsrc/components/serachbar.tsxsrc/index.csssrc/main.tsxsrc/services/githubapi.tssrc/types/github.ts
| min-height: 100vh; | ||
| min-height: 100dvh; | ||
|
|
||
| display: flex; |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | 💤 Low value
Address Stylelint formatting warnings.
Stylelint is flagging empty lines before declarations throughout the file. While these are minor style issues, consider running stylelint --fix to auto-correct them for consistency with your project's linting rules.
Also applies to: 13-13, 15-15, 34-34, 37-37, 43-43, 46-46, 48-48, 55-55, 57-57, 59-59, 61-61
🧰 Tools
🪛 Stylelint (17.11.0)
[error] 9-9: Expected no empty line before declaration (declaration-empty-line-before)
(declaration-empty-line-before)
🤖 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/App.css` at line 9, Stylelint is flagging extra empty lines before CSS
declarations in App.css (e.g., the rule containing "display: flex;" and other
declarations at the lines referenced); fix by removing the blank lines that
precede each declaration so declarations immediately follow their selector or
previous property, or run stylelint --fix to auto-correct; update the
selectors/rules that include "display: flex;" and the other noted declarations
so they conform to the project's Stylelint formatting rules.
| <h1>Hello, OrgExplorer!</h1> | ||
| </> | ||
| <div className="app-container"> | ||
| <h1>OrgExplorer</h1> |
There was a problem hiding this comment.
Externalize user-facing strings for internationalization.
The title "OrgExplorer", loading message "Loading...", and error messages are hardcoded. As per coding guidelines, user-visible strings should be externalized to resource files for i18n support.
Also applies to: 42-42, 44-44
🤖 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/App.tsx` at line 38, Hardcoded user-facing strings in the App component
(the <h1>OrgExplorer</h1>, the "Loading..." text and the error messages shown in
render) must be moved to i18n resource keys and referenced from code; replace
the literal strings in App (the h1 element and wherever loading/error messages
are rendered) with calls to your localization API (e.g.,
useTranslation()/t('...') or a getString('...') helper) using clear keys like
title.orgExplorer, loading.message, and error.fetchFailed, and add those keys
with appropriate values to the locale resource file(s); update any imports
(e.g., import { useTranslation } from 'react-i18next' or your project
equivalent) and ensure the component uses the translation function to render the
strings.
| if (!response.ok) { | ||
| throw new Error('Organization not found') | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
For GitHub REST API organization endpoint /orgs/{org}, which HTTP status codes are returned for not found, rate limit exceeded, and forbidden/auth-related failures?
💡 Result:
For GitHub REST API endpoint GET /orgs/{org} (organization endpoint): 1) Not found - 404 Not Found (resource not found) [1] 2) Rate limit exceeded - 403 Forbidden (rate limit exceeded) or 429 Too Many Requests (rate limit exceeded) [2][3] 3) Forbidden / auth-related failures - 401 Requires authentication [1] - 403 Forbidden (forbidden; includes insufficient scope / authz) [1][4] Notes on how GitHub signals auth vs existence: - GitHub may return 404 Not Found instead of 403 Forbidden in some authentication scenarios (to avoid confirming the existence of private resources). [5]
Citations:
- 1: https://docs.github.com/en/rest/orgs/orgs?apiVersion=2026-03-10
- 2: https://docs.github.com/en/rest/orgs/orgs?apiVersion=2022-11-28
- 3: https://docs.github.com/en/rest/orgs
- 4: https://docs.github.com/rest/orgs/orgs
- 5: https://gist.github.com/IaroslavR/cf3de7efe581fa483d9fa661cadebb14
🏁 Script executed:
# First, locate and read the githubapi.ts file
fd -t f -i githubapi.tsRepository: AOSSIE-Org/OrgExplorer
Length of output: 92
🏁 Script executed:
# Read the githubapi.ts file to inspect lines 10-12 and surrounding context
cat -n src/services/githubapi.ts | head -30Repository: AOSSIE-Org/OrgExplorer
Length of output: 487
Handle HTTP status codes explicitly instead of mapping all failures to "Organization not found".
The current code treats 404 (not found), 403 (forbidden), 429 (rate limit), 401 (authentication), and 5xx (server errors) identically, which provides incorrect user feedback and complicates debugging. Differentiate between status codes: 404 for missing organizations, 429 for rate limits, 403/401 for authentication issues, and 5xx for server failures.
🤖 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/services/githubapi.ts` around lines 10 - 12, Replace the generic error
thrown when response.ok is false with explicit handling of response.status in
the fetch/org call: inspect response.status from the code block that contains
the `if (!response.ok)` check and throw distinct errors/messages for 404 (throw
"Organization not found"), 429 (throw "Rate limited by GitHub" and surface retry
info/Retry-After header), 401/403 (throw "Authentication/permission error" with
status), and 5xx (throw "GitHub server error" including status); keep a fallback
that includes status and response text for any other unexpected codes so
debugging has full context.
| ) | ||
|
|
||
| if (!response.ok) { | ||
| throw new Error('Organization not found') |
There was a problem hiding this comment.
Externalize this user-facing error string for i18n.
On Line 11, the hardcoded message should come from localization resources instead of inline text.
As per coding guidelines "Internationalization: User-visible strings should be externalized to resource files (i18n)".
🤖 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/services/githubapi.ts` at line 11, The hardcoded user-facing error string
"Organization not found" must be externalized for i18n: replace the inline throw
new Error('Organization not found') in src/services/githubapi.ts with a throw
new Error(...) that uses your localization/resource lookup (e.g., call the
project's i18n translate function or import the errors resource and use a key
like errors.organizationNotFound); ensure you import the localization helper at
the top (e.g., i18n or t) and reference the resource key instead of the literal
string, and update any unit tests or callers that assert on this exact message
to use the localized key or compare error codes where appropriate.
|
Hi @Zahnentferner I’ve addressed all the requested changes and updated the PR. Please review whenever you get time. Thanks! |
|
@coderpurohit share any visuals that demonstrates your work. |
aos1.mp4Thank you for reviewing the PR @rahul-vyas-dev I’ve attached visuals demonstrating the implemented GitHub organization search workflow, including organization lookup using the GitHub API, organization details rendering, GitHub profile navigation, and error handling for invalid organizations. Please let me know if any additional demonstrations or changes are required. |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/App.tsx (1)
20-39:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPrevent stale search responses from overwriting newer results.
Concurrent submissions can resolve out of order, causing older results/errors to replace the latest search state.
Suggested fix
-import { useState } from 'react' +import { useRef, useState } from 'react' @@ const [error, setError] = useState('') + const latestRequestId = useRef(0) async function handleSearch(orgName: string) { + const requestId = ++latestRequestId.current try { setLoading(true) setError('') @@ const data = await fetchOrganization(orgName) + if (requestId !== latestRequestId.current) return setOrganization(data) } catch (error) { + if (requestId !== latestRequestId.current) return setOrganization(null) @@ } finally { - setLoading(false) + if (requestId === latestRequestId.current) { + setLoading(false) + } } }🤖 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/App.tsx` around lines 20 - 39, handleSearch can have out-of-order async responses overwrite newer state; add a request identifier or abort logic to ignore stale responses: create a module-level or component ref like latestRequestId (or use AbortController) that you increment/set before awaiting fetchOrganization(orgName), then after the await check that the current id/controller still matches before calling setOrganization/setError/setLoading; ensure any catch/finally paths also verify the id (or that the fetch wasn't aborted) so only the latest request updates state (reference handleSearch and fetchOrganization to locate where to apply this).
🤖 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/services/githubapi.ts`:
- Around line 14-20: The 403 handling in src/services/githubapi.ts currently
always throws "GitHub API rate limit exceeded"; update the branch that checks
response.status === 403 to distinguish a true rate-limit from an
auth/permission/abuse 403 by inspecting response headers/body (e.g., check
response.headers.get('x-ratelimit-remaining') === '0', presence of rate-limit
headers like 'x-ratelimit-reset' or a response.json().message containing "rate
limit") and throw distinct errors (e.g., a rate-limit error vs a forbidden/auth
error). Replace hardcoded thrown strings ("GitHub API rate limit exceeded" and
"Something went wrong") with i18n resource keys / calls (e.g., using the app's
translate function) so App.tsx receives localized error keys/messages instead of
raw English text; keep the thrown Error types/messages descriptive but sourced
from i18n rather than literals.
---
Outside diff comments:
In `@src/App.tsx`:
- Around line 20-39: handleSearch can have out-of-order async responses
overwrite newer state; add a request identifier or abort logic to ignore stale
responses: create a module-level or component ref like latestRequestId (or use
AbortController) that you increment/set before awaiting
fetchOrganization(orgName), then after the await check that the current
id/controller still matches before calling setOrganization/setError/setLoading;
ensure any catch/finally paths also verify the id (or that the fetch wasn't
aborted) so only the latest request updates state (reference handleSearch and
fetchOrganization to locate where to apply this).
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: d7640f90-a38e-4ec1-81ee-f4352b82a0af
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (6)
src/App.tsxsrc/components/orgcard.tsxsrc/components/searchbar.tsxsrc/main.tsxsrc/services/githubapi.tssrc/types/github.ts
💤 Files with no reviewable changes (1)
- src/components/searchbar.tsx
Implemented the GitHub organization search feature using the GitHub API.
Changes made:
Tested locally with multiple organizations and verified build/lint checks.
Summary by CodeRabbit