-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Add Bullish Market Card Component with Dynamic Sentiment Bars #22
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
Conversation
WalkthroughTop-level layout/header removed from src/app/page.tsx. Added a new BullishMarketCard component and inserted it into PostsList between PostFilters and PostGallery. PostGallery alignment updated from center to start with added left margin. BullishMarketCard uses local mock data and no external fetching. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Page as Next.js Page (app/page.tsx)
participant PostsList as PostsList
participant Filters as PostFilters
participant Card as BullishMarketCard
participant Gallery as PostGallery
User->>Page: GET /
Page->>PostsList: render PostsList
PostsList->>Filters: render PostFilters
PostsList->>Card: render BullishMarketCard
Note right of Card #DCEFEF: compute sentiment percentages\ncompute minutesAgo (mock updatedAt)
Card-->>PostsList: Card JSX
PostsList->>Gallery: render PostGallery (left-aligned)
PostsList-->>Page: composed JSX
Page-->>User: HTML
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
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.
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. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (5)
src/components/PostComponents/PostsList.tsx (1)
105-107
: Keep PostsList focused; consider moving the card out.PostsList is a data list + infinite scroll. Embedding a dashboard summary mixes concerns. Prefer rendering the card at the page/section container level (or via a header component) and keep PostsList purely for posts.
src/components/HomepageComponents/BullishMarketCard.tsx (4)
21-37
: Avoidthis
in object literal accessors; harden typing and clamp minutes.
this
in object literals can tripnoImplicitThis
and is brittle. Also guard against negative minutes.Apply:
- get sentimentPercentages(): { + get sentimentPercentages(): { BULLISH: number; NEUTRAL: number; BEARISH: number; } { - const { BULLISH, NEUTRAL, BEARISH } = this.sentimentCounts; + const { BULLISH, NEUTRAL, BEARISH } = MockData.sentimentCounts; const total = BULLISH + NEUTRAL + BEARISH; return { BULLISH: Math.round((BULLISH / total) * 100), NEUTRAL: Math.round((NEUTRAL / total) * 100), BEARISH: Math.round((BEARISH / total) * 100), }; }, updatedAt: new Date('2025-09-16T09:55:00Z'), // Fixed date for SSR compatibility get minutesAgo() { - return Math.floor((Date.now() - this.updatedAt.getTime()) / 60000); + const mins = Math.floor((Date.now() - MockData.updatedAt.getTime()) / 60000); + return Math.max(0, mins); },Optional: compute once in render to avoid re-running the getter several times:
export default function BullishMarketCard() { - return ( + const perc = MockData.sentimentPercentages; + return (…and use
perc.BULLISH
/perc.NEUTRAL
/perc.BEARISH
below.
43-44
: Make the card responsive without fixed widths.
w-[500px]
will overflow small screens. Prefer fluid width with a max.Apply:
- <Card className="flex w-[500px] h-[240px] md:w-[800px] bg-gradient-to-r from-green-50 to-white border-l-green-500"> + <Card className="flex w-full max-w-[800px] min-h-[240px] bg-gradient-to-r from-green-50 to-white border-l-green-500">
56-75
: Color-only encoding; add non-color cues and dark-mode tokens.Consider using semantic tokens (e.g., text-success/ text-destructive) and add icons or patterns so meaning isn’t solely by color. Add dark: variants for the gradient.
100-107
: Pluralization for “minute(s)”.Small UX nit: handle 1 minute vs minutes.
Apply:
- Updated {MockData.minutesAgo} minutes ago + Updated {MockData.minutesAgo} {MockData.minutesAgo === 1 ? "minute" : "minutes"} ago
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/app/page.tsx
(0 hunks)src/components/HomepageComponents/BullishMarketCard.tsx
(1 hunks)src/components/PostComponents/PostsList.tsx
(2 hunks)
💤 Files with no reviewable changes (1)
- src/app/page.tsx
🧰 Additional context used
🧬 Code graph analysis (2)
src/components/HomepageComponents/BullishMarketCard.tsx (1)
src/components/ui/card.tsx (7)
Card
(91-91)CardHeader
(92-92)CardTitle
(94-94)CardAction
(95-95)CardDescription
(96-96)CardContent
(97-97)CardFooter
(93-93)
src/components/PostComponents/PostsList.tsx (1)
src/components/HomepageComponents/BullishMarketCard.tsx (1)
BullishMarketCard
(40-112)
🔇 Additional comments (1)
src/components/HomepageComponents/BullishMarketCard.tsx (1)
1-12
: Mark component as client.File src/components/HomepageComponents/BullishMarketCard.tsx is not marked "use client" but uses Date (new Date + Date.now) to compute minutesAgo. Add "use client" at the top if this component is imported by a client component or requires client-side runtime updates. Repo search showed no imports of BullishMarketCard — verify its usage.
Apply:
+ "use client"; + import { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from "../ui/card"; import { FaRegChartBar } from "react-icons/fa"; import { CiCalendar } from "react-icons/ci";
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (7)
src/components/PostComponents/PostGallery.tsx (3)
194-194
: Fix invalid Tailwind class: use arbitrary value or scale token instead of ml-30.Tailwind doesn’t ship with ml-30 by default. Use an arbitrary value or a supported token.
- <div className="flex flex-row justify-start ml-30 gap-6 p-2"> + <div className="flex flex-row justify-start gap-6 p-2 ml-[30px]">Optional: prefer padding on the container or a layout wrapper over hard left margins for alignment.
195-197
: Use a stable key instead of the array index.Prevents unnecessary re-mounts/repaints when the data changes order.
- {posts.map((post, index) => ( - <SinglePostCard key={index} post={post} /> + {posts.map((post, index) => ( + <SinglePostCard key={post.title ?? index} post={post} /> ))}
109-110
: Replace non-standard width/height utilities.w-54 and h-66 aren’t in Tailwind’s default scale.
- <Card className="w-54 h-66 font-sans"> + <Card className="w-56 h-64 font-sans">Alternatively, use exact pixels via arbitrary values (e.g., w-[216px] h-[256px]).
src/components/HomepageComponents/BullishMarketCard.tsx (4)
44-44
: Replace invalid border utility and improve responsiveness.border-5 isn’t a default Tailwind class; also make the card width responsive.
- <Card className="flex w-[500px] h-[240px] md:w-[950px] bg-gradient-to-r from-green-50 to-white border-l-green-500 border-5"> + <Card className="flex w-full max-w-[950px] h-[240px] bg-gradient-to-r from-green-50 to-white border border-l-[5px] border-l-green-500">If you want only the left border visible, use transparent borders elsewhere:
- <Card className="flex w-full max-w-[950px] h-[240px] bg-gradient-to-r from-green-50 to-white border border-l-[5px] border-l-green-500"> + <Card className="flex w-full max-w-[950px] h-[240px] bg-gradient-to-r from-green-50 to-white border border-transparent border-l-[5px] border-l-green-500">
52-55
: Format large numbers for readability.- <span className="font-bold text-[11px]"> - {MockData.totalSourceCount} Sources + <span className="font-bold text-[11px]"> + {MockData.totalSourceCount.toLocaleString()} Sources </span>
36-38
: Guard against negative times if updatedAt is in the future.- get minutesAgo() { - return Math.floor((Date.now() - this.updatedAt.getTime()) / 60000); - }, + get minutesAgo() { + return Math.max(0, Math.floor((Date.now() - this.updatedAt.getTime()) / 60000)); + },
125-131
: Expose machine-readable timestamp.Wrap the text in a time element with dateTime for a11y/SEO.
- <span className="text-muted-foreground text-xs"> - Updated {MockData.minutesAgo} minutes ago - </span> + <time + className="text-muted-foreground text-xs" + dateTime={MockData.updatedAt.toISOString()} + aria-label={`Last updated ${MockData.minutesAgo} minutes ago`} + > + Updated {MockData.minutesAgo} minutes ago + </time>
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/components/HomepageComponents/BullishMarketCard.tsx
(1 hunks)src/components/PostComponents/PostGallery.tsx
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/components/HomepageComponents/BullishMarketCard.tsx (1)
src/components/ui/card.tsx (7)
Card
(91-91)CardHeader
(92-92)CardTitle
(94-94)CardAction
(95-95)CardDescription
(96-96)CardContent
(97-97)CardFooter
(93-93)
🔇 Additional comments (1)
src/components/HomepageComponents/BullishMarketCard.tsx (1)
81-103
: Progress bars a11y and display: looks good.Bars are block-level with ARIA attributes and no conflicting fixed widths.
Also applies to: 109-117
Description:
This PR introduces the
BullishMarketCard
component, which displays overall market sentiment statistics using mock data. The card features dynamic percentage bars for bullish, neutral, and bearish sentiments, a total source count, and a timestamp for the last update. The component supports both light and dark mode color variables and uses CSS variables for easy theming. This addition enhances the dashboard with a visually informative summary of aggregated sentiment data.Summary by CodeRabbit
New Features
Style