Skip to content

Conversation

@codeunia-dev
Copy link
Owner

@codeunia-dev codeunia-dev commented Sep 13, 2025

Add a new SponsorsSection component to showcase project sponsors with animation effects. The section includes logos, titles, and links for each sponsor, with hover animations and a scrolling display. Also updates the project name in package-lock.json.

Summary by CodeRabbit

  • New Features

    • Added a Sponsors section on the Home page showcasing industry supporters in a continuously scrolling gallery.
    • Interactive sponsor tiles display logos, names, and titles; open links in a new tab when available.
  • Performance

    • Section loads lazily to keep the page responsive and fast.
  • UI/UX

    • Hover effects and subtle animations enhance interactivity.
    • Loading placeholders appear while the section loads.

Add a new SponsorsSection component to showcase project sponsors with animation effects. The section includes logos, titles, and links for each sponsor, with hover animations and a scrolling display. Also updates the project name in package-lock.json.
@vercel
Copy link

vercel bot commented Sep 13, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
codeunia Ready Ready Preview Comment Sep 13, 2025 2:47am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 13, 2025

Walkthrough

Adds a new client-side SponsorsSection component and integrates it into the Home page via a dynamic import with SSR disabled. The Home page wraps the section in Suspense and provides loading fallbacks. The SponsorsSection renders a scrolling gallery of sponsor tiles with optional links and hover effects.

Changes

Cohort / File(s) Summary
Home page integration
app/page.tsx
Adds a lazily loaded SponsorsSection using Next.js dynamic import with ssr: false, plus Suspense. Inserts the section after CommunitySpotlight and before LatestContentPreview. Provides inline skeleton fallbacks for both dynamic import and Suspense.
New Sponsors Section component
components/home/SponsorsSection.tsx
Introduces export function SponsorsSection() as a client component. Renders a header and a continuously scrolling, duplicated strip of sponsor tiles with Next/Image logos, optional links, and hover effects. Uses utility classes and Framer Motion imports.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant N as Next.js App Router
    participant H as HomePage
    participant S as Suspense
    participant D as Dynamic Import (SponsorsSection)
    participant C as SponsorsSection

    U->>N: Request Home (/)
    N->>H: Render page
    H->>S: Wrap SponsorsSection with fallback
    S->>U: Show Suspense fallback
    H->>D: Trigger dynamic import (ssr: false)
    D-->>H: Load pending (client-side only)
    Note over S,D: Two fallbacks exist: inline + dynamic loading skeleton
    D-->>H: Module resolved
    H->>C: Render SponsorsSection
    S-->>U: Replace fallback with content
    C-->>U: Display scrolling sponsors gallery
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

A hop, a skip, a sponsor scroll,
New tiles parade in polished roll.
I twitch my nose—fallbacks in place,
Suspense unwraps with gentle grace.
With logos bright and links that gleam,
I thump: “Shipped!”—a silky stream. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "feat(home): add sponsors section with animated display" accurately and succinctly summarizes the primary change — adding a SponsorsSection to the Home page with animation and scrolling behavior. It follows a conventional-commit style with a clear scope and avoids unnecessary detail or noise. This matches the changes in app/page.tsx and components/home/SponsorsSection.tsx described in the PR.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/app/page.tsx

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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

coderabbitai bot added a commit that referenced this pull request Sep 13, 2025
Docstrings generation was requested by @codeunia-dev.

* #237 (comment)

The following files were modified:

* `app/page.tsx`
* `components/home/SponsorsSection.tsx`
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 13, 2025

Note

Generated docstrings for this pull request at #238

@codeunia-dev codeunia-dev merged commit d114ae7 into main Sep 13, 2025
13 of 14 checks passed
Copy link
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: 3

🧹 Nitpick comments (6)
components/home/SponsorsSection.tsx (4)

94-99: Ensure animate-scroll is defined and support reduced motion.

  • If the animate-scroll class/keyframes aren’t defined globally, the strip won’t move.
  • Respect prefers-reduced-motion to avoid motion sickness.

If missing, add to your global CSS:

@keyframes sponsors-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
.animate-scroll { animation: sponsors-scroll 30s linear infinite; will-change: transform; }
@media (prefers-reduced-motion: reduce) {
  .animate-scroll { animation: none; }
}

99-133: DRY up the card markup and keys.

The anchor/non-anchor branches duplicate large blocks, and you render two maps with near-identical bodies. Use a single SponsorCard and map over a duplicated array. Also prefer stable keys.

Example:

+type Sponsor = { name: string; title: string; logo: string; link?: string };
+
+function SponsorCard({ sponsor, duplicate }: { sponsor: Sponsor; duplicate?: boolean }) {
+  const Card = (
+    <motion.div
+      className="flex-shrink-0 w-[300px] h-[200px] rounded-xl border border-primary/10 bg-background/50 backdrop-blur-sm p-2 flex flex-col items-center justify-center gap-4 hover:border-primary/20 transition-all duration-300 hover:shadow-lg group"
+      whileHover={{ y: -5 }}
+      {...(duplicate ? { 'aria-hidden': true } : {})}
+    >
+      <div className="relative w-full h-48 flex items-center justify-center">
+        <Image src={sponsor.logo} alt={sponsor.name} fill sizes="300px" className="object-contain p-4" />
+      </div>
+      <div className="text-center">
+        <h3 className="font-semibold text-lg">{sponsor.name}</h3>
+        <p className="text-sm text-muted-foreground">{sponsor.title}</p>
+      </div>
+    </motion.div>
+  );
+  return sponsor.link ? (
+    <a
+      href={sponsor.link}
+      target="_blank"
+      rel="noopener noreferrer"
+      className="no-underline"
+      {...(duplicate ? { 'aria-hidden': true } : {})}
+    >
+      {Card}
+    </a>
+  ) : Card;
+}
@@
-              {sponsors.map((sponsor, idx) => (
-                sponsor.link ? (
-                  <a
-                    key={`first-${idx}`}
+              {[...sponsors, ...sponsors].map((sponsor, idx) => (
+                <div key={`${sponsor.name}-${idx}`} className="contents">
+                  <SponsorCard sponsor={sponsor} duplicate={idx >= sponsors.length} />
+                </div>
-                ) : (
-
-                )
               ))}
-              {sponsors.map((sponsor, idx) => (
-
-              ))}

Also applies to: 135-161, 164-199, 200-227


101-102: Prefer stable keys over array indices.

Avoid idx-based keys to reduce accidental remounts; sponsor.name is stable and unique here.

- key={`first-${idx}`}
+ key={`first-${sponsor.name}`}- key={`second-${idx}`}
+ key={`second-${sponsor.name}`}

Also applies to: 136-137, 167-168, 201-202


82-83: Nit: -bottom-0 is equivalent to bottom-0.

Minor cleanup.

-                <span className="absolute -bottom-0 left-[1.125rem] h-px w-[calc(100%-2.25rem)] …
+                <span className="absolute bottom-0 left-[1.125rem] h-px w-[calc(100%-2.25rem)] …
app/page.tsx (2)

107-111: Redundant Suspense vs dynamic loading fallback.

Since this dynamic import doesn’t set suspense: true, the Suspense fallback won’t apply; the loading option already covers the client load. Choose one:

  • Remove the Suspense wrapper, or
  • Enable suspense: true in dynamic options and drop the loading prop for consistency with other sections.
-const SponsorsSection = dynamic(() => import("@/components/home/SponsorsSection").then(mod => ({ default: mod.SponsorsSection })), {
-  loading: () => (/* skeleton */),
-  ssr: false
-});
+const SponsorsSection = dynamic(
+  () => import("@/components/home/SponsorsSection").then(mod => ({ default: mod.SponsorsSection })),
+  { ssr: false, suspense: true }
+);
@@
-          <Suspense fallback={<div className="py-16"><div className="container px-4 mx-auto"><div className="animate-pulse"><div className="h-8 bg-gray-200 rounded w-1/3 mx-auto mb-4"></div><div className="h-4 bg-gray-200 rounded w-1/2 mx-auto"></div></div></div></div>}>
-            <SponsorsSection />
-          </Suspense>
+          <Suspense fallback={<div className="py-16"><div className="container px-4 mx-auto"><div className="animate-pulse"><div className="h-8 bg-gray-200 rounded w-1/3 mx-auto mb-4"></div><div className="h-4 bg-gray-200 rounded w-1/2 mx-auto"></div></div></div></div>}>
+            <SponsorsSection />
+          </Suspense>

60-74: Optional: consider enabling SSR for faster first paint of static content.

If SEO or initial paint matters for this section, ssr: true is safe here (the component is client-safe and data-free).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4037bea and e7ffa47.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • app/page.tsx (2 hunks)
  • components/home/SponsorsSection.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
app/page.tsx (2)
components/home/SponsorsSection.tsx (1)
  • SponsorsSection (58-234)
app/about/components/SponsorsSection.tsx (1)
  • SponsorsSection (58-269)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test Suite
🔇 Additional comments (3)
components/home/SponsorsSection.tsx (2)

58-234: Overall: solid section and visuals.

Nice, cohesive UI with thoughtful motion and theming. Once the a11y and image tweaks are in, this will be production-ready.


7-56: No missing sponsor images — filenames match public/images/sponsors

All logos referenced in components/home/SponsorsSection.tsx are present in public/images/sponsors: Innovxus.png, alexadevcommunity.png, codecrafter.png, codeunia.png, geekforgeeks.png, rotaract.png, studentchaptercu.png, unstop.png, webytes.png. The earlier "MISS" results were caused by checking ./images/... instead of ./public/images/....

app/page.tsx (1)

60-74: Dynamic import of named export is correct; SSR disabled is fine for a purely visual section.

Looks good as a non-critical, client-only block.

Comment on lines +71 to +84
<div className="flex flex-col items-center justify-center gap-4">
<button className="bg-slate-800 no-underline group relative shadow-2xl shadow-zinc-900 rounded-full p-px text-sm font-semibold leading-6 text-white inline-block cursor-default">
<span className="absolute inset-0 overflow-hidden rounded-full">
<span className="absolute inset-0 rounded-full bg-[image:radial-gradient(75%_100%_at_50%_0%,rgba(56,189,248,0.6)_0%,rgba(56,189,248,0)_75%)] opacity-0 transition-opacity duration-500 group-hover:opacity-100" />
</span>
<div className="relative flex space-x-2 items-center z-10 rounded-full bg-zinc-950 py-0.5 px-4 ring-1 ring-white/10">
<span>Our Sponsors</span>
<span>
<Handshake className="w-3 h-3" />
</span>
</div>
<span className="absolute -bottom-0 left-[1.125rem] h-px w-[calc(100%-2.25rem)] bg-gradient-to-r from-emerald-400/0 via-emerald-400/90 to-emerald-400/0 transition-opacity duration-500 group-hover:opacity-40" />
</button>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Non-interactive “button” hurts accessibility; use a non-focusable element.

This badge is decorative and not clickable. A is focusable and announced as interactive.

Apply:

-              <button className="bg-slate-800 no-underline group relative shadow-2xl shadow-zinc-900 rounded-full p-px text-sm font-semibold leading-6 text-white inline-block cursor-default">
+              <div aria-hidden="true" className="bg-slate-800 no-underline group relative shadow-2xl shadow-zinc-900 rounded-full p-px text-sm font-semibold leading-6 text-white inline-block">-              </button>
+              </div>
📝 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
<div className="flex flex-col items-center justify-center gap-4">
<button className="bg-slate-800 no-underline group relative shadow-2xl shadow-zinc-900 rounded-full p-px text-sm font-semibold leading-6 text-white inline-block cursor-default">
<span className="absolute inset-0 overflow-hidden rounded-full">
<span className="absolute inset-0 rounded-full bg-[image:radial-gradient(75%_100%_at_50%_0%,rgba(56,189,248,0.6)_0%,rgba(56,189,248,0)_75%)] opacity-0 transition-opacity duration-500 group-hover:opacity-100" />
</span>
<div className="relative flex space-x-2 items-center z-10 rounded-full bg-zinc-950 py-0.5 px-4 ring-1 ring-white/10">
<span>Our Sponsors</span>
<span>
<Handshake className="w-3 h-3" />
</span>
</div>
<span className="absolute -bottom-0 left-[1.125rem] h-px w-[calc(100%-2.25rem)] bg-gradient-to-r from-emerald-400/0 via-emerald-400/90 to-emerald-400/0 transition-opacity duration-500 group-hover:opacity-40" />
</button>
</div>
<div className="flex flex-col items-center justify-center gap-4">
<div aria-hidden="true" className="bg-slate-800 no-underline group relative shadow-2xl shadow-zinc-900 rounded-full p-px text-sm font-semibold leading-6 text-white inline-block">
<span className="absolute inset-0 overflow-hidden rounded-full">
<span className="absolute inset-0 rounded-full bg-[image:radial-gradient(75%_100%_at_50%_0%,rgba(56,189,248,0.6)_0%,rgba(56,189,248,0)_75%)] opacity-0 transition-opacity duration-500 group-hover:opacity-100" />
</span>
<div className="relative flex space-x-2 items-center z-10 rounded-full bg-zinc-950 py-0.5 px-4 ring-1 ring-white/10">
<span>Our Sponsors</span>
<span>
<Handshake className="w-3 h-3" />
</span>
</div>
<span className="absolute -bottom-0 left-[1.125rem] h-px w-[calc(100%-2.25rem)] bg-gradient-to-r from-emerald-400/0 via-emerald-400/90 to-emerald-400/0 transition-opacity duration-500 group-hover:opacity-40" />
</div>
</div>
🤖 Prompt for AI Agents
In components/home/SponsorsSection.tsx around lines 71-84, the badge is
implemented as a <button> which is focusable and exposed as interactive though
it is decorative; replace the <button> with a non-interactive element (e.g.,
<div> or <span>) keeping the same className and structure, remove any
button-specific semantics, and mark it decorative with aria-hidden="true" so it
is not announced or focusable by assistive tech (ensure no tabIndex is set).

Comment on lines +112 to +126
<div className={"relative w-full h-48 flex items-center justify-center"}>
<Image
src={sponsor.logo}
alt={sponsor.name}
fill
className={
sponsor.name === "Unstop"
? "object-contain p-4"
: sponsor.name === "Code Crafters"
? "object-contain w-32 h-16 mx-auto"
: sponsor.name === "Innovxus"
? "object-contain w-24 h-10 mx-auto flex items-center justify-center"
: "object-cover"
}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Next/Image: avoid mixing fill with width/height utility classes.

When using fill, width/height classes like w-32 h-16 are ignored/conflict. Also, using object-cover may crop logos.

  • Use consistent object-contain and padding for all logos.
  • Provide sizes="300px" to improve image selection.
    Apply:
-                        <Image
+                        <Image
                           src={sponsor.logo}
                           alt={sponsor.name}
-                          fill
-                          className={
-                            sponsor.name === "Unstop"
-                              ? "object-contain p-4"
-                              : sponsor.name === "Code Crafters"
-                              ? "object-contain w-32 h-16 mx-auto"
-                              : sponsor.name === "Innovxus"
-                              ? "object-contain w-24 h-10 mx-auto flex items-center justify-center"
-                              : "object-cover"
-                          }
+                          fill
+                          sizes="300px"
+                          className="object-contain p-4"
                         />

If you need per-brand tweaks, adjust the wrapping container (add extra padding) rather than overriding Image width/height.

Also applies to: 140-154, 177-191, 205-219

🤖 Prompt for AI Agents
In components/home/SponsorsSection.tsx around lines 112-126 (also apply same
pattern at 140-154, 177-191, 205-219): the Image components use Next/Image with
the fill prop while conditionally applying width/height utility classes and
object-cover, which conflict with fill and can crop logos. Replace per-brand
width/height utilities on the Image with a consistent object-contain and
optional padding class, move any size/spacing tweaks into the wrapping div
(adjust padding/margins or set explicit width/height on the wrapper), and add
sizes="300px" to the Image props so the browser can pick an appropriate src;
ensure no width/height Tailwind classes remain on Image when using fill.

Comment on lines +164 to +227
{sponsors.map((sponsor, idx) => (
sponsor.link ? (
<a
key={`second-${idx}`}
href={sponsor.link}
target="_blank"
rel="noopener noreferrer"
className="no-underline"
>
<motion.div
className="flex-shrink-0 w-[300px] h-[200px] rounded-xl border border-primary/10 bg-background/50 backdrop-blur-sm p-2 flex flex-col items-center justify-center gap-4 hover:border-primary/20 transition-all duration-300 hover:shadow-lg group"
whileHover={{ y: -5 }}
>
<div className={"relative w-full h-48 flex items-center justify-center"}>
<Image
src={sponsor.logo}
alt={sponsor.name}
fill
className={
sponsor.name === "Unstop"
? "object-contain p-4"
: sponsor.name === "Code Crafters"
? "object-contain w-32 h-16 mx-auto"
: sponsor.name === "Innovxus"
? "object-contain w-24 h-10 mx-auto flex items-center justify-center"
: "object-cover"
}
/>
</div>
<div className="text-center">
<h3 className="font-semibold text-lg">{sponsor.name}</h3>
<p className="text-sm text-muted-foreground">{sponsor.title}</p>
</div>
</motion.div>
</a>
) : (
<motion.div
key={`second-${idx}`}
className="flex-shrink-0 w-[300px] h-[200px] rounded-xl border border-primary/10 bg-background/50 backdrop-blur-sm p-2 flex flex-col items-center justify-center gap-4 hover:border-primary/20 transition-all duration-300 hover:shadow-lg group"
whileHover={{ y: -5 }}
>
<div className={"relative w-full h-48 flex items-center justify-center"}>
<Image
src={sponsor.logo}
alt={sponsor.name}
fill
className={
sponsor.name === "Unstop"
? "object-contain p-4"
: sponsor.name === "Code Crafters"
? "object-contain w-32 h-16 mx-auto"
: sponsor.name === "Innovxus"
? "object-contain w-24 h-10 mx-auto flex items-center justify-center"
: "object-cover"
}
/>
</div>
<div className="text-center">
<h3 className="font-semibold text-lg">{sponsor.name}</h3>
<p className="text-sm text-muted-foreground">{sponsor.title}</p>
</div>
</motion.div>
)
))}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Duplicate strip should be hidden from screen readers.

The second mapping is for continuous scrolling only; it repeats content for AT.

Apply aria-hidden on duplicate items:

-                  <a
+                  <a
+                    aria-hidden="true"
                     key={`second-${idx}`}
                     href={sponsor.link}
                     target="_blank"
                     rel="noopener noreferrer"
                     className="no-underline"
                   >
-                  <motion.div
+                  <motion.div
+                    aria-hidden="true"
                     key={`second-${idx}`}
                     className="flex-shrink-0 w-[300px] h-[200px] rounded-xl border border-primary/10 bg-background/50 backdrop-blur-sm p-2 flex flex-col items-center justify-center gap-4 hover:border-primary/20 transition-all duration-300 hover:shadow-lg group"
                     whileHover={{ y: -5 }}
                   >

Do the same for the non-link branch within the duplicate set.

📝 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
{sponsors.map((sponsor, idx) => (
sponsor.link ? (
<a
key={`second-${idx}`}
href={sponsor.link}
target="_blank"
rel="noopener noreferrer"
className="no-underline"
>
<motion.div
className="flex-shrink-0 w-[300px] h-[200px] rounded-xl border border-primary/10 bg-background/50 backdrop-blur-sm p-2 flex flex-col items-center justify-center gap-4 hover:border-primary/20 transition-all duration-300 hover:shadow-lg group"
whileHover={{ y: -5 }}
>
<div className={"relative w-full h-48 flex items-center justify-center"}>
<Image
src={sponsor.logo}
alt={sponsor.name}
fill
className={
sponsor.name === "Unstop"
? "object-contain p-4"
: sponsor.name === "Code Crafters"
? "object-contain w-32 h-16 mx-auto"
: sponsor.name === "Innovxus"
? "object-contain w-24 h-10 mx-auto flex items-center justify-center"
: "object-cover"
}
/>
</div>
<div className="text-center">
<h3 className="font-semibold text-lg">{sponsor.name}</h3>
<p className="text-sm text-muted-foreground">{sponsor.title}</p>
</div>
</motion.div>
</a>
) : (
<motion.div
key={`second-${idx}`}
className="flex-shrink-0 w-[300px] h-[200px] rounded-xl border border-primary/10 bg-background/50 backdrop-blur-sm p-2 flex flex-col items-center justify-center gap-4 hover:border-primary/20 transition-all duration-300 hover:shadow-lg group"
whileHover={{ y: -5 }}
>
<div className={"relative w-full h-48 flex items-center justify-center"}>
<Image
src={sponsor.logo}
alt={sponsor.name}
fill
className={
sponsor.name === "Unstop"
? "object-contain p-4"
: sponsor.name === "Code Crafters"
? "object-contain w-32 h-16 mx-auto"
: sponsor.name === "Innovxus"
? "object-contain w-24 h-10 mx-auto flex items-center justify-center"
: "object-cover"
}
/>
</div>
<div className="text-center">
<h3 className="font-semibold text-lg">{sponsor.name}</h3>
<p className="text-sm text-muted-foreground">{sponsor.title}</p>
</div>
</motion.div>
)
))}
{sponsors.map((sponsor, idx) => (
sponsor.link ? (
<a
aria-hidden="true"
key={`second-${idx}`}
href={sponsor.link}
target="_blank"
rel="noopener noreferrer"
className="no-underline"
>
<motion.div
aria-hidden="true"
key={`second-${idx}`}
className="flex-shrink-0 w-[300px] h-[200px] rounded-xl border border-primary/10 bg-background/50 backdrop-blur-sm p-2 flex flex-col items-center justify-center gap-4 hover:border-primary/20 transition-all duration-300 hover:shadow-lg group"
whileHover={{ y: -5 }}
>
<div className={"relative w-full h-48 flex items-center justify-center"}>
<Image
src={sponsor.logo}
alt={sponsor.name}
fill
className={
sponsor.name === "Unstop"
? "object-contain p-4"
: sponsor.name === "Code Crafters"
? "object-contain w-32 h-16 mx-auto"
: sponsor.name === "Innovxus"
? "object-contain w-24 h-10 mx-auto flex items-center justify-center"
: "object-cover"
}
/>
</div>
<div className="text-center">
<h3 className="font-semibold text-lg">{sponsor.name}</h3>
<p className="text-sm text-muted-foreground">{sponsor.title}</p>
</div>
</motion.div>
</a>
) : (
<motion.div
aria-hidden="true"
key={`second-${idx}`}
className="flex-shrink-0 w-[300px] h-[200px] rounded-xl border border-primary/10 bg-background/50 backdrop-blur-sm p-2 flex flex-col items-center justify-center gap-4 hover:border-primary/20 transition-all duration-300 hover:shadow-lg group"
whileHover={{ y: -5 }}
>
<div className={"relative w-full h-48 flex items-center justify-center"}>
<Image
src={sponsor.logo}
alt={sponsor.name}
fill
className={
sponsor.name === "Unstop"
? "object-contain p-4"
: sponsor.name === "Code Crafters"
? "object-contain w-32 h-16 mx-auto"
: sponsor.name === "Innovxus"
? "object-contain w-24 h-10 mx-auto flex items-center justify-center"
: "object-cover"
}
/>
</div>
<div className="text-center">
<h3 className="font-semibold text-lg">{sponsor.name}</h3>
<p className="text-sm text-muted-foreground">{sponsor.title}</p>
</div>
</motion.div>
)
))}
🤖 Prompt for AI Agents
In components/home/SponsorsSection.tsx around lines 164 to 227, the duplicated
sponsor items used for continuous scrolling should be hidden from assistive
technologies; add aria-hidden="true" to the duplicate branches: set
aria-hidden="true" on the outer <a> element wrapping the duplicate linked branch
and on the root <motion.div> of the duplicate non-link branch (and if you prefer
consistency, also add aria-hidden="true" to the duplicate <motion.div> inside
the linked branch), keeping existing attributes intact.

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.

3 participants