Skip to content
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

Landing page new #39

Merged
merged 26 commits into from
Feb 7, 2025
Merged

Landing page new #39

merged 26 commits into from
Feb 7, 2025

Conversation

Jikugodwill
Copy link
Collaborator

@Jikugodwill Jikugodwill commented Feb 6, 2025

Summary by CodeRabbit

  • New Features

    • Revamped the landing page with interactive FAQs, partner showcases, and social sharing buttons.
    • Introduced a dynamic tweet display panel that adapts to various devices, offering a grid view on larger screens and a scrollable layout on smaller ones.
  • Style

    • Enhanced visual animations, including smooth fade-ins, marquee, and typewriter effects, to deliver a more polished user experience.
  • Chores

    • Updated project dependencies for improved functionality and compatibility.
    • Added new configuration to support package transpilation in the Next.js application.
    • Introduced a new JSON file for tweet identifiers to streamline tweet management.
    • Updated TypeScript configuration to include new JavaScript components.

Copy link

vercel bot commented Feb 6, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
curatedotfun-app ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 6, 2025 10:36pm
curatedotfun-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 6, 2025 10:36pm
curatedotfun-landing ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 6, 2025 10:36pm

Copy link

coderabbitai bot commented Feb 6, 2025

Walkthrough

This pull request introduces updates across multiple components of the project. New dependencies are added in the package.json files, and existing ones are updated. The landing page features interactive components, including a hashtag button for clipboard functionality and a collapsible FAQs section. A new TweetWall component is created to display tweets from a JSON file with responsive layouts. Additionally, global styles are enhanced, and configuration files for Next.js and TypeScript are modified to support the new features.

Changes

File(s) Change Summary
landing-page/package.json Added dependencies: "lucide-react" (^0.474.0), "react-router-dom" (^7.1.5), "react-tweet" (^3.2.1); Updated devDependencies "@types/react" and "@types/react-dom" to ^19.0.8 and ^19.0.3 respectively.
package.json Reorganized devDependencies (retaining "turbo" and "prettier") and repositioned the "private" and "type" fields.
landing-page/pages/index.tsx Added constant PARTNERS, new type and component HashtagButton (with clipboard handling and mounted state), and added FAQs component; restructured header and main sections to highlight platform features and community contributions.
landing-page/styles/globals.css Updated html/body styles; added new classes (.scrollbar-hide, .testimonial-card, .animate-marquee, .hover:pause-marquee) and defined @Keyframes fadeIn; adjusted font-family quotations and keyframe placements.
landing-page/components/TweetWall.js Introduced TweetWall component to render tweets from tweets.json, handling responsive grid and scrollable layouts with scroll indicators.
landing-page/data/tweets.json Updated to include two additional tweet identifiers in the tweetIds array.
landing-page/next.config.js Added Next.js config to transpile "react-tweet".
landing-page/tsconfig.json Updated tsconfig "include" to compile the TweetWall component.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant HB as HashtagButton
    participant CP as Clipboard API

    U->>HB: Clicks hashtag button
    HB->>CP: Invoke copy command
    CP-->>HB: Returns copy result
    HB->>HB: Updates state (copied = true)
    HB->>U: Renders visual feedback (icon change)
Loading
sequenceDiagram
    participant U as User
    participant TW as TweetWall

    U->>TW: Scroll event in tweet wall
    TW->>TW: handleScroll updates currentIndex
    TW->>TW: Re-renders with updated tweet indicators
Loading

Poem

I’m a rabbit hopping in the code glen,
New dependencies and features sprout again.
Tweet walls scrolling and hashtags in the light,
FAQs and copy buttons making everything bright.
In my burrow of code, these changes delight! 🐰


🪧 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.
    • Generate unit testing code for this file.
    • 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. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

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

Documentation and Community

  • 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: 4

🧹 Nitpick comments (6)
landing-page/pages/index.tsx (4)

5-6: Consolidate Icon Imports to Optimize Bundle Size

The imports from "react-icons/fa" and "lucide-react" add multiple icon components, which may increase the bundle size unnecessarily if not all icons are used. Consider importing only the specific icons needed or using dynamic imports to optimize performance.

Apply this diff to import only the necessary icons:

-import { FaTwitter, FaBook, FaGithub, FaTelegram, FaCopy, FaCheck, } from "react-icons/fa";
+import { FaTwitter, FaBook, FaGithub, FaTelegram, FaCopy, FaCheck } from "react-icons/fa";

-import { Newspaper, Workflow, Bot, Gift, ExternalLink, SatelliteDish, CalendarRange, Podcast } from "lucide-react";
+import { Newspaper, Workflow, Bot, Gift, ExternalLink, SatelliteDish, CalendarRange, Podcast } from "lucide-react";

Ensure that only the icons actually used in the component are imported.


70-72: Re-evaluate the Use of Mounted State

Using the mounted state to delay rendering of client-side features is unnecessary here. The navigator object is available in the browser environment, and conditional rendering can be simplified.

Simplify the code by removing the mounted state:

-const [mounted, setMounted] = useState(false);

-useEffect(() => {
-  setMounted(true);
-}, []);

 {mounted && isActive && (
+{isActive && (

331-350: Ensure Consistent Use of Image Components and Proper Sizing

In this section, <img> tags are used instead of the Next.js <Image> component, potentially missing out on image optimization. Also, ensure that images have explicit width and height for layout stability.

Apply this diff to replace <img> with <Image> and specify dimensions:

-<img
-  src="/pod-network-avatar.png"
-  alt="Pod Network"
-  className="w-12 h-12 rounded-full mr-3"
/>
+<Image
+  src="/pod-network-avatar.png"
+  alt="Pod Network"
+  width={48}
+  height={48}
+  className="rounded-full mr-3"
/>

This change improves performance and prevents layout shifts.


475-477: Review Long Sections Without Semantic HTML Elements

Several sections lack appropriate semantic HTML tags, such as <section>, <article>, or appropriate headings. Using semantic HTML improves accessibility and SEO.

Consider wrapping content sections with semantic elements and using proper heading levels.

Also applies to: 639-643, 753-845

landing-page/styles/globals.css (2)

107-114: Consider Accessibility Impact of Hiding Scrollbars

The .scrollbar-hide class hides scrollbars, which may impact users who rely on them for navigation, such as keyboard or screen reader users.

Ensure that hiding scrollbars does not hinder accessibility. Consider providing alternative navigation methods or re-evaluating the necessity of hiding scrollbars.


116-119: Optimize the fadeIn Animation Keyframes

The fadeIn keyframes can be more efficiently defined using Tailwind CSS utility classes or built-in animation utilities to maintain consistency and reduce custom CSS.

Consider using Tailwind CSS's built-in animations or extending them in tailwind.config.js.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 22fef0d and 4b56c9e.

⛔ Files ignored due to path filters (1)
  • landing-page/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • landing-page/package.json (1 hunks)
  • landing-page/pages/index.tsx (7 hunks)
  • landing-page/styles/globals.css (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: CI
landing-page/pages/index.tsx

[warning] 1-1: Code style issues found in the above file. Run Prettier with --write to fix.

🔇 Additional comments (2)
landing-page/pages/index.tsx (1)

1289-1290: Resolve Pipeline Failure: Run Prettier to Fix Code Style Issues

Code style issues were found by Prettier in this file. Consistent code formatting enhances readability and maintainability.

Apply the following command to format the code:

This will format the files according to the project's Prettier configuration.

landing-page/package.json (1)

14-14: Verify Compatibility of lucide-react Version

The added dependency lucide-react at version ^0.474.0 should be verified for compatibility with your project and React version. Ensure there are no known issues with this version.

Please check the latest version of lucide-react and confirm it's compatible with your React version.

✅ Verification successful

🌐 Web query:

What is the latest version of `lucide-react`, and is version `^0.474.0` compatible with React 18?

💡 Result:

The latest version of `lucide-react` is **0.474.0**, as confirmed by multiple sources including its GitHub releases[1][5] and npm registry entries[2][3]. This version was published 10 days ago relative to the current date (February 6, 2025)[2].

**Compatibility with React 18**  
Version `^0.474.0` is fully compatible with React 18 based on:
- Explicit support for modern React features like Suspense in dynamic imports[2][4]
- Usage examples demonstrating standard React component patterns[4]
- No warnings or compatibility notices in documentation[4]
- Active maintenance aligning with React ecosystem standards[1][5]

The package uses standard ES modules and follows React best practices for props handling and SVG rendering[2][4]. For Next.js users, additional configuration in `next.config.js` ensures proper dynamic import functionality[2][3].

Citations:

- 1: https://github.com/lucide-icons/lucide/releases
- 2: https://www.npmjs.com/package/lucide-react/v/0.340.0
- 3: https://www.npmjs.com/package/lucide-react/v/0.318.0
- 4: https://lucide.dev/guide/packages/lucide-react
- 5: https://www.npmjs.com/package/lucide-react?activeTab=versions
- 6: https://www.sveltesociety.dev/packages?category=ui-components
- 7: https://lucide.dev/guide/packages/lucide-react-native
- 8: https://codesandbox.io/examples/package/lucide-react
- 9: https://lucide.dev/guide/installation
- 10: https://www.jsdelivr.com/package/npm/lucide

Compatibility Verified: lucide-react 0.474.0 is Compatible with React 18

  • The latest version of lucide-react is indeed 0.474.0.
  • This version explicitly supports React 18 features (such as Suspense and dynamic imports) and follows React best practices.
  • No compatibility issues or warnings have been reported for React 18.

Comment on lines 297 to +301
<Link
href="https://app.curate.fun/"
target="_blank"
rel="noopener noreferrer"
id="cta-button"
className="text-xl bg-black text-white px-4 py-2 rounded hover:bg-gray-800 font-lodrina"
className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Correct the Use of Link Component for External URLs

The Link component is being used for external URLs, which is not recommended. Replace Link with an <a> tag for external links to ensure proper navigation and prevent potential issues.

Apply this diff to correct the links:

-<Link
-  href="https://app.curate.fun/"
-  target="_blank"
-  rel="noopener noreferrer"
-  className="..."
->
+<a
+  href="https://app.curate.fun/"
+  target="_blank"
+  rel="noopener noreferrer"
+  className="..."
+>
   Dashboard
-</Link>
+</a>

Ensure all external links are updated accordingly.

Also applies to: 322-327, 858-864


⚠️ Potential issue

Use Anchor <a> Tags for External Links

The Link component from next/link is intended for internal routing. For external links, use anchor <a> tags to ensure proper behavior and avoid potential issues with client-side routing.

Apply this diff to correct the external link:

-<Link
-  href="https://app.curate.fun/"
-  target="_blank"
-  rel="noopener noreferrer"
-  className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
->
+<a
+  href="https://app.curate.fun/"
+  target="_blank"
+  rel="noopener noreferrer"
+  className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
+>
   Dashboard
-</Link>
+</a>

Repeat this correction for all external links using Link.

📝 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
<Link
href="https://app.curate.fun/"
target="_blank"
rel="noopener noreferrer"
id="cta-button"
className="text-xl bg-black text-white px-4 py-2 rounded hover:bg-gray-800 font-lodrina"
className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
<a
href="https://app.curate.fun/"
target="_blank"
rel="noopener noreferrer"
className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
>
Dashboard
</a>

Comment on lines 64 to 118
const HashtagButton = ({ tag, isActive, onClick }: HashtagButton) => {
// Move the copied state to client-side only using useEffect
const [copied, setCopied] = useState(false);
const [mounted, setMounted] = useState(false);

// Only show client-side features after mounting
useEffect(() => {
setMounted(true);
}, []);

const handleCopy = (e: React.MouseEvent) => {
e.stopPropagation();
navigator.clipboard.writeText(`@isubmit @curatedotfun #${tag}`);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};

return (
<button
className="relative"
onClick={onClick}
>
<div
className={`
px-4 py-2 rounded-lg transition-all duration-200 flex items-center gap-2
${isActive
? 'bg-gray-500 text-white'
: 'bg-white hover:bg-gray-100 border border-gray-200'
}
`}
>
<span>#{tag}</span>
{isActive && <span className="text-gray-300">▼</span>}
</div>
{/* Only render dropdown after component is mounted */}
{mounted && isActive && (
<div className="absolute top-full left-0 mt-2 bg-white border border-gray-200 rounded-lg p-3 shadow-lg z-50 whitespace-nowrap">
<div className="flex items-center gap-2">
<p className="text-sm text-gray-600">@isubmit @curatedotfun #{tag}</p>
<button
className="flex items-center gap-1 px-2 py-1 text-sm text-gray-500 hover:bg-gray-100 rounded transition-colors"
onClick={handleCopy}
>
{copied ? (
<FaCheck className="text-green-500" />
) : (
<FaCopy className="text-gray-400 hover:text-gray-600" />
)}
</button>
</div>
</div>
)}
</button>
);
};
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Ensure Proper Error Handling for Clipboard Operations

The navigator.clipboard.writeText API may fail in some browsers or when the user denies permission. Consider adding error handling to provide feedback in case the copy operation fails.

Apply this diff to handle potential errors:

 const handleCopy = (e: React.MouseEvent) => {
   e.stopPropagation();
-  navigator.clipboard.writeText(`@isubmit @curatedotfun #${tag}`);
-  setCopied(true);
-  setTimeout(() => setCopied(false), 2000);
+  navigator.clipboard.writeText(`@isubmit @curatedotfun #${tag}`)
+    .then(() => {
+      setCopied(true);
+      setTimeout(() => setCopied(false), 2000);
+    })
+    .catch(() => {
+      alert('Failed to copy to clipboard. Please try manually.');
+    });
 };
📝 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 HashtagButton = ({ tag, isActive, onClick }: HashtagButton) => {
// Move the copied state to client-side only using useEffect
const [copied, setCopied] = useState(false);
const [mounted, setMounted] = useState(false);
// Only show client-side features after mounting
useEffect(() => {
setMounted(true);
}, []);
const handleCopy = (e: React.MouseEvent) => {
e.stopPropagation();
navigator.clipboard.writeText(`@isubmit @curatedotfun #${tag}`);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
return (
<button
className="relative"
onClick={onClick}
>
<div
className={`
px-4 py-2 rounded-lg transition-all duration-200 flex items-center gap-2
${isActive
? 'bg-gray-500 text-white'
: 'bg-white hover:bg-gray-100 border border-gray-200'
}
`}
>
<span>#{tag}</span>
{isActive && <span className="text-gray-300"></span>}
</div>
{/* Only render dropdown after component is mounted */}
{mounted && isActive && (
<div className="absolute top-full left-0 mt-2 bg-white border border-gray-200 rounded-lg p-3 shadow-lg z-50 whitespace-nowrap">
<div className="flex items-center gap-2">
<p className="text-sm text-gray-600">@isubmit @curatedotfun #{tag}</p>
<button
className="flex items-center gap-1 px-2 py-1 text-sm text-gray-500 hover:bg-gray-100 rounded transition-colors"
onClick={handleCopy}
>
{copied ? (
<FaCheck className="text-green-500" />
) : (
<FaCopy className="text-gray-400 hover:text-gray-600" />
)}
</button>
</div>
</div>
)}
</button>
);
};
const HashtagButton = ({ tag, isActive, onClick }: HashtagButton) => {
// Move the copied state to client-side only using useEffect
const [copied, setCopied] = useState(false);
const [mounted, setMounted] = useState(false);
// Only show client-side features after mounting
useEffect(() => {
setMounted(true);
}, []);
const handleCopy = (e: React.MouseEvent) => {
e.stopPropagation();
navigator.clipboard.writeText(`@isubmit @curatedotfun #${tag}`)
.then(() => {
setCopied(true);
setTimeout(() => setCopied(false), 2000);
})
.catch(() => {
alert('Failed to copy to clipboard. Please try manually.');
});
};
return (
<button
className="relative"
onClick={onClick}
>
<div
className={`
px-4 py-2 rounded-lg transition-all duration-200 flex items-center gap-2
${isActive
? 'bg-gray-500 text-white'
: 'bg-white hover:bg-gray-100 border border-gray-200'
}
`}
>
<span>#{tag}</span>
{isActive && <span className="text-gray-300"></span>}
</div>
{/* Only render dropdown after component is mounted */}
{mounted && isActive && (
<div className="absolute top-full left-0 mt-2 bg-white border border-gray-200 rounded-lg p-3 shadow-lg z-50 whitespace-nowrap">
<div className="flex items-center gap-2">
<p className="text-sm text-gray-600">@isubmit @curatedotfun #{tag}</p>
<button
className="flex items-center gap-1 px-2 py-1 text-sm text-gray-500 hover:bg-gray-100 rounded transition-colors"
onClick={handleCopy}
>
{copied ? (
<FaCheck className="text-green-500" />
) : (
<FaCopy className="text-gray-400 hover:text-gray-600" />
)}
</button>
</div>
</div>
)}
</button>
);
};

Comment on lines 287 to 306
<header className="w-full bg-white">
<div className="flex justify-between items-center w-full p-4 border-b border-black">
<div className="flex items-center">
<img
src="/curatedotfuntransparenticon.png"
alt="curate.fun Logo"
className="h-8 w-8 mr-2"
/>
<h1 className="text-2xl font-bold">curate.fun</h1>
</div>

<Link
href="https://app.curate.fun/"
target="_blank"
rel="noopener noreferrer"
id="cta-button"
className="text-xl bg-black text-white px-4 py-2 rounded hover:bg-gray-800 font-lodrina"
className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
>
DASHBOARD
Dashboard
</Link>
</nav>
</div>

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Replace <img> Tags with Next.js <Image> Component for Optimization

The use of <img> tags does not leverage Next.js's image optimization features. Replace <img> with the <Image> component from next/image for better performance and optimization.

Apply this diff to update the image tags:

-<img
-  src="/curatedotfuntransparenticon.png"
-  alt="curate.fun Logo"
-  className="h-8 w-8 mr-2"
/>
+<Image
+  src="/curatedotfuntransparenticon.png"
+  alt="curate.fun Logo"
+  width={32}
+  height={32}
+  className="h-8 w-8 mr-2"
+/>

Ensure to import Image from 'next/image' if not already imported.

📝 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
<header className="w-full bg-white">
<div className="flex justify-between items-center w-full p-4 border-b border-black">
<div className="flex items-center">
<img
src="/curatedotfuntransparenticon.png"
alt="curate.fun Logo"
className="h-8 w-8 mr-2"
/>
<h1 className="text-2xl font-bold">curate.fun</h1>
</div>
<Link
href="https://app.curate.fun/"
target="_blank"
rel="noopener noreferrer"
id="cta-button"
className="text-xl bg-black text-white px-4 py-2 rounded hover:bg-gray-800 font-lodrina"
className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
>
DASHBOARD
Dashboard
</Link>
</nav>
</div>
import Image from 'next/image';
<header className="w-full bg-white">
<div className="flex justify-between items-center w-full p-4 border-b border-black">
<div className="flex items-center">
<Image
src="/curatedotfuntransparenticon.png"
alt="curate.fun Logo"
width={32}
height={32}
className="h-8 w-8 mr-2"
/>
<h1 className="text-2xl font-bold">curate.fun</h1>
</div>
<Link
href="https://app.curate.fun/"
target="_blank"
rel="noopener noreferrer"
className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
>
Dashboard
</Link>
</div>

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

🔭 Outside diff range comments (1)
landing-page/pages/index.tsx (1)

1-1082: Fix Code Style Issues with Prettier

The CI pipeline indicates code style issues that can be fixed by running Prettier.

Run the following command to fix formatting:

prettier --write "landing-page/pages/index.tsx"
🧰 Tools
🪛 GitHub Actions: CI

[warning] 1-1: Code style issues found in the above file. Run Prettier with --write to fix.

♻️ Duplicate comments (3)
landing-page/pages/index.tsx (3)

363-367: 🛠️ Refactor suggestion

Replace <img> with Next.js <Image> Component

For better performance and optimization, use the Next.js <Image> component instead of the HTML <img> tag.

Apply this diff:

-<img
-  src="/curatedotfuntransparenticon.png"
-  alt="curate.fun Logo"
-  className="h-8 w-8 mr-2"
-/>
+<Image
+  src="/curatedotfuntransparenticon.png"
+  alt="curate.fun Logo"
+  width={32}
+  height={32}
+  className="h-8 w-8 mr-2"
+/>

74-79: 🛠️ Refactor suggestion

Add Error Handling for Clipboard Operations

The clipboard operation needs proper error handling as it may fail in some browsers or when permission is denied.

Apply this diff:

 const handleCopy = (e: React.MouseEvent) => {
   e.stopPropagation();
-  navigator.clipboard.writeText(`!submit @curatedotfun #${tag}`);
-  setCopied(true);
-  setTimeout(() => setCopied(false), 2000);
+  navigator.clipboard.writeText(`!submit @curatedotfun #${tag}`)
+    .then(() => {
+      setCopied(true);
+      setTimeout(() => setCopied(false), 2000);
+    })
+    .catch(() => {
+      alert('Failed to copy to clipboard. Please try manually.');
+    });
 };

370-377: ⚠️ Potential issue

Use Anchor Tags for External Links

The Link component from Next.js is being used for external URLs, which is not recommended.

Replace all external links with anchor tags. For example:

-<Link
-  href="https://app.curate.fun/"
-  target="_blank"
-  rel="noopener noreferrer"
-  className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
->
-  Dashboard
-</Link>
+<a
+  href="https://app.curate.fun/"
+  target="_blank"
+  rel="noopener noreferrer"
+  className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
+>
+  Dashboard
+</a>

Apply this change to all external links in the footer and throughout the component.

Also applies to: 1034-1075

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4b56c9e and 2de1cd0.

📒 Files selected for processing (1)
  • landing-page/pages/index.tsx (5 hunks)
🧰 Additional context used
🪛 GitHub Actions: CI
landing-page/pages/index.tsx

[warning] 1-1: Code style issues found in the above file. Run Prettier with --write to fix.

Comment on lines 123 to 144
const faqs = [
{
question: "What is curate.fun?",
answer: "Curate.fun is a platform designed to streamline content curation and sharing.",
},
{
question: "How do I get a feed?",
answer: "You can get a feed by signing up and selecting your preferred sources.",
},
{
question: "How does it work?",
answer: "The curate.fun is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
},
{
question: "How can you add support?",
answer: "You can add support by contributing to our GitHub repository or joining our community.",
},
{
question: "How does it work?",
answer: "Curate.fun uses AI to curate and summarize content from various sources.",
},
];
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove Duplicate FAQ Question

There are two entries for "How does it work?" with different answers, which could confuse users.

Apply this diff to consolidate the answers and remove the duplicate:

 const faqs = [
   {
     question: "What is curate.fun?",
     answer: "Curate.fun is a platform designed to streamline content curation and sharing.",
   },
   {
     question: "How do I get a feed?",
     answer: "You can get a feed by signing up and selecting your preferred sources.",
   },
   {
     question: "How does it work?",
-    answer: "The curate.fun is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
+    answer: "Curate.fun uses AI to curate and summarize content from various sources. It is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
   },
   {
     question: "How can you add support?",
     answer: "You can add support by contributing to our GitHub repository or joining our community.",
   },
-  {
-    question: "How does it work?",
-    answer: "Curate.fun uses AI to curate and summarize content from various sources.",
-  },
 ];
📝 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 faqs = [
{
question: "What is curate.fun?",
answer: "Curate.fun is a platform designed to streamline content curation and sharing.",
},
{
question: "How do I get a feed?",
answer: "You can get a feed by signing up and selecting your preferred sources.",
},
{
question: "How does it work?",
answer: "The curate.fun is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
},
{
question: "How can you add support?",
answer: "You can add support by contributing to our GitHub repository or joining our community.",
},
{
question: "How does it work?",
answer: "Curate.fun uses AI to curate and summarize content from various sources.",
},
];
const faqs = [
{
question: "What is curate.fun?",
answer: "Curate.fun is a platform designed to streamline content curation and sharing.",
},
{
question: "How do I get a feed?",
answer: "You can get a feed by signing up and selecting your preferred sources.",
},
{
question: "How does it work?",
- answer: "The curate.fun is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
+ answer: "Curate.fun uses AI to curate and summarize content from various sources. It is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
},
{
question: "How can you add support?",
answer: "You can add support by contributing to our GitHub repository or joining our community.",
},
- {
- question: "How does it work?",
- answer: "Curate.fun uses AI to curate and summarize content from various sources.",
- },
];

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)
landing-page/pages/index.tsx (2)

421-428: Add alt text descriptions for community logos.

The current alt text for community logos is generic and not descriptive enough for accessibility.

Apply this diff to improve alt text descriptions:

-<img src="/community-logo-1.png" alt="Community 1" className="h-8" />
-<img src="/community-logo-2.png" alt="Community 2" className="h-8" />
-<img src="/community-logo-3.png" alt="Community 3" className="h-8" />
-<img src="/community-logo-4.png" alt="Community 4" className="h-8" />
-<img src="/community-logo-5.png" alt="Community 5" className="h-8" />
-<img src="/community-logo-6.png" alt="Community 6" className="h-8" />
-<img src="/community-logo-7.png" alt="Community 7" className="h-8" />
-<img src="/community-logo-8.png" alt="Community 8" className="h-8" />
+<img src="/community-logo-1.png" alt="Ethereum Community Logo" className="h-8" />
+<img src="/community-logo-2.png" alt="NEAR Protocol Community Logo" className="h-8" />
+<img src="/community-logo-3.png" alt="Solana Community Logo" className="h-8" />
+<img src="/community-logo-4.png" alt="Morph Community Logo" className="h-8" />
+<img src="/community-logo-5.png" alt="Public Goods Community Logo" className="h-8" />
+<img src="/community-logo-6.png" alt="Crypto Grant Wire Community Logo" className="h-8" />
+<img src="/community-logo-7.png" alt="AI News Community Logo" className="h-8" />
+<img src="/community-logo-8.png" alt="DeSci Community Logo" className="h-8" />

961-961: Fix typo in heading text.

There's a typo in the heading text "Cryto Grant Wire".

Apply this diff to fix the typo:

-<h3 className="text-2xl font-bold">Cryto Grant Wire</h3>
+<h3 className="text-2xl font-bold">Crypto Grant Wire</h3>
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2de1cd0 and ccadb7e.

⛔ Files ignored due to path filters (1)
  • landing-page/public/assets/images/hero-cards.png is excluded by !**/*.png
📒 Files selected for processing (2)
  • landing-page/pages/index.tsx (5 hunks)
  • landing-page/styles/globals.css (2 hunks)
🧰 Additional context used
🪛 GitHub Actions: CI
landing-page/pages/index.tsx

[warning] 1-1: Code style issues found in the above file. Run Prettier with --write to fix.

🔇 Additional comments (4)
landing-page/pages/index.tsx (4)

363-367: 🛠️ Refactor suggestion

Replace <img> with Next.js <Image> component.

Using the Next.js <Image> component provides automatic image optimization, lazy loading, and better performance.

Apply this diff to optimize the image:

-<img
-  src="/curatedotfuntransparenticon.png"
-  alt="curate.fun Logo"
-  className="h-8 w-8 mr-2"
-/>
+<Image
+  src="/curatedotfuntransparenticon.png"
+  alt="curate.fun Logo"
+  width={32}
+  height={32}
+  className="h-8 w-8 mr-2"
+/>

Likely invalid or redundant comment.


74-79: 🛠️ Refactor suggestion

Add error handling for clipboard operations.

The clipboard operation should handle potential failures gracefully.

Apply this diff to add error handling:

 const handleCopy = (e: React.MouseEvent) => {
   e.stopPropagation();
-  navigator.clipboard.writeText(`!submit @curatedotfun #${tag}`);
-  setCopied(true);
-  setTimeout(() => setCopied(false), 2000);
+  navigator.clipboard.writeText(`!submit @curatedotfun #${tag}`)
+    .then(() => {
+      setCopied(true);
+      setTimeout(() => setCopied(false), 2000);
+    })
+    .catch(() => {
+      alert('Failed to copy to clipboard. Please try manually.');
+    });
 };

Likely invalid or redundant comment.


123-144: ⚠️ Potential issue

Remove duplicate FAQ entry.

There are two entries for "How does it work?" with different answers, which could confuse users.

Apply this diff to consolidate the answers and remove the duplicate:

 const faqs = [
   {
     question: "What is curate.fun?",
     answer: "Curate.fun is a platform designed to streamline content curation and sharing.",
   },
   {
     question: "How do I get a feed?",
     answer: "You can get a feed by signing up and selecting your preferred sources.",
   },
   {
     question: "How does it work?",
-    answer: "The curate.fun is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
+    answer: "Curate.fun uses AI to curate and summarize content from various sources. It is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
   },
   {
     question: "How can you add support?",
     answer: "You can add support by contributing to our GitHub repository or joining our community.",
   },
-  {
-    question: "How does it work?",
-    answer: "Curate.fun uses AI to curate and summarize content from various sources.",
-  },
 ];

Likely invalid or redundant comment.


370-377: 🛠️ Refactor suggestion

Use anchor tag for external links.

The Next.js Link component is designed for internal routing. For external links, use anchor tags.

Apply this diff to fix the external link:

-<Link
-  href="https://app.curate.fun/"
-  target="_blank"
-  rel="noopener noreferrer"
-  className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
->
+<a
+  href="https://app.curate.fun/"
+  target="_blank"
+  rel="noopener noreferrer"
+  className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
+>
   Dashboard
-</Link>
+</a>

Likely invalid or redundant comment.

Comment on lines 11 to 15
html, body {
height: 100vw;
margin: 0;
padding: 0;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect height unit.

The height property uses vw (viewport width) unit which is incorrect for vertical height. Use vh (viewport height) instead.

Apply this diff to fix the height unit:

 html, body {
-  height: 100vw;
+  height: 100vh;
   margin: 0;
   padding: 0;
 }
📝 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
html, body {
height: 100vw;
margin: 0;
padding: 0;
}
html, body {
height: 100vh;
margin: 0;
padding: 0;
}

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

♻️ Duplicate comments (4)
landing-page/pages/index.tsx (4)

363-367: 🛠️ Refactor suggestion

Replace <img> with Next.js <Image> Component

For better performance and optimization, use the Next.js <Image> component instead of the HTML <img> tag.

Apply this diff:

-<img
-  src="/curatedotfuntransparenticon.png"
-  alt="curate.fun Logo"
-  className="h-8 w-8 mr-2"
-/>
+<Image
+  src="/curatedotfuntransparenticon.png"
+  alt="curate.fun Logo"
+  width={32}
+  height={32}
+  className="h-8 w-8 mr-2"
+/>

74-79: ⚠️ Potential issue

Add Error Handling for Clipboard Operations

The clipboard API may fail in some browsers or when permission is denied. Add proper error handling.

Apply this diff:

 const handleCopy = (e: React.MouseEvent) => {
   e.stopPropagation();
-  navigator.clipboard.writeText(`!submit @curatedotfun #${tag}`);
-  setCopied(true);
-  setTimeout(() => setCopied(false), 2000);
+  navigator.clipboard.writeText(`!submit @curatedotfun #${tag}`)
+    .then(() => {
+      setCopied(true);
+      setTimeout(() => setCopied(false), 2000);
+    })
+    .catch(() => {
+      alert('Failed to copy to clipboard. Please try manually.');
+    });
 };

123-144: ⚠️ Potential issue

Remove Duplicate FAQ Question

There are two entries for "How does it work?" with different answers, which could confuse users.

Apply this diff to consolidate the answers and remove the duplicate:

 const faqs = [
   {
     question: "What is curate.fun?",
     answer: "Curate.fun is a platform designed to streamline content curation and sharing.",
   },
   {
     question: "How do I get a feed?",
     answer: "You can get a feed by signing up and selecting your preferred sources.",
   },
   {
     question: "How does it work?",
-    answer: "The curate.fun is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
+    answer: "Curate.fun uses AI to curate and summarize content from various sources. It is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
   },
   {
     question: "How can you add support?",
     answer: "You can add support by contributing to our GitHub repository or joining our community.",
   },
-  {
-    question: "How does it work?",
-    answer: "Curate.fun uses AI to curate and summarize content from various sources.",
-  },
 ];

370-377: ⚠️ Potential issue

Use Anchor Tags for External Links

The Link component from Next.js is intended for internal routing. For external links, use anchor <a> tags.

Apply this diff:

-<Link
-  href="https://app.curate.fun/"
-  target="_blank"
-  rel="noopener noreferrer"
-  className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
->
+<a
+  href="https://app.curate.fun/"
+  target="_blank"
+  rel="noopener noreferrer"
+  className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
+>
   Dashboard
-</Link>
+</a>

Also applies to other external links in the footer (lines 1066-1097) and other sections.

🧹 Nitpick comments (1)
landing-page/pages/index.tsx (1)

82-85: Enhance Button Accessibility

The HashtagButton needs ARIA attributes for better accessibility.

Apply this diff:

 <button
   className="relative"
   onClick={onClick}
+  aria-label={`Select hashtag ${tag}`}
+  aria-expanded={isActive}
+  aria-haspopup="true"
 >
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2e71183 and ba000b5.

📒 Files selected for processing (1)
  • landing-page/pages/index.tsx (5 hunks)
🧰 Additional context used
🪛 GitHub Actions: CI
landing-page/pages/index.tsx

[warning] 1-1: Code style issues found in the above file. Run Prettier with --write to fix.

Comment on lines 423 to 446
<a href="https://nearweek.com" target="_blank" rel="noopener noreferrer">
<img src="/assets/images/communities/nearweek.svg" alt="Near Week" className="h-8" />
</a>
<a href="https://alpha.potlock.org" target="_blank" rel="noopener noreferrer">
<img src="/assets/images/communities/potlock.svg" alt="PotLock" className="h-8" />
</a>
<a href="https://t.me/cryptograntwire" target="_blank" rel="noopener noreferrer">
<img src="/assets/images/communities/cryptograntwire.svg" alt="Crypto Grant Wire" className="h-8" />
</a>
<a href="https://community4.example.com" target="_blank" rel="noopener noreferrer">
<img src="/community-logo-4.png" alt="Community 4" className="h-8" />
</a>
<a href="https://community5.example.com" target="_blank" rel="noopener noreferrer">
<img src="/community-logo-5.png" alt="Community 5" className="h-8" />
</a>
<a href="https://community6.example.com" target="_blank" rel="noopener noreferrer">
<img src="/community-logo-6.png" alt="Community 6" className="h-8" />
</a>
<a href="https://community7.example.com" target="_blank" rel="noopener noreferrer">
<img src="/community-logo-7.png" alt="Community 7" className="h-8" />
</a>
<a href="https://community8.example.com" target="_blank" rel="noopener noreferrer">
<img src="/community-logo-8.png" alt="Community 8" className="h-8" />
</a>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve Image Accessibility and Error Handling

The community logo images need proper alt text and error handling for missing images.

  1. Add meaningful alt text for each community logo
  2. Add error handling for missing images
  3. Consider adding loading="lazy" for better performance

Apply this pattern to each image:

 <a href="https://community4.example.com" target="_blank" rel="noopener noreferrer">
   <img 
     src="/community-logo-4.png" 
-    alt="Community 4" 
+    alt="[Specific Community Name] Logo"
     className="h-8"
+    loading="lazy"
+    onError={(e) => {
+      e.currentTarget.style.display = 'none';
+    }}
   />
 </a>
📝 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
<a href="https://nearweek.com" target="_blank" rel="noopener noreferrer">
<img src="/assets/images/communities/nearweek.svg" alt="Near Week" className="h-8" />
</a>
<a href="https://alpha.potlock.org" target="_blank" rel="noopener noreferrer">
<img src="/assets/images/communities/potlock.svg" alt="PotLock" className="h-8" />
</a>
<a href="https://t.me/cryptograntwire" target="_blank" rel="noopener noreferrer">
<img src="/assets/images/communities/cryptograntwire.svg" alt="Crypto Grant Wire" className="h-8" />
</a>
<a href="https://community4.example.com" target="_blank" rel="noopener noreferrer">
<img src="/community-logo-4.png" alt="Community 4" className="h-8" />
</a>
<a href="https://community5.example.com" target="_blank" rel="noopener noreferrer">
<img src="/community-logo-5.png" alt="Community 5" className="h-8" />
</a>
<a href="https://community6.example.com" target="_blank" rel="noopener noreferrer">
<img src="/community-logo-6.png" alt="Community 6" className="h-8" />
</a>
<a href="https://community7.example.com" target="_blank" rel="noopener noreferrer">
<img src="/community-logo-7.png" alt="Community 7" className="h-8" />
</a>
<a href="https://community8.example.com" target="_blank" rel="noopener noreferrer">
<img src="/community-logo-8.png" alt="Community 8" className="h-8" />
</a>
<a href="https://nearweek.com" target="_blank" rel="noopener noreferrer">
<img src="/assets/images/communities/nearweek.svg" alt="Near Week" className="h-8" />
</a>
<a href="https://alpha.potlock.org" target="_blank" rel="noopener noreferrer">
<img src="/assets/images/communities/potlock.svg" alt="PotLock" className="h-8" />
</a>
<a href="https://t.me/cryptograntwire" target="_blank" rel="noopener noreferrer">
<img src="/assets/images/communities/cryptograntwire.svg" alt="Crypto Grant Wire" className="h-8" />
</a>
<a href="https://community4.example.com" target="_blank" rel="noopener noreferrer">
<img
src="/community-logo-4.png"
alt="[Specific Community Name] Logo"
className="h-8"
loading="lazy"
onError={(e) => {
e.currentTarget.style.display = 'none';
}}
/>
</a>
<a href="https://community5.example.com" target="_blank" rel="noopener noreferrer">
<img src="/community-logo-5.png" alt="Community 5" className="h-8" />
</a>
<a href="https://community6.example.com" target="_blank" rel="noopener noreferrer">
<img src="/community-logo-6.png" alt="Community 6" className="h-8" />
</a>
<a href="https://community7.example.com" target="_blank" rel="noopener noreferrer">
<img src="/community-logo-7.png" alt="Community 7" className="h-8" />
</a>
<a href="https://community8.example.com" target="_blank" rel="noopener noreferrer">
<img src="/community-logo-8.png" alt="Community 8" className="h-8" />
</a>

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: 0

🧹 Nitpick comments (1)
landing-page/pages/index.tsx (1)

543-560: Optimize marquee animation performance.

The marquee animation duplicates the entire PARTNERS array and renders all images at once. Consider:

  1. Using CSS content-visibility: auto for off-screen items
  2. Implementing virtualization for better performance
-<div className="flex justify-start items-center px-4 gap-20 animate-marquee hover:pause-marquee whitespace-nowrap">
+<div className="flex justify-start items-center px-4 gap-20 animate-marquee hover:pause-marquee whitespace-nowrap content-visibility-auto">
   {[...PARTNERS, ...PARTNERS].map((partner, i) => (
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e685fff and e618cf7.

📒 Files selected for processing (1)
  • landing-page/pages/index.tsx (5 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
landing-page/pages/index.tsx

[error] 291-291: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

🔇 Additional comments (6)
landing-page/pages/index.tsx (6)

167-172: Add error handling for clipboard operations.

The clipboard API may fail in some browsers or when permission is denied.


216-241: Remove duplicate FAQ question.

There are two entries for "How does it work?" with different answers.


289-292: Replace dangerouslySetInnerHTML with a safer alternative.

Using dangerouslySetInnerHTML without sanitization can expose users to XSS attacks.

🧰 Tools
🪛 Biome (1.9.4)

[error] 291-291: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)


483-490: Use anchor tags for external links instead of Next.js Link component.

The Link component is being used for external URLs, which is not recommended.

Also applies to: 1039-1045, 1046-1054


968-973: Remove duplicate content in Content Engine description.

The description text is identical to the Curate Engine section.


75-146: Replace placeholder URLs in PARTNERS array.

Several entries in the PARTNERS array use "#" as placeholder URLs. These should be replaced with actual URLs or removed if not needed.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Find all placeholder URLs in PARTNERS array
rg -A 2 'href: "#",' landing-page/pages/index.tsx

Length of output: 629


Replace placeholder URLs in PARTNERS array.

The shell script verification confirmed that several objects in the PARTNERS array use "#" as the href value. These placeholder URLs should be replaced with actual URLs or removed if they're not needed.

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 (4)
landing-page/components/TweetWall.js (4)

6-8: Consider adding TypeScript types.

Adding type definitions would improve code maintainability and catch potential runtime errors during development.

Convert the file to TypeScript and add types:

+interface Tweet {
+  tweetIds: string[];
+}
+
-const TweetWall = () => {
+const TweetWall: React.FC = () => {
   const [currentIndex, setCurrentIndex] = React.useState(0);

9-14: Optimize scroll handler performance.

The scroll handler might fire too frequently, potentially impacting performance. Consider debouncing the handler and adding error handling for edge cases.

Add debouncing and error handling:

+import { debounce } from "lodash";
+
 const TweetWall = () => {
   const [currentIndex, setCurrentIndex] = React.useState(0);
 
-  const handleScroll = (event) => {
+  const handleScroll = React.useCallback(debounce((event) => {
+    if (!event.target) return;
     const scrollLeft = event.target.scrollLeft;
     const width = event.target.clientWidth;
     const newIndex = Math.round(scrollLeft / width);
-    setCurrentIndex(newIndex);
-  };
+    if (newIndex >= 0 && newIndex < tweetData.tweetIds.length) {
+      setCurrentIndex(newIndex);
+    }
+  }, 100), []);

41-60: Enhance mobile scroll experience with accessibility features.

The horizontal scroll implementation could benefit from improved accessibility and user experience.

Add keyboard navigation and ARIA attributes:

 <div
   className="flex overflow-x-auto snap-x snap-mandatory scrollbar-hide"
   onScroll={handleScroll}
+  role="region"
+  aria-label="Tweet carousel"
+  tabIndex={0}
+  onKeyDown={(e) => {
+    if (e.key === 'ArrowRight' && currentIndex < tweetData.tweetIds.length - 1) {
+      setCurrentIndex(currentIndex + 1);
+    } else if (e.key === 'ArrowLeft' && currentIndex > 0) {
+      setCurrentIndex(currentIndex - 1);
+    }
+  }}
 >

31-38: Add loading states for tweets.

Consider showing a loading skeleton while tweets are being fetched to improve perceived performance.

Add loading state:

 <ErrorBoundary
   fallback={
     <div className="p-4 text-gray-500">Failed to load tweet</div>
   }
 >
+  <React.Suspense fallback={
+    <div className="animate-pulse">
+      <div className="h-12 bg-gray-200 rounded w-48 mb-4"></div>
+      <div className="h-32 bg-gray-200 rounded"></div>
+    </div>
+  }>
     <Tweet id={tweetId} />
+  </React.Suspense>
 </ErrorBoundary>

Also applies to: 51-58

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e618cf7 and 5bbadf4.

📒 Files selected for processing (1)
  • landing-page/components/TweetWall.js (1 hunks)

import React from "react";
import tweetData from "../data/tweets.json";
import { Tweet } from "react-tweet";
import { ErrorBoundary } from "next/dist/client/components/error-boundary";
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use the public API for ErrorBoundary import.

Importing from Next.js internal paths (next/dist/client/components/error-boundary) is not recommended as these paths may change between versions. Consider using a stable public API or implementing your own ErrorBoundary component.

Apply this diff to use a custom ErrorBoundary implementation:

-import { ErrorBoundary } from "next/dist/client/components/error-boundary";
+import { Component } from "react";
+
+class ErrorBoundary extends Component {
+  constructor(props) {
+    super(props);
+    this.state = { hasError: false };
+  }
+
+  static getDerivedStateFromError(error) {
+    return { hasError: true };
+  }
+
+  render() {
+    if (this.state.hasError) {
+      return this.props.fallback;
+    }
+    return this.props.children;
+  }
+}
📝 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
import { ErrorBoundary } from "next/dist/client/components/error-boundary";
-import { ErrorBoundary } from "next/dist/client/components/error-boundary";
+import { Component } from "react";
+
+class ErrorBoundary extends Component {
+ constructor(props) {
+ super(props);
+ this.state = { hasError: false };
+ }
+
+ static getDerivedStateFromError(error) {
+ return { hasError: true };
+ }
+
+ render() {
+ if (this.state.hasError) {
+ return this.props.fallback;
+ }
+ return this.props.children;
+ }
+}

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: 0

🧹 Nitpick comments (1)
landing-page/styles/globals.css (1)

27-36: Nitpick: Consider a More Descriptive Name for 'spin'
The @keyframes spin animation applies a vertical translation and opacity change rather than an actual rotation. Renaming it (for example, to fadeInUp) might improve code clarity.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5bbadf4 and a8604f5.

📒 Files selected for processing (1)
  • landing-page/styles/globals.css (3 hunks)
🔇 Additional comments (22)
landing-page/styles/globals.css (22)

18-25: Approved: Utility Animation Delay Classes
The new utility classes .delay-150 and .delay-300 are implemented clearly and will help control animation timing easily.


38-41: Approved: Emoji Animation Application
The #emojis span rule applies the spin animation with a very short duration (0.1s), which creates a quick effect. Ensure that this rapid animation aligns with your intended interaction.


42-47: Approved: Custom Font Configuration
The @font-face declaration for "Londrina Solid" is correctly configured. Please confirm that the font file is available at /fonts/LondrinaSolid-NNS.ttf.


49-57: Approved: Typography Consistency
Updating the font-family declarations for Link and heading elements to use double quotes enhances consistency and readability.


58-60: Approved: Call-to-Action Button Styling
The .cta-button class now uses the updated "Londrina Solid" font family, aligning it with the rest of the typography.


61-64: Approved: Enhanced h1 Styling
The h1 element is now styled with a larger font-size and stronger font-weight, creating a strong visual hierarchy.


66-69: Approved: h2 Style Consistency
The h2 styling is clear and maintains consistency with the overall design, ensuring proper subheading emphasis.


71-74: Approved: h3 Typography Update
The h3 style is well-defined for tertiary headings and fits smoothly into the established design system.


75-78: Approved: h4 Representation
The styling for h4 is appropriately scaled for secondary headings without compromising on visual weight.


79-82: Approved: h5 Styling
The h5 element receives a consistent and appropriately scaled font size, maintaining the design's hierarchy.


83-86: Approved: h6 Styling
The h6 style is scaled correctly for minimal headings while preserving the strong typographic design.


88-92: Approved: Hyperlink Styling
The .hyperlink class applies a clear visual style with underline and color, ensuring links are easily recognizable within the design.


94-107: Approved: WebKit Scrollbar Customization
The customizations for WebKit scrollbars (Chrome, Safari) are well implemented, providing a refined UI appearance.


109-113: Approved: Firefox Scrollbar Styling
The Firefox-specific scrollbar styles ensure that the UI remains consistent across different browsers.


115-120: Approved: Base Typography Settings
The @layer base rules setting the font-family for paragraphs and elements with the .text-base class are clear and maintain overall style consistency.


122-124: Approved: Typewriter Effect Setup
The .typewriter class correctly applies the "Londrina Solid" font, which fits the intended typewriter effect design.


126-134: Approved: Scrollbar Hiding for Testimonials
The .scrollbar-hide class effectively removes scrollbars in a cross-browser manner, ensuring a cleaner look for the testimonials section.


136-145: Approved: Fade-In Animation Definition
The @keyframes fadeIn animation is well defined, offering a smooth transition effect from a slightly translated, transparent state to full opacity and position.


147-149: Approved: Testimonial Card Animation
The .testimonial-card class applies the fadeIn animation neatly, enhancing the presentation of testimonial elements.


151-157: Verify: Marquee Animation Interaction
The .animate-marquee and .hover\:pause-marquee classes implement a continuous scrolling effect and a hover pause, respectively. Please verify that the animation operates smoothly across all target browsers.


11-16: 🛠️ Refactor suggestion

⚠️ Potential issue

Potential Issue: Incorrect Height Unit for html & body
The CSS sets height: 100vw; on the html, body selector, which uses the viewport width rather than the viewport height. This can lead to layout issues on devices where height is critical. Consider updating it to 100vh for a full viewport height.
For example:

-  height: 100vw;
+  height: 100vh;

Likely invalid or redundant comment.


158-165: Refactor Suggestion: Revise Marquee Keyframes for a Seamless Loop
The current @keyframes scroll animation transitions from translateX(-70%) to translateX(0%). This may cause a noticeable jump when the animation resets. Consider adjusting the keyframes for a continuous scroll effect. For example:

-@keyframes scroll {
-  0% {
-    transform: translateX(-70%);
-  }
-  100% {
-    transform: translateX(0%);
-  }
-}
+@keyframes scroll {
+  0% {
+    transform: translateX(0%);
+  }
+  50% {
+    transform: translateX(-50%);
+  }
+  100% {
+    transform: translateX(-100%);
+  }
+}

This configuration should create a smooth and uninterrupted marquee effect. Verify that the new sequence meets the design intent.

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

♻️ Duplicate comments (2)
landing-page/pages/index.tsx (2)

886-891: ⚠️ Potential issue

Remove duplicate content in Content Engine description.

The description text is identical to the Curate Engine section.

-                  <p className="font-['PT_Root_UI'] text-[#57606A] text-[18px] leading-[30px] font-normal text-center md:text-left">
-                    Pull posts, threads, and videos from Twitter, Telegram, and
-                    more. Organize everything into smart feeds that update
-                    automatically, so you're always sharing fresh, relevant
-                    content.
-                  </p>
+                  <p className="font-['PT_Root_UI'] text-[#57606A] text-[18px] leading-[30px] font-normal text-center md:text-left">
+                    Transform curated content into engaging formats using AI.
+                    Generate summaries, threads, and newsletters automatically
+                    while maintaining your brand voice and style.
+                  </p>

489-496: ⚠️ Potential issue

Replace Next.js Link with anchor tags for external URLs.

The Next.js Link component is designed for internal routing. For external links, use anchor tags instead.

Apply this pattern to all external links:

-<Link
-  href="https://app.curate.fun/"
-  target="_blank"
-  rel="noopener noreferrer"
-  className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
->
+<a
+  href="https://app.curate.fun/"
+  target="_blank"
+  rel="noopener noreferrer"
+  className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
+>
   Dashboard
-</Link>
+</a>

Also applies to: 512-518, 519-525, 957-963, 964-972

🧹 Nitpick comments (1)
landing-page/pages/index.tsx (1)

166-182: Improve error handling feedback for clipboard operations.

While error handling is implemented, the errors are only logged to the console. Users should receive visual feedback when the operation fails.

 const handleCopy = (e: React.MouseEvent) => {
   e.stopPropagation();
   navigator.clipboard
     .writeText(`!submit @curatedotfun #${tag}`)
     .then(
       () => {
         setCopied(true);
         setTimeout(() => setCopied(false), 2000);
       },
       () => {
-        console.error("Failed to copy text to clipboard");
+        alert('Failed to copy to clipboard. Please try manually.');
       },
     )
     .catch((error) => {
-      console.error("Failed to copy text to clipboard", error);
+      alert('Failed to copy to clipboard. Please try manually.');
     });
 };
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a8604f5 and 017b93f.

📒 Files selected for processing (1)
  • landing-page/pages/index.tsx (5 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
landing-page/pages/index.tsx

[error] 300-300: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

🪛 GitHub Actions: CI
landing-page/pages/index.tsx

[warning] 1-1: Code style issues found in the above file. Run Prettier with --write to fix.

🔇 Additional comments (2)
landing-page/pages/index.tsx (2)

76-147: Replace placeholder links and improve alt text descriptions.

Several entries in the PARTNERS array have placeholder values that need to be updated:

  1. Placeholder "#" hrefs for multiple entries
  2. Generic alt texts like "Community Convert to ORM #2"

Consider updating the entries with actual links and descriptive alt texts, or removing placeholder entries if they're not ready for production. This will improve accessibility and user experience.


225-251: ⚠️ Potential issue

Remove duplicate FAQ entries.

There are two entries for "How does it work?" with different answers.

 const faqs = [
   {
     question: "What is curate.fun?",
     answer: "Curate.fun is a platform designed to streamline content curation and sharing.",
   },
   {
     question: "How do I get a feed?",
     answer: "You can get a feed by signing up and selecting your preferred sources.",
   },
   {
     question: "How does it work?",
-    answer: "The curate.fun is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
+    answer: "Curate.fun uses AI to curate and summarize content from various sources. It is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
   },
   {
     question: "How can you add support?",
     answer: "You can add support by contributing to our <a class='hyperlink' href='https://github.com/potlock/curatedotfun' target='_blank' rel='noopener noreferrer'>GitHub repository</a> or joining our community.",
   },
-  {
-    question: "How does it work?",
-    answer: "Curate.fun uses AI to curate and summarize content from various sources.",
-  },
 ];

Likely invalid or redundant comment.

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

♻️ Duplicate comments (4)
landing-page/pages/index.tsx (4)

226-252: ⚠️ Potential issue

Remove duplicate FAQ entry.

There are two entries for "How does it work?" with different answers.

Consolidate the answers into a single, comprehensive entry:

 const faqs = [
   {
     question: "What is curate.fun?",
     answer: "Curate.fun is a platform designed to streamline content curation and sharing.",
   },
   {
     question: "How do I get a feed?",
     answer: "You can get a feed by signing up and selecting your preferred sources.",
   },
   {
     question: "How does it work?",
-    answer: "The curate.fun is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
+    answer: "Curate.fun uses AI to curate and summarize content from various sources. It is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
   },
   {
     question: "How can you add support?",
     answer: "You can add support by contributing to our <a class='hyperlink' href='https://github.com/potlock/curatedotfun' target='_blank' rel='noopener noreferrer'>GitHub repository</a> or joining our community.",
   },
-  {
-    question: "How does it work?",
-    answer: "Curate.fun uses AI to curate and summarize content from various sources.",
-  },
 ];

299-302: ⚠️ Potential issue

Replace dangerouslySetInnerHTML with a safer alternative.

Using dangerouslySetInnerHTML can expose users to XSS attacks.

Install and use DOMPurify to sanitize HTML content:

+import DOMPurify from 'dompurify';
+
+const SafeHTML = ({ html }: { html: string }) => (
+  <span dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(html) }} />
+);

-<p
-  className="mt-2 text-gray-600 flex-1"
-  dangerouslySetInnerHTML={{ __html: faq.answer }}
-/>
+<p className="mt-2 text-gray-600 flex-1">
+  <SafeHTML html={faq.answer} />
+</p>
🧰 Tools
🪛 Biome (1.9.4)

[error] 301-301: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)


489-496: ⚠️ Potential issue

Use anchor tags for external links instead of Next.js Link.

The Link component is being used for external URLs, which is not recommended.

Replace Link with anchor tags for external links:

-<Link
+<a
   href="https://app.curate.fun/"
   target="_blank"
   rel="noopener noreferrer"
   className="text-lg bg-black text-white px-6 py-2 rounded-lg hover:bg-gray-800"
 >
   Dashboard
-</Link>
+</a>

Also applies to: 512-518, 963-969, 970-978


892-897: ⚠️ Potential issue

Remove duplicate content in Content Engine description.

The description text is identical to the Curate Engine section.

Update the Content Engine description to be unique:

-<p className="font-['PT_Root_UI'] text-[#57606A] text-[18px] leading-[30px] font-normal text-center md:text-left">
-  Pull posts, threads, and videos from Twitter, Telegram, and
-  more. Organize everything into smart feeds that update
-  automatically, so you're always sharing fresh, relevant
-  content.
-</p>
+<p className="font-['PT_Root_UI'] text-[#57606A] text-[18px] leading-[30px] font-normal text-center md:text-left">
+  Transform curated content into engaging formats using AI.
+  Generate summaries, threads, and newsletters automatically
+  while maintaining your brand voice and style.
+</p>
🧹 Nitpick comments (1)
landing-page/pages/index.tsx (1)

166-182: Enhance clipboard error handling with user feedback.

While error handling exists, it only logs to console. Users should receive visual feedback when operations fail.

Consider adding a toast notification or inline error message:

 const handleCopy = (e: React.MouseEvent) => {
   e.stopPropagation();
   navigator.clipboard
     .writeText(`!submit @curatedotfun #${tag}`)
     .then(
       () => {
         setCopied(true);
         setTimeout(() => setCopied(false), 2000);
       },
       () => {
-        console.error("Failed to copy text to clipboard");
+        setError("Failed to copy to clipboard");
+        setTimeout(() => setError(null), 2000);
       },
     )
     .catch((error) => {
-      console.error("Failed to copy text to clipboard", error);
+      setError("Failed to copy to clipboard");
+      setTimeout(() => setError(null), 2000);
     });
 };
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 017b93f and 0b9e043.

📒 Files selected for processing (2)
  • landing-page/data/tweets.json (1 hunks)
  • landing-page/pages/index.tsx (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • landing-page/data/tweets.json
🧰 Additional context used
🪛 Biome (1.9.4)
landing-page/pages/index.tsx

[error] 301-301: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

Comment on lines +76 to +147
const PARTNERS = [
{
href: "#",
img: "/assets/images/communities/community1.png",
alt: "Community #2",
},
{
href: "#",
img: "/assets/images/communities/community2.png",
alt: "Community #2",
},
{
href: "https://near.org/",
img: "/assets/images/communities/near.png",
alt: "Near Protocol",
},
{
href: "https://ethereum.org",
img: "/assets/images/communities/eth.svg",
alt: "Ethereum",
},
{
href: "https://nearweek.com",
img: "/assets/images/communities/nearweek.svg",
alt: "Near Week",
},
{
href: "#",
img: "/assets/images/communities/community3.png",
alt: "Community #3",
},
{
href: "https://t.me/cryptograntwire",
img: "/assets/images/communities/cryptograntwire.svg",
alt: "Crypto Grant Wire",
},
{
href: "#",
img: "/assets/images/communities/community4.png",
alt: "Community #4",
},
{
href: "https://alpha.potlock.org",
img: "/assets/images/communities/potlock.svg",
alt: "PotLock",
},
{
href: "https://www.refidao.com/",
img: "/assets/images/communities/refi_dao.png",
alt: "Refi DAO",
},
{
href: "https://www.gitcoin.co/",
img: "/assets/images/communities/gitcoin_dao.png",
alt: "GitCoin DAO",
},
{
href: "#",
img: "/assets/images/communities/community5.png",
alt: "Community #5",
},
{
href: "https://ethereum.org",
img: "/assets/images/communities/acf_logo.png",
alt: "American Crypto Foundation",
},
{
href: "#",
img: "/assets/images/communities/community6.png",
alt: "Community 6",
},
];
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve partner entries with meaningful links and descriptions.

Several partner entries use placeholder links (#) and generic alt texts, which impacts accessibility and SEO.

Consider updating the entries with:

  1. Valid URLs instead of "#" placeholders
  2. Descriptive alt texts instead of generic "Community #N"
  3. Consistent naming convention for image files
 {
-  href: "#",
-  img: "/assets/images/communities/community1.png",
-  alt: "Community #2",
+  href: "https://example.com/partner1",
+  img: "/assets/images/communities/partner1.png",
+  alt: "Partner Name - Brief Description",
 },
📝 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 PARTNERS = [
{
href: "#",
img: "/assets/images/communities/community1.png",
alt: "Community #2",
},
{
href: "#",
img: "/assets/images/communities/community2.png",
alt: "Community #2",
},
{
href: "https://near.org/",
img: "/assets/images/communities/near.png",
alt: "Near Protocol",
},
{
href: "https://ethereum.org",
img: "/assets/images/communities/eth.svg",
alt: "Ethereum",
},
{
href: "https://nearweek.com",
img: "/assets/images/communities/nearweek.svg",
alt: "Near Week",
},
{
href: "#",
img: "/assets/images/communities/community3.png",
alt: "Community #3",
},
{
href: "https://t.me/cryptograntwire",
img: "/assets/images/communities/cryptograntwire.svg",
alt: "Crypto Grant Wire",
},
{
href: "#",
img: "/assets/images/communities/community4.png",
alt: "Community #4",
},
{
href: "https://alpha.potlock.org",
img: "/assets/images/communities/potlock.svg",
alt: "PotLock",
},
{
href: "https://www.refidao.com/",
img: "/assets/images/communities/refi_dao.png",
alt: "Refi DAO",
},
{
href: "https://www.gitcoin.co/",
img: "/assets/images/communities/gitcoin_dao.png",
alt: "GitCoin DAO",
},
{
href: "#",
img: "/assets/images/communities/community5.png",
alt: "Community #5",
},
{
href: "https://ethereum.org",
img: "/assets/images/communities/acf_logo.png",
alt: "American Crypto Foundation",
},
{
href: "#",
img: "/assets/images/communities/community6.png",
alt: "Community 6",
},
];
const PARTNERS = [
{
href: "https://example.com/partner1",
img: "/assets/images/communities/partner1.png",
alt: "Partner Name - Brief Description",
},
{
href: "#",
img: "/assets/images/communities/community2.png",
alt: "Community #2",
},
{
href: "https://near.org/",
img: "/assets/images/communities/near.png",
alt: "Near Protocol",
},
{
href: "https://ethereum.org",
img: "/assets/images/communities/eth.svg",
alt: "Ethereum",
},
{
href: "https://nearweek.com",
img: "/assets/images/communities/nearweek.svg",
alt: "Near Week",
},
{
href: "#",
img: "/assets/images/communities/community3.png",
alt: "Community #3",
},
{
href: "https://t.me/cryptograntwire",
img: "/assets/images/communities/cryptograntwire.svg",
alt: "Crypto Grant Wire",
},
{
href: "#",
img: "/assets/images/communities/community4.png",
alt: "Community #4",
},
{
href: "https://alpha.potlock.org",
img: "/assets/images/communities/potlock.svg",
alt: "PotLock",
},
{
href: "https://www.refidao.com/",
img: "/assets/images/communities/refi_dao.png",
alt: "Refi DAO",
},
{
href: "https://www.gitcoin.co/",
img: "/assets/images/communities/gitcoin_dao.png",
alt: "GitCoin DAO",
},
{
href: "#",
img: "/assets/images/communities/community5.png",
alt: "Community #5",
},
{
href: "https://ethereum.org",
img: "/assets/images/communities/acf_logo.png",
alt: "American Crypto Foundation",
},
{
href: "#",
img: "/assets/images/communities/community6.png",
alt: "Community 6",
},
];

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 (1)
landing-page/pages/index.tsx (1)

166-182: Enhance error handling for clipboard operations.

While error handling is implemented, it only logs to console. Consider providing user feedback for failed operations.

 const handleCopy = (e: React.MouseEvent) => {
   e.stopPropagation();
   navigator.clipboard
     .writeText(`!submit @curatedotfun #${tag}`)
     .then(
       () => {
         setCopied(true);
         setTimeout(() => setCopied(false), 2000);
       },
       () => {
-        console.error("Failed to copy text to clipboard");
+        alert('Failed to copy to clipboard. Please try manually.');
       },
     )
     .catch((error) => {
-      console.error("Failed to copy text to clipboard", error);
+      alert('Failed to copy to clipboard. Please try manually.');
     });
 };
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 0b9e043 and 0fce1bd.

📒 Files selected for processing (1)
  • landing-page/pages/index.tsx (5 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
landing-page/pages/index.tsx

[error] 301-301: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

🔇 Additional comments (4)
landing-page/pages/index.tsx (4)

76-147: Improve partner entries with meaningful links and descriptions.

Several partner entries use placeholder links (#) and generic alt texts, which impacts accessibility and SEO.


489-496: Use anchor tags for external links instead of Next.js Link component.

The Next.js Link component is being used for external URLs, which is not recommended.

Also applies to: 512-518, 519-525, 965-971, 972-980


894-899: ⚠️ Potential issue

Fix duplicate content in Content Engine description.

The Content Engine description is identical to the Curate Engine section.

-<p className="font-['PT_Root_UI'] text-[#57606A] text-[18px] leading-[30px] font-normal text-center md:text-left">
-  Pull posts, threads, and videos from Twitter, Telegram, and
-  more. Organize everything into smart feeds that update
-  automatically, so you're always sharing fresh, relevant
-  content.
-</p>
+<p className="font-['PT_Root_UI'] text-[#57606A] text-[18px] leading-[30px] font-normal text-center md:text-left">
+  Transform curated content into engaging formats using AI.
+  Generate summaries, threads, and newsletters automatically
+  while maintaining your brand voice and style.
+</p>

Likely invalid or redundant comment.


226-252: ⚠️ Potential issue

Remove duplicate FAQ entry.

There are two entries for "How does it work?" with different answers.

 const faqs = [
   {
     question: "What is curate.fun?",
     answer: "Curate.fun is a platform designed to streamline content curation and sharing.",
   },
   {
     question: "How do I get a feed?",
     answer: "You can get a feed by signing up and selecting your preferred sources.",
   },
   {
     question: "How does it work?",
-    answer: "The curate.fun is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
+    answer: "Curate.fun uses AI to curate and summarize content from various sources. It is part of the potluck ecosystem and tokenomics will be baked in with the $GRANTS ecosystem token.",
   },
   {
     question: "How can you add support?",
     answer: "You can add support by contributing to our <a class='hyperlink' href='https://github.com/potlock/curatedotfun' target='_blank' rel='noopener noreferrer'>GitHub repository</a> or joining our community.",
   },
-  {
-    question: "How does it work?",
-    answer: "Curate.fun uses AI to curate and summarize content from various sources.",
-  },
 ];

Likely invalid or redundant comment.

Comment on lines +299 to +302
<p
className="mt-2 text-gray-600 flex-1"
dangerouslySetInnerHTML={{ __html: faq.answer }}
/>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace dangerouslySetInnerHTML with a safer alternative.

Using dangerouslySetInnerHTML can expose users to XSS attacks.

First, install DOMPurify:

npm install dompurify @types/dompurify

Then apply this diff:

-<p
-  className="mt-2 text-gray-600 flex-1"
-  dangerouslySetInnerHTML={{ __html: faq.answer }}
-/>
+<p className="mt-2 text-gray-600 flex-1">
+  <SafeHTML html={faq.answer} />
+</p>

Create a SafeHTML component:

import DOMPurify from 'dompurify';

const SafeHTML = ({ html }: { html: string }) => (
  <span dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(html) }} />
);
🧰 Tools
🪛 Biome (1.9.4)

[error] 301-301: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

@codingshot codingshot merged commit e44b302 into main Feb 7, 2025
6 checks passed
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.

2 participants