-
-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add git contributors page #397
Conversation
@shubhagarwal1 is attempting to deploy a commit to the bunty's projects Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughThis pull request introduces a new React component, Changes
Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Thank you for submitting your pull request! 🙌 We'll review it as soon as possible. In the meantime, please ensure that your changes align with our CONTRIBUTING.md. If there are any specific instructions or feedback regarding your PR, we'll provide them here. Thanks again for your contribution! 😊 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (4)
- frontend/package.json (1 hunks)
- frontend/src/components/Contributors.jsx (1 hunks)
- frontend/src/components/Shared/Navbar.jsx (1 hunks)
- frontend/src/router/index.jsx (2 hunks)
🔇 Additional comments (6)
frontend/package.json (2)
27-27
: Review icon library strategy.The project already includes
react-icons
. Consider whether maintaining two icon libraries (react-icons
andlucide-react
) is necessary, as this increases bundle size and maintenance overhead.#!/bin/bash # Check current usage of react-icons in the codebase rg -l "react-icons" # Check if lucide-react is only used in the new Contributors component rg -l "lucide-react"
27-27
: Consider pinning the exact version of lucide-react.The caret (^) with a pre-1.0 version (0.x.x) allows minor version updates which could introduce breaking changes. Consider using an exact version number to ensure stability.
✅ Verification successful
Let me check the actual usage of both icon libraries to make a more informed decision.
The addition of lucide-react is appropriate and well-scoped
The package is only used in the new Contributors component for specific icons (Github, Loader2) that might not be available in react-icons. Both icon libraries serve different purposes and their usage is well-segregated across components, with no unnecessary duplication.
Regarding version pinning, while it's a pre-1.0 version, the limited scope of usage (just two icons in a single new component) minimizes the risk of breaking changes affecting the application.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check if there are any breaking changes in recent versions npm view lucide-react versions --json | jq -r '.[] | select(startswith("0.45"))'Length of output: 515
Script:
#!/bin/bash # Check react-icons usage patterns rg "from 'react-icons'" -A 1 # Check lucide-react usage patterns rg "from 'lucide-react'" -A 1Length of output: 205
frontend/src/router/index.jsx (2)
46-46
: Consider security and configuration for the contributors page.While the route implementation is correct, consider the following architectural recommendations:
- If the repository details are configurable, consider passing them as route state or URL parameters instead of hardcoding them in the component.
- Consider implementing rate limiting or caching for GitHub API calls to prevent abuse.
- Evaluate if this route should be protected or if public access to contributor information aligns with your security requirements.
Let's check if there are any authentication patterns in use:
#!/bin/bash # Description: Check for authentication patterns in the router # Expected: Find protected routes or auth middleware if they exist # Test 1: Look for auth-related route protection patterns rg -l "auth|protect|private|restricted" src/
25-25
: Verify the Contributors component implementation.The import statement follows the project's conventions.
Let's verify the component exists and is exported correctly:
✅ Verification successful
Component implementation verified successfully ✅
The Contributors component exists at
frontend/src/components/Contributors.jsx
and is properly implemented as a functional component with the correct export. The component includes state management for contributors and loading states.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the Contributors component exists and is properly exported # Expected: Find the component definition and default export # Test 1: Check if the file exists fd -t f "Contributors.jsx" src/components # Test 2: Verify the component implementation ast-grep --pattern 'export default function Contributors' || ast-grep --pattern 'const Contributors = 'Length of output: 257
Script:
#!/bin/bash # Let's try a more comprehensive verification with correct paths and patterns # Test 1: Find the Contributors component file fd -t f "Contributors" frontend/src/components # Test 2: Check for component implementation using ripgrep rg -l "Contributors" frontend/src/components # Test 3: Look for default export patterns rg "export.*Contributors" frontend/src/components -A 2 # Test 4: Check for any React component patterns in potential files rg "function Contributors|const Contributors" frontend/src/components -A 2Length of output: 633
frontend/src/components/Shared/Navbar.jsx (2)
23-23
: Consider authentication requirements for the Contributors page.Since this is adding access to a new feature, consider whether the Contributors page should be accessible to all users or only authenticated users. If authentication is required, the menu item should be conditionally rendered based on the
token
state, similar to the login/logout buttons.Let's check if other routes use authentication:
#!/bin/bash # Description: Check for authentication patterns in routes # Test: Look for authentication checks in route definitions ast-grep --pattern 'token|isAuthenticated|auth'
23-23
: LGTM! Verify route configuration.The new menu item follows the existing pattern and maintains consistency with other navigation items.
Let's verify the route configuration:
✅ Verification successful
Route configuration is properly implemented
The Contributors route is correctly configured in
frontend/src/router/index.jsx
and follows the same pattern as other public routes in the application. The component is properly imported and the route path matches the navbar link.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check if the Contributors route is properly configured # Test: Search for route configuration for /contributors path rg -l "path.*['\"]\/contributors['\"]" --type jsx --type tsxLength of output: 143
Script:
#!/bin/bash # Search for route configurations in the codebase rg -A 3 "Route.*path.*=.*['\"]\/contributors['\"]" --type jsx --type tsx # Search for any file that might contain the Contributors component fd -e jsx -e tsx -e js -e ts "Contributors" # Search for router configuration files fd -e jsx -e tsx -e js -e ts "router|routes" -ILength of output: 531
Script:
#!/bin/bash # Let's check the App.jsx or similar files for route configuration fd -e jsx -e tsx "App|Layout" -d 2 # Then check the content of these files and the Contributors component rg -A 3 "Route.*path.*=.*['\"]/" --type jsx --type tsx # Check the Contributors component implementation cat frontend/src/components/Contributors.jsxLength of output: 5866
Script:
#!/bin/bash # Let's try a different approach to find route configurations rg -l "Route.*path.*contributors" --type-add 'frontend:*.{jsx,tsx,js,ts}' --type frontend # Also check for router setup in the main App or index files fd "^(App|index|main)\.(jsx|tsx|js|ts)$" frontend/srcLength of output: 250
Script:
#!/bin/bash # Let's check the router configuration file cat frontend/src/router/index.jsx # And verify if there are any authentication wrappers or protected routes rg -A 3 "ProtectedRoute|isAuthenticated|auth" frontend/src/router/index.jsxLength of output: 2284
import React, { useState, useEffect } from 'react'; | ||
import { Github, Loader2 } from 'lucide-react'; | ||
|
||
const Contributors = () => { | ||
const [contributors, setContributors] = useState([]); | ||
const [loading, setLoading] = useState(true); | ||
const [error, setError] = useState(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider adding PropTypes or TypeScript for better type safety.
While the component's state management is well-structured, adding type definitions would improve code maintainability and catch potential runtime errors during development.
Consider converting to TypeScript or adding PropTypes:
interface Contributor {
id: number;
login: string;
avatar_url: string;
html_url: string;
contributions: number;
name?: string;
bio?: string;
location?: string;
company?: string;
}
interface ContributorsState {
contributors: Contributor[];
loading: boolean;
error: string | null;
}
{loading ? ( | ||
<div className="flex justify-center items-center py-12"> | ||
<Loader2 className="w-8 h-8 animate-spin text-blue-500" /> | ||
</div> | ||
) : ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve accessibility and loading states.
While the UI is well-structured, it needs accessibility improvements and could benefit from a better loading experience.
Consider these improvements:
{loading ? (
<div className="flex justify-center items-center py-12">
- <Loader2 className="w-8 h-8 animate-spin text-blue-500" />
+ <Loader2
+ className="w-8 h-8 animate-spin text-blue-500"
+ aria-label="Loading contributors"
+ role="status"
+ />
+ <span className="sr-only">Loading contributors</span>
</div>
) : (
// ...
)}
<img
src={contributor.avatar_url}
alt={contributor.login}
- className="w-12 h-12 rounded-full"
+ className="w-12 h-12 rounded-full"
+ loading="lazy"
+ aria-label={`${contributor.name || contributor.login}'s avatar`}
/>
Also consider implementing skeleton loading for a better user experience:
const SkeletonLoader = () => (
<div className="space-y-3">
{[...Array(5)].map((_, i) => (
<div key={i} className="animate-pulse flex items-center bg-white dark:bg-gray-800 rounded-lg p-4">
<div className="w-12 h-12 bg-gray-200 dark:bg-gray-700 rounded-full" />
<div className="ml-4 space-y-2 flex-1">
<div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/4" />
<div className="h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/2" />
</div>
</div>
))}
</div>
);
Also applies to: 89-93
{contributor.bio && <p>{contributor.bio}</p>} | ||
{contributor.location && ( | ||
<p className="text-gray-500 dark:text-gray-400 mt-1"> | ||
📍 {contributor.location} | ||
</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure proper content sanitization for user-provided data.
User-provided content (bio, location) is being rendered directly, which could potentially lead to XSS attacks.
Consider using a sanitization library:
+import DOMPurify from 'dompurify';
-{contributor.bio && <p>{contributor.bio}</p>}
+{contributor.bio && <p>{DOMPurify.sanitize(contributor.bio)}</p>}
-{contributor.location && <p className="text-gray-500 dark:text-gray-400 mt-1">📍 {contributor.location}</p>}
+{contributor.location && <p className="text-gray-500 dark:text-gray-400 mt-1">📍 {DOMPurify.sanitize(contributor.location)}</p>}
Also, ensure your Content Security Policy (CSP) is configured to allow GitHub API requests and avatar images.
Committable suggestion was skipped due to low confidence.
const contributorsWithDetails = await Promise.all( | ||
data.map(async (contributor) => { | ||
const userResponse = await fetch(contributor.url); | ||
const userData = await userResponse.json(); | ||
return { | ||
...contributor, | ||
name: userData.name || userData.login, | ||
bio: userData.bio, | ||
location: userData.location, | ||
company: userData.company | ||
}; | ||
}) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Optimize contributor details fetching.
The current implementation makes N+1 API calls, which is inefficient and could hit rate limits quickly.
Consider batching the requests or limiting the number of contributors shown:
-const contributorsWithDetails = await Promise.all(
- data.map(async (contributor) => {
- const userResponse = await fetch(contributor.url);
- const userData = await userResponse.json();
- return {
- ...contributor,
- name: userData.name || userData.login,
- bio: userData.bio,
- location: userData.location,
- company: userData.company
- };
- })
-);
+// Limit to top 10 contributors to reduce API calls
+const topContributors = data.slice(0, 10);
+const contributorsWithDetails = await Promise.all(
+ topContributors.map(async (contributor) => {
+ const userResponse = await fetch(contributor.url, {
+ signal: controller.signal,
+ headers: {
+ 'Authorization': `token ${process.env.REACT_APP_GITHUB_TOKEN}`,
+ }
+ });
+ const userData = await userResponse.json();
+ return {
+ ...contributor,
+ name: userData.name || userData.login,
+ bio: userData.bio,
+ location: userData.location,
+ company: userData.company
+ };
+ })
+);
Committable suggestion was skipped due to low confidence.
if (error) { | ||
return ( | ||
<div className="min-h-screen bg-gray-50 dark:bg-gray-900 py-12 px-4"> | ||
<div className="max-w-3xl mx-auto text-center"> | ||
<div className="bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 p-4 rounded-lg"> | ||
Error loading contributors: {error} | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance error handling with specific error cases and retry mechanism.
The current error handling is basic and could be more informative to users.
Consider implementing more specific error handling:
if (error) {
return (
<div className="min-h-screen bg-gray-50 dark:bg-gray-900 py-12 px-4">
<div className="max-w-3xl mx-auto text-center">
- <div className="bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 p-4 rounded-lg">
- Error loading contributors: {error}
+ <div className="bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 p-4 rounded-lg space-y-4">
+ <p>{error.includes('rate limit') ? 'GitHub API rate limit exceeded. Please try again later.' : 'Failed to load contributors.'}</p>
+ <button
+ onClick={() => {
+ setError(null);
+ fetchContributors();
+ }}
+ className="px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700"
+ >
+ Retry
+ </button>
</div>
</div>
</div>
);
}
Committable suggestion was skipped due to low confidence.
useEffect(() => { | ||
const fetchContributors = async () => { | ||
try { | ||
setLoading(true); | ||
const response = await fetch('https://api.github.com/repos/RamakrushnaBiswal/PlayCafe/contributors'); | ||
if (!response.ok) { | ||
throw new Error('Failed to fetch contributors'); | ||
} | ||
const data = await response.json(); | ||
|
||
// Fetch additional user details for each contributor | ||
const contributorsWithDetails = await Promise.all( | ||
data.map(async (contributor) => { | ||
const userResponse = await fetch(contributor.url); | ||
const userData = await userResponse.json(); | ||
return { | ||
...contributor, | ||
name: userData.name || userData.login, | ||
bio: userData.bio, | ||
location: userData.location, | ||
company: userData.company | ||
}; | ||
}) | ||
); | ||
|
||
setContributors(contributorsWithDetails); | ||
setError(null); | ||
} catch (err) { | ||
setError(err.message); | ||
} finally { | ||
setLoading(false); | ||
} | ||
}; | ||
|
||
fetchContributors(); | ||
}, []); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add API rate limiting protection and environment configuration.
Several potential issues in the data fetching logic:
- Multiple API calls could hit GitHub's rate limits
- Hardcoded repository URL should be configurable
- Missing cleanup for unmounted component
- No caching strategy for contributor data
Consider these improvements:
useEffect(() => {
+ const controller = new AbortController();
const fetchContributors = async () => {
try {
setLoading(true);
- const response = await fetch('https://api.github.com/repos/RamakrushnaBiswal/PlayCafe/contributors');
+ const response = await fetch(`${process.env.REACT_APP_GITHUB_API_URL}/repos/${process.env.REACT_APP_REPO_OWNER}/${process.env.REACT_APP_REPO_NAME}/contributors`, {
+ signal: controller.signal,
+ headers: {
+ 'Authorization': `token ${process.env.REACT_APP_GITHUB_TOKEN}`,
+ }
+ });
// ... rest of the code
}
};
fetchContributors();
+ return () => controller.abort();
}, []);
Also consider implementing a caching strategy using React Query or SWR to prevent unnecessary API calls.
Committable suggestion was skipped due to low confidence.
@shubhagarwal1 add the contributors button in footer and resolve coderabbit changes |
Hey @RamakrushnaBiswal, i will add the bhtton the footer but as you can see as many changes i do the coderabbit will still suggest the changes please dont got that way . |
@shubhagarwal1 resolve the conflicts |
This PR has been automatically closed due to inactivity from the owner for 3 days. |
fix: #341
hey @RamakrushnaBiswal please review my PR
Summary by CodeRabbit
New Features
Contributors
component that fetches and displays a list of contributors from a specified GitHub repository.Contributors
component, accessible via/contributors
.Bug Fixes
Contributors
component.