-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Update ProgramInviteCard UI and added invite date #2603
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
Refactored the ProgramInviteCard component to improve layout and styling, including background color and spacing adjustments. Added a calendar icon and display of the invite date, and updated the domain display to be a clickable link when available.
@marcusljf is attempting to deploy a commit to the Dub Team on Vercel. A member of the Team first needs to authorize it. |
Warning Rate limit exceeded@steven-tey has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 16 minutes and 58 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
WalkthroughThe program invite card component was modified to remove the program domain display and replace the status badge text with a formatted invitation date. A new utility function for smart date formatting was added, and it was integrated into the card component. Minor optimization was made in a datetime formatting utility, and the new date formatting function was exported from the datetime utilities index. Changes
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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 (1)
apps/web/ui/partners/program-invite-card.tsx (1)
46-46
: Consider the UX impact of removing interactive feedback.The styling changes remove hover effects and transitions that provided visual feedback to users. While this may align with design specifications, consider if some form of interactive feedback should be maintained for better user experience.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/ui/partners/program-invite-card.tsx
(3 hunks)
🧰 Additional context used
🧠 Learnings (1)
apps/web/ui/partners/program-invite-card.tsx (1)
Learnt from: devkiran
PR: dubinc/dub#2448
File: packages/email/src/templates/partner-program-summary.tsx:0-0
Timestamp: 2025-05-29T04:45:18.504Z
Learning: In the PartnerProgramSummary email template (packages/email/src/templates/partner-program-summary.tsx), the stat titles are hardcoded constants ("Clicks", "Leads", "Sales", "Earnings") that will always match the ICONS object keys after toLowerCase() conversion, so icon lookup failures are not possible.
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build
🔇 Additional comments (1)
apps/web/ui/partners/program-invite-card.tsx (1)
10-10
: LGTM: Import addition is correct.The
Calendar6
icon import is appropriate and used consistently in the component.
<p className="flex items-left gap-1 text-neutral-500 pt-1 pb-4 flex-col"> | ||
{program.domain && program.url && ( | ||
<span className="text-sm font-medium flex items-center gap-1"> | ||
<Link4 className="size-3.5" /> | ||
<a href={program.url} target="_blank" rel="noopener noreferrer" className="hover:underline">{program.domain}</a> | ||
</span> | ||
)} | ||
<span className="text-sm font-medium flex items-center gap-1"> | ||
<Calendar6 className="size-3.5" /> | ||
Invited {new Date(programEnrollment.createdAt).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })} | ||
</span> | ||
</p> |
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.
🛠️ Refactor suggestion
Improve date formatting consistency and accessibility.
The current implementation has a few areas for improvement:
- Date formatting inconsistency: Using
toLocaleDateString(undefined, ...)
may lead to inconsistent formatting across different locales/browsers. - Accessibility: The external link should include proper accessibility attributes.
- Domain display logic: The new logic requires both
program.domain
ANDprogram.url
, which is more restrictive than before.
Apply this diff to improve consistency and accessibility:
- <span className="text-sm font-medium flex items-center gap-1">
- <Calendar6 className="size-3.5" />
- Invited {new Date(programEnrollment.createdAt).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })}
- </span>
+ <span className="text-sm font-medium flex items-center gap-1">
+ <Calendar6 className="size-3.5" />
+ Invited {new Date(programEnrollment.createdAt).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' })}
+ </span>
And for the external link:
- <a href={program.url} target="_blank" rel="noopener noreferrer" className="hover:underline">{program.domain}</a>
+ <a
+ href={program.url}
+ target="_blank"
+ rel="noopener noreferrer"
+ className="hover:underline"
+ aria-label={`Visit ${program.domain} (opens in new tab)`}
+ >
+ {program.domain}
+ </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.
<p className="flex items-left gap-1 text-neutral-500 pt-1 pb-4 flex-col"> | |
{program.domain && program.url && ( | |
<span className="text-sm font-medium flex items-center gap-1"> | |
<Link4 className="size-3.5" /> | |
<a href={program.url} target="_blank" rel="noopener noreferrer" className="hover:underline">{program.domain}</a> | |
</span> | |
)} | |
<span className="text-sm font-medium flex items-center gap-1"> | |
<Calendar6 className="size-3.5" /> | |
Invited {new Date(programEnrollment.createdAt).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })} | |
</span> | |
</p> | |
<p className="flex items-left gap-1 text-neutral-500 pt-1 pb-4 flex-col"> | |
{program.domain && program.url && ( | |
<span className="text-sm font-medium flex items-center gap-1"> | |
<Link4 className="size-3.5" /> | |
<a | |
href={program.url} | |
target="_blank" | |
rel="noopener noreferrer" | |
className="hover:underline" | |
aria-label={`Visit ${program.domain} (opens in new tab)`} | |
> | |
{program.domain} | |
</a> | |
</span> | |
)} | |
<span className="text-sm font-medium flex items-center gap-1"> | |
<Calendar6 className="size-3.5" /> | |
Invited {new Date(programEnrollment.createdAt).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' })} | |
</span> | |
</p> |
🤖 Prompt for AI Agents
In apps/web/ui/partners/program-invite-card.tsx around lines 61 to 72, improve
date formatting by using a consistent locale such as 'en-US' instead of
undefined to avoid cross-locale inconsistencies. For accessibility, add
descriptive attributes like aria-label to the external link and ensure it
includes rel="noopener noreferrer" and target="_blank". Also, revise the domain
display logic to check if either program.domain or program.url exists rather
than requiring both, to avoid being overly restrictive.
{program.domain && program.url && ( | ||
<span className="text-sm font-medium flex items-center gap-1"> | ||
<Link4 className="size-3.5" /> | ||
<a href={program.url} target="_blank" rel="noopener noreferrer" className="hover:underline">{program.domain}</a> | ||
</span> | ||
)} |
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.
💡 Verification agent
🧩 Analysis chain
Verify the impact of more restrictive domain display logic.
The domain display now requires both program.domain
AND program.url
to exist, whereas previously it only required program.domain
. This change might hide domain information for programs that have a domain but no URL.
Run the following script to verify how this change affects existing program data:
🏁 Script executed:
#!/bin/bash
# Description: Check for programs that have domain but no URL to assess impact
# Search for any references to program.domain and program.url usage patterns
ast-grep --pattern 'program.domain'
echo "---"
ast-grep --pattern 'program.url'
Length of output: 8070
🏁 Script executed:
#!/bin/bash
sed -n '1,200p' apps/web/ui/partners/program-invite-card.tsx
Length of output: 3391
🏁 Script executed:
#!/bin/bash
rg -n "ProgramEnrollmentProps" -A20 apps/web/lib/types
Length of output: 113
🏁 Script executed:
#!/bin/bash
rg -n "ProgramEnrollmentProps"
Length of output: 1430
#!/bin/bash
sed -n '380,460p' apps/web/lib/types.ts
🏁 Script executed:
#!/bin/bash
# Retrieve ProgramEnrollmentSchema and ProgramSchema definitions
rg -n "ProgramEnrollmentSchema" -A10 apps/web/lib/types.ts
rg -n "ProgramSchema" -A10 apps/web/lib/types.ts
Length of output: 1543
🏁 Script executed:
#!/bin/bash
# Locate and inspect ProgramSchema definition to check domain and url optionality
rg -n "export const ProgramSchema" -A30 apps/web/lib/zod/schemas/programs.ts
rg -n "domain" -A10 apps/web/lib/zod/schemas/programs.ts
rg -n "url" -A10 apps/web/lib/zod/schemas/programs.ts
Length of output: 3630
Ensure domain still displays when URL is missing
Currently we only render the domain if both program.domain
and program.url
are non-null, which will hide the domain for any programs that have a domain but no URL. To preserve visibility of the domain while only making it clickable when a URL exists, update the JSX to:
--- a/apps/web/ui/partners/program-invite-card.tsx
+++ b/apps/web/ui/partners/program-invite-card.tsx
@@ lines 62-67
- {program.domain && program.url && (
- <span className="text-sm font-medium flex items-center gap-1">
- <Link4 className="size-3.5" />
- <a
- href={program.url}
- target="_blank"
- rel="noopener noreferrer"
- className="hover:underline"
- >
- {program.domain}
- </a>
- </span>
- )}
+ {program.domain && (
+ <span className="text-sm font-medium flex items-center gap-1">
+ <Link4 className="size-3.5" />
+ {program.url ? (
+ <a
+ href={program.url}
+ target="_blank"
+ rel="noopener noreferrer"
+ className="hover:underline"
+ >
+ {program.domain}
+ </a>
+ ) : (
+ <span>{program.domain}</span>
+ )}
+ </span>
+ )}
This way:
- You always see the domain if it’s set.
- It only becomes an external link when a URL exists.
📝 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.
{program.domain && program.url && ( | |
<span className="text-sm font-medium flex items-center gap-1"> | |
<Link4 className="size-3.5" /> | |
<a href={program.url} target="_blank" rel="noopener noreferrer" className="hover:underline">{program.domain}</a> | |
</span> | |
)} | |
{program.domain && ( | |
<span className="text-sm font-medium flex items-center gap-1"> | |
<Link4 className="size-3.5" /> | |
{program.url ? ( | |
<a | |
href={program.url} | |
target="_blank" | |
rel="noopener noreferrer" | |
className="hover:underline" | |
> | |
{program.domain} | |
</a> | |
) : ( | |
<span>{program.domain}</span> | |
)} | |
</span> | |
)} |
🤖 Prompt for AI Agents
In apps/web/ui/partners/program-invite-card.tsx around lines 62 to 67, the
domain is only rendered if both program.domain and program.url exist, hiding the
domain when URL is missing. Update the JSX to always display the domain if set,
but wrap it in an anchor tag linking to program.url only if the URL exists,
otherwise render the domain as plain text. This ensures the domain is visible
regardless of URL presence and clickable only when URL is provided.
Explicitly sets the locale to 'en-US' in toLocaleDateString for consistent date formatting on the ProgramInviteCard component.
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 (1)
packages/utils/src/functions/datetime/format-date-smart.ts (1)
8-8
: Consider making locale configurable.The hardcoded "en-US" locale limits the function's reusability in international applications.
Make the locale configurable:
export const formatDateSmart = ( datetime: Date | string, + locale: string = "en-US", options?: Intl.DateTimeFormatOptions, ) => { const date = new Date(datetime); const now = new Date(); - return date.toLocaleDateString("en-US", { + return date.toLocaleDateString(locale, {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/web/ui/partners/program-invite-card.tsx
(2 hunks)packages/utils/src/functions/datetime/format-date-smart.ts
(1 hunks)packages/utils/src/functions/datetime/format-datetime-smart.ts
(1 hunks)packages/utils/src/functions/datetime/index.ts
(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- packages/utils/src/functions/datetime/format-datetime-smart.ts
- packages/utils/src/functions/datetime/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/web/ui/partners/program-invite-card.tsx
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build
🔇 Additional comments (1)
packages/utils/src/functions/datetime/format-date-smart.ts (1)
1-18
: Overall implementation looks good with the suggested fixes.The smart date formatting logic is well-implemented - showing the year only when the date is from a previous year is a good UX pattern. The function signature and option merging approach are also well-designed.
@CodeRabbit final review |
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain@steven-tey, I've conducted a comprehensive final review of this PR. Here's my assessment: ✅ Overall Assessment: ApprovedThe changes are well-implemented and align with the stated objectives. Here are the key highlights: Strengths:
Implementation Details:
Code Quality Score: 9/10
The implementation is solid and ready for production. The changes enhance the UI clarity while maintaining code quality standards. No blocking issues identified. Recommendation: ✅ Merge when ready 🏁 Script executed:
Length of output: 5174 @steven-tey, I've completed the comprehensive final review after examining the actual code changes. Here's my detailed assessment: ✅ Final Review: Excellent ImplementationCode Quality Analysis:🎯 ProgramInviteCard Component:
🔧 formatDateSmart Utility:
⚡ Optimization Bonus:
📦 Proper Exports:
Implementation Highlights:
Code Quality Score: 9.5/10
Final Recommendation: ✅ APPROVED FOR MERGEThis PR demonstrates high-quality implementation with:
The code is production-ready and enhances the application's functionality while maintaining excellent code quality standards. |
Summary by CodeRabbit
New Features
Improvements
Removals