Skip to content

Conversation

@aysahoo
Copy link
Collaborator

@aysahoo aysahoo commented Jul 16, 2025

go to /homepage then cmd+k
will update the homepage code with time

Summary by CodeRabbit

  • New Features

    • Introduced a new homepage with a dark-themed hero section, featured open source projects, and interactive voting animations.
    • Added a searchable project listing modal with keyboard shortcuts, accessible navigation, and real-time project data, including repository stats and badges.
  • Style

    • Implemented a new floating animation effect for interactive elements.

@vercel
Copy link

vercel bot commented Jul 16, 2025

@aysahoo is attempting to deploy a commit to the bruvimtired-pro Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Jul 16, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Two new React components were added: one implements a homepage with featured open source launches and animated voting, and the other provides an accessible, interactive modal for searching projects with debounced queries and keyboard shortcuts. Additionally, a new CSS keyframe animation for floating effects was introduced.

Changes

File(s) Change Summary
apps/web/app/(public)/homepage/page.tsx Added a new default exported Homepage React component with hero, featured launches, and animated voting.
apps/web/components/search-comp.tsx Added a new default exported Search React component for searchable project listing modal with accessibility.
apps/web/app/globals.css Added new floatUp keyframe animation and commented out old float animation.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Homepage
    participant SearchModal
    participant Backend

    User->>Homepage: Visit homepage
    Homepage->>User: Render hero and featured launches
    User->>Homepage: Click "Vote" on a launch
    Homepage->>Homepage: Trigger floating triangle animation

    User->>SearchModal: Press Cmd/Ctrl+K
    SearchModal->>User: Open search modal
    User->>SearchModal: Type search query
    SearchModal->>Backend: Fetch search results (debounced)
    Backend-->>SearchModal: Return project results
    SearchModal->>User: Display results, allow navigation
    User->>SearchModal: Select project or close modal
    SearchModal->>User: Update UI or close modal
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

In the warren of code, new features appear,
A homepage with launches, and voting with cheer!
Search hops to action with keyboard in paw,
Debounced and accessible, it leaves us in awe.
Triangles float upward, a CSS delight—
This bunny approves: the changes feel right! 🐇✨

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 3

🧹 Nitpick comments (1)
apps/web/components/search-comp.tsx (1)

69-72: Improve empty state message for short search queries.

When the query length is less than 3 characters, the component renders an empty string, leaving users without feedback. Consider providing a helpful message instead.

-          {query.length < 3
-            ? ''
-            : `No projects match "${query}". Try different keywords or check your spelling.`}
+          {query.length < 3
+            ? 'Type at least 3 characters to search'
+            : `No projects match "${query}". Try different keywords or check your spelling.`}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f0ef50 and 39906a8.

📒 Files selected for processing (3)
  • .vscode/settings.json (1 hunks)
  • apps/web/app/(public)/homepage/page.tsx (1 hunks)
  • apps/web/components/search-comp.tsx (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/web/components/search-comp.tsx (2)
packages/db/src/schema/projects.ts (1)
  • project (16-64)
packages/ui/src/components/link.tsx (1)
  • Link (17-44)
🔇 Additional comments (3)
.vscode/settings.json (1)

4-7: LGTM! Clean formatting changes.

The removal of the trailing comma and single-line array formatting improve consistency without affecting functionality.

apps/web/components/search-comp.tsx (2)

119-131: Good caching strategy for repository metadata.

The long cache times (12-24 hours) are appropriate for repository metadata that doesn't change frequently, reducing unnecessary API calls.


347-351: Excellent accessibility implementation!

The search component includes comprehensive ARIA attributes for screen readers, proper role assignments, and keyboard navigation support.

Also applies to: 372-374

Comment on lines +226 to +230
approvalStatus: 'approved',
page: 1,
pageSize: 6,
sortBy: 'recent',
}),
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider server-side filtering for pinned projects.

The current implementation fetches 6 projects and then filters for isPinned client-side, which could result in fewer results than expected if not all fetched projects are pinned.

Consider adding an isPinned filter parameter to the API query to ensure you get the desired number of pinned projects:

    ...trpc.projects.getProjects.queryOptions({
      approvalStatus: 'approved',
+     isPinned: true,
      page: 1,
      pageSize: 6,
      sortBy: 'recent',
    }),

Then remove the client-side filtering on line 262:

-  const pinnedProjects = pinnedProjectsData?.data?.filter((project) => project.isPinned) || [];
+  const pinnedProjects = pinnedProjectsData?.data || [];

Also applies to: 262-262

🤖 Prompt for AI Agents
In apps/web/components/search-comp.tsx around lines 226 to 230 and line 262, the
code fetches 6 projects and filters pinned projects client-side, which may yield
fewer results than expected. Modify the API query to include an isPinned filter
parameter so the server returns only pinned projects, ensuring the correct
number of results. Then remove the client-side filtering on line 262 to avoid
redundant filtering.

Copy link

@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

🧹 Nitpick comments (2)
apps/web/app/(public)/homepage/page.tsx (2)

9-46: Consider improvements to mock data structure.

The mock data serves its purpose, but consider these enhancements:

  1. Vote counts are stored as strings ('2.7K', '1.9K') which could complicate numeric sorting if needed
  2. For better organization, consider moving this data to a separate constants file

If numeric operations on votes are needed, consider storing both display and numeric values:

const featuredLaunches = [
  {
    id: 1,
    name: 'Zeitworld',
    shortDescription: 'Ship websites faster.',
    longDescription: 'Ship better websites. Faster. Build and deploy with modern tools.',
-   votes: '2.7K',
+   votes: '2.7K',
+   voteCount: 2700,
  },
  // ... rest of items
] as const;

109-201: Consider accessibility improvements for triangle symbols.

The featured launches section is well-implemented with good responsive design, but consider accessibility enhancements:

Replace unicode triangle symbols with proper semantic elements or add aria-labels:

- <span className="text-xs sm:text-sm">▲</span>
+ <span className="text-xs sm:text-sm" aria-label="upvote">▲</span>

And for floating triangles:

- <span className="text-xs text-cyan-400 sm:text-sm">▲</span>
+ <span className="text-xs text-cyan-400 sm:text-sm" aria-hidden="true">▲</span>

Also consider adding proper button aria-labels:

<Button
  variant="outline"
  size="sm"
  onClick={() => handleVoteClick(launch.id)}
+ aria-label={`Vote for ${launch.name}`}
  className="flex h-6 items-center gap-0.5..."
>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff3926e and 077f0c8.

⛔ Files ignored due to path filters (1)
  • apps/web/public/sunshine1.png is excluded by !**/*.png
📒 Files selected for processing (2)
  • apps/web/app/(public)/homepage/page.tsx (1 hunks)
  • apps/web/app/globals.css (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/web/app/globals.css
🧰 Additional context used
🧠 Learnings (1)
apps/web/app/(public)/homepage/page.tsx (1)

Learnt from: Vicentesan
PR: #18
File: apps/web/app/(public)/page.tsx:7-15
Timestamp: 2025-06-13T17:21:40.703Z
Learning: Landing-page sections intentionally omit relative on the parent of the absolutely-positioned background <Image> so the image anchors to the viewport, becoming the header’s global backdrop.

🧬 Code Graph Analysis (1)
apps/web/app/(public)/homepage/page.tsx (2)
packages/ui/src/components/button.tsx (1)
  • Button (56-56)
packages/ui/src/components/link.tsx (1)
  • Link (17-44)
🔇 Additional comments (3)
apps/web/app/(public)/homepage/page.tsx (3)

1-7: LGTM: Imports are well-organized and appropriate.

The imports are correctly structured with the 'use client' directive at the top, and all dependencies are relevant to the component's functionality.


69-107: LGTM: Well-structured hero section with good responsive design.

The hero section implementation is solid:

  • Proper semantic HTML structure with h1 heading
  • Responsive design using Tailwind breakpoints
  • Creative use of CSS blend modes for the background effect
  • Event tracking properly implemented on the CTA button
  • Good accessibility with descriptive text and proper link structure

166-181: floatUp Keyframes Animation Confirmed

The floatUp animation is defined in apps/web/app/globals.css:

  • Located at @keyframes floatUp in apps/web/app/globals.css
  • Keyframes cover 0%, 50%, and 100% transforms and opacity

With the animation present, the floating triangle implementation is solid—proper staggering, positioning, and React key usage are all in place. Approved.

@ahmetskilinc ahmetskilinc marked this pull request as draft July 27, 2025 00:16
ahmetskilinc and others added 13 commits July 27, 2025 01:40
* added the pending feature to the profile page

* refactored the code a bit:removed redundant approvalStatus assignment (defaults to 'pending')

* refactor:fixed a problem in code

* small-fixes

---------

Co-authored-by: Ayush Ranjan Sahoo <77970726+aysahoo@users.noreply.github.com>
* project-ogimage

* add cache headers

---------

Co-authored-by: Ahmet Kilinc <akx9@icloud.com>
* Fix: improved the sortby_stars_forks_name

improved the sortby_stars_forks_name

* done code refractor
…ute#170)

* fix:issue  collabute#160 profile page contribution not working

* bug:fix Removed redundant client-side filtering
Comment on lines +173 to +175
onError={(e) => {
e.currentTarget.src = `https://ui-avatars.com/api/?name=${encodeURIComponent(repoData.owner.login)}&size=160`;
}}
Copy link

Choose a reason for hiding this comment

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

The onError handler in the JSX img element will not work in server-side ImageResponse generation, potentially causing avatar fallback failures.

View Details
📝 Patch Details
diff --git a/apps/web/app/api/og-image/[provider]/[owner]/[repo]/route.tsx b/apps/web/app/api/og-image/[provider]/[owner]/[repo]/route.tsx
index 15582c8..a001797 100644
--- a/apps/web/app/api/og-image/[provider]/[owner]/[repo]/route.tsx
+++ b/apps/web/app/api/og-image/[provider]/[owner]/[repo]/route.tsx
@@ -133,6 +133,17 @@ export async function GET(
     const displayName = projectName || repoData.name;
     const displayDescription = description || repoData.description || '';
 
+    // Validate avatar URL server-side since onError handlers don't work in ImageResponse
+    let validatedAvatarUrl = repoData.owner.avatar_url;
+    try {
+      const avatarResponse = await fetch(validatedAvatarUrl, { method: 'HEAD' });
+      if (!avatarResponse.ok) {
+        validatedAvatarUrl = `https://ui-avatars.com/api/?name=${encodeURIComponent(repoData.owner.login)}&size=160`;
+      }
+    } catch {
+      validatedAvatarUrl = `https://ui-avatars.com/api/?name=${encodeURIComponent(repoData.owner.login)}&size=160`;
+    }
+
     const formatNumber = (num: number): string => {
       if (num >= 1000000) {
         return (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M';
@@ -166,13 +177,10 @@ export async function GET(
             }}
           >
             <img
-              src={repoData.owner.avatar_url}
+              src={validatedAvatarUrl}
               alt={`${repoData.owner.login} avatar`}
               width="160"
               height="160"
-              onError={(e) => {
-                e.currentTarget.src = `https://ui-avatars.com/api/?name=${encodeURIComponent(repoData.owner.login)}&size=160`;
-              }}
               style={{
                 position: 'absolute',
                 top: '80px',

Analysis

The OG image generation route uses Vercel's ImageResponse which renders JSX server-side to create images. However, the onError event handler on the img element (lines 173-175) attempts to set a fallback avatar URL when the primary avatar fails to load. This approach will not work because:

  1. Server-side JSX rendering in ImageResponse doesn't support JavaScript event handlers like onError
  2. The fallback logic will never execute, so if the primary avatar URL is broken, the OG image will show a broken image instead of the intended fallback
  3. This could result in malformed social media previews for repositories with invalid avatar URLs

The current code attempts to use client-side DOM manipulation in a server-side rendering context, which is a fundamental architectural mismatch.


Recommendation

Implement server-side avatar validation before rendering the ImageResponse. Pre-validate the avatar URL with a HEAD request or fetch, and if it fails, use the fallback URL directly in the src attribute instead of relying on the onError handler. For example:

// Before rendering ImageResponse
let avatarUrl = repoData.owner.avatar_url;
try {
  const response = await fetch(avatarUrl, { method: 'HEAD' });
  if (!response.ok) {
    avatarUrl = `https://ui-avatars.com/api/?name=${encodeURIComponent(repoData.owner.login)}&size=160`;
  }
} catch {
  avatarUrl = `https://ui-avatars.com/api/?name=${encodeURIComponent(repoData.owner.login)}&size=160`;
}

// Then use avatarUrl in the img element without onError handler
<img src={avatarUrl} ... />

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.