-
Notifications
You must be signed in to change notification settings - Fork 30
feat: Built BountyCard component with shadcn composition #17
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
Changes from 2 commits
8efab73
b1bbbf2
97b9c87
7f40ae5
472495b
8b74d84
b40b19c
f487bb9
328ba0b
6a8fdc9
dc49879
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,15 @@ | ||
| import SignIn from "@/components/login/sign-in"; | ||
| import Image from "next/image"; | ||
|
|
||
|
|
||
|
|
||
| export default async function Home() { | ||
| return ( | ||
| <div className="flex justify-center items-center h-screen"> | ||
| <SignIn /> | ||
|
|
||
| </div> | ||
|
|
||
|
|
||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,232 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import * as React from "react"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import * as React from "react"; |
Outdated
Copilot
AI
Jan 24, 2026
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.
CardContent is imported but never used, which will trigger lint/build failures. Remove the import or refactor the layout to use CardContent.
| CardContent, |
Outdated
Copilot
AI
Jan 24, 2026
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.
DollarSign is imported from lucide-react but never used, which will trigger lint/build failures. Remove it or render it as part of the budget display.
| import { Clock, Users, DollarSign } from "lucide-react"; | |
| import { Clock, Users } from "lucide-react"; |
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
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.
Guard against unmapped bounty statuses.
statusConfig only covers open/claimed/closed. If the API sends another status (e.g., in‑progress/disputed per requirements), status becomes undefined and the render will throw. Add mappings for all statuses and/or a safe fallback.
🩹 Suggested hardening
- const status = statusConfig[bounty.status];
+ const status =
+ statusConfig[bounty.status] ?? {
+ variant: "outline",
+ label: "Unknown",
+ dotColor: "bg-slate-400",
+ };📝 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.
| const statusConfig = { | |
| open: { | |
| variant: "default" as const, | |
| label: "Open", | |
| dotColor: "bg-emerald-500", | |
| }, | |
| claimed: { | |
| variant: "secondary" as const, | |
| label: "Claimed", | |
| dotColor: "bg-amber-500", | |
| }, | |
| closed: { | |
| variant: "outline" as const, | |
| label: "Closed", | |
| dotColor: "bg-slate-400", | |
| }, | |
| }; | |
| const difficultyColors: Record<string, string> = { | |
| beginner: "text-success-400", | |
| intermediate: "text-warning-400", | |
| advanced: "text-error-400", | |
| } | |
| export function BountyCard({ | |
| bounty, | |
| onClick, | |
| variant = "grid", | |
| }: BountyCardProps) { | |
| const status = statusConfig[bounty.status]; | |
| const statusConfig = { | |
| open: { | |
| variant: "default" as const, | |
| label: "Open", | |
| dotColor: "bg-emerald-500", | |
| }, | |
| claimed: { | |
| variant: "secondary" as const, | |
| label: "Claimed", | |
| dotColor: "bg-amber-500", | |
| }, | |
| closed: { | |
| variant: "outline" as const, | |
| label: "Closed", | |
| dotColor: "bg-slate-400", | |
| }, | |
| }; | |
| export function BountyCard({ | |
| bounty, | |
| onClick, | |
| variant = "grid", | |
| }: BountyCardProps) { | |
| const status = | |
| statusConfig[bounty.status] ?? { | |
| variant: "outline", | |
| label: "Unknown", | |
| dotColor: "bg-slate-400", | |
| }; |
🤖 Prompt for AI Agents
In `@components/bounty/bounty-card.tsx` around lines 23 - 46, The statusConfig
mapping and its use in BountyCard can return undefined for unexpected
bounty.status values; update statusConfig to include all possible statuses
(e.g., "in-progress", "disputed", etc.) and/or add a safe fallback before
rendering: compute a resolvedStatus = statusConfig[bounty.status] ?? /* default
mapping like closed/default */ and use resolvedStatus in the component. Ensure
the symbols referenced are statusConfig, BountyCard and the variable status (or
replace with resolvedStatus) so unknown API statuses won't cause a render error.
Outdated
Copilot
AI
Jan 24, 2026
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.
The classes w-xs and rounded-4xl look like they may be no-ops with the current Tailwind theme setup (e.g., app/globals.css only defines radius tokens up to --radius-xl, and there’s no --radius-4xl). If these utilities aren’t defined, the card won’t size/round as intended. Prefer standard utilities (e.g., w-full/max-w-*, rounded-xl/rounded-3xl) or an explicit arbitrary value (e.g., rounded-[...]).
Outdated
Copilot
AI
Jan 24, 2026
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.
In the list variant, md:flex-row is applied to the outer Card, which will place the footer beside the main content on medium screens (since CardFooter is a sibling). If the footer is intended to remain at the bottom, keep the Card as a column layout and only apply row layout to the internal content area.
| variant === "list" && "flex flex-col md:flex-row", | |
| variant === "list" && "flex flex-col", |
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.
List variant is still capped to max-w-xs.
With max-w-xs applied unconditionally, the list layout won’t expand to full width, which undermines the list variant’s responsive intent.
💡 Proposed fix
- className={cn(
- "overflow-hidden w-full max-w-xs rounded-4xl cursor-pointer transition-all duration-300",
+ className={cn(
+ "overflow-hidden w-full rounded-4xl cursor-pointer transition-all duration-300",
+ variant === "grid" && "max-w-xs",
+ variant === "list" && "max-w-none",
"hover:shadow-lg hover:border-primary/60 hover:scale-[1.02]",
"border border-slate-200 dark:border-slate-800",
variant === "list" && "flex flex-col",
)}📝 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.
| className={cn( | |
| "overflow-hidden w-full max-w-xs rounded-4xl cursor-pointer transition-all duration-300", | |
| "hover:shadow-lg hover:border-primary/60 hover:scale-[1.02]", | |
| "border border-slate-200 dark:border-slate-800", | |
| variant === "list" && "flex flex-col", | |
| )} | |
| className={cn( | |
| "overflow-hidden w-full rounded-4xl cursor-pointer transition-all duration-300", | |
| variant === "grid" && "max-w-xs", | |
| variant === "list" && "max-w-none", | |
| "hover:shadow-lg hover:border-primary/60 hover:scale-[1.02]", | |
| "border border-slate-200 dark:border-slate-800", | |
| variant === "list" && "flex flex-col", | |
| )} |
🤖 Prompt for AI Agents
In `@components/bounty/bounty-card.tsx` around lines 99 - 104, The card always
applies "max-w-xs" which prevents the list variant from expanding; update the
className construction in bounty-card.tsx (the cn(...) call where variant ===
"list" is checked) to apply "max-w-xs" only when variant !== "list" (or
alternatively apply a full-width class like "w-full" when variant === "list"),
so the list variant can use the full available width while preserving the
compact cap for other variants.
Copilot
AI
Jan 24, 2026
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.
Attaching onClick to a div-based Card makes it mouse-only by default. For accessibility, either render a semantic interactive element (e.g., <button>/<a> via asChild) or add role="button", tabIndex={0}, and keyboard handlers for Enter/Space (plus an accessible label if needed).
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.
There are several extra blank lines added here that don’t change behavior but add noise to the diff. Please remove the redundant whitespace to keep the file clean.