Feat : Enable click-to-copy for email address and adding slack icon in footer - #190
Conversation
✅ Deploy Preview for cv-community-dashboard ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
WalkthroughA new client-side React component CopyEmailButton was added that copies support@circuitverse.org to the clipboard on click, shows a temporary "Email Copied!" indicator, handles clipboard errors, and clears timers on unmount. The footer was updated to use this component and the email mailto UI was replaced with a copy-to-clipboard interaction; the Slack link/icon was adjusted accordingly. 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
🧰 Additional context used🧬 Code graph analysis (1)components/footer.tsx (1)
🔇 Additional comments (2)
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.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In @components/copy-email-button.tsx:
- Line 41: The JSX element rendering the Hint component (Hint label="Email")
contains trailing whitespace after the closing '>' which should be removed; edit
the JSX in components/copy-email-button.tsx where the Hint component is rendered
and delete the trailing spaces so the tag reads without extra whitespace
directly after the '>' to keep the markup clean.
- Around line 21-37: handleCopy currently assumes navigator.clipboard exists;
add a guard that checks for navigator?.clipboard?.writeText and a secure context
before calling it, and if unavailable fall back to creating a temporary
textarea/input, set its value to EMAIL, select it, execute
document.execCommand('copy'), then clean up; in both branches setCopied(true),
clear and reset timeoutRef the same way as now and retain the existing catch
path to log failures (refer to handleCopy, navigator.clipboard.writeText, EMAIL,
timeoutRef, setCopied).
🧹 Nitpick comments (2)
components/copy-email-button.tsx (2)
7-7: Consider extracting email to config.The email address is hardcoded. While this works for the current use case, consider extracting it to the config file for easier maintenance if the email needs to change.
♻️ Example refactor
Pass the email as a prop or import from config:
-const EMAIL = "support@circuitverse.org"; +interface CopyEmailButtonProps { + email: string; +} -export default function CopyEmailButton() { +export default function CopyEmailButton({ email }: CopyEmailButtonProps) { const [copied, setCopied] = useState(false); const timeoutRef = useRef<NodeJS.Timeout | null>(null); // ... rest of component const handleCopy = async () => { try { - await navigator.clipboard.writeText(EMAIL); + await navigator.clipboard.writeText(email); setCopied(true); // ...Then update footer.tsx:
-<CopyEmailButton /> +<CopyEmailButton email={config.org.email} />
58-72: LGTM! Tooltip implementation works well.The tooltip correctly displays "Email Copied!" with styling that matches the existing Hint component. The positioning and animations should provide good user feedback.
Note: The tooltip styling duplicates the Hint component's appearance. While the current implementation works well, you could potentially explore reusing the Hint component with a dynamic label if it supports programmatic visibility control.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
components/copy-email-button.tsxcomponents/footer.tsx
🔇 Additional comments (6)
components/footer.tsx (2)
14-14: LGTM! Import is correctly placed.The import statement follows the existing pattern for local components and correctly imports the default export from the new file.
147-147: LGTM! Component integration looks clean.The CopyEmailButton is properly placed alongside other social media icons and requires no props, making it a clean integration.
components/copy-email-button.tsx (4)
1-5: LGTM! Proper client component setup.The "use client" directive is correctly placed since this component uses client-side hooks and browser APIs. All imports are necessary and properly structured.
9-11: LGTM! Proper state and ref initialization.The component correctly initializes state and refs with appropriate TypeScript types.
13-19: LGTM! Proper cleanup implementation.The useEffect correctly cleans up the timeout when the component unmounts, preventing potential memory leaks.
42-56: LGTM! Button implementation is solid.The button has proper attributes including
type="button",aria-label, and styling that matches the existing social media icons in the footer.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In @components/copy-email-button.tsx:
- Around line 44-61: In the CopyEmailButton component, the Next.js Image
instance (the <Image> used inside the Hint button) includes both width={20}
height={20} and className="w-5 h-5"; remove the redundant Tailwind sizing (w-5
h-5) from the Image's className so the component relies on width/height props
for proper Next.js image optimization, leaving other styling classes intact on
the button or Image.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
components/copy-email-button.tsx
🔇 Additional comments (3)
components/copy-email-button.tsx (3)
1-8: LGTM: Clean setup.The "use client" directive is correctly placed for client-side hooks, and the EMAIL constant provides a single source of truth.
10-19: LGTM: Proper cleanup pattern.The useEffect cleanup correctly prevents memory leaks by clearing the timeout when the component unmounts or re-renders.
63-77: LGTM: Tooltip styling and positioning.The "Email Copied!" tooltip is well-implemented with proper centering, dark/light mode support, and an arrow indicator that matches the existing Hint component pattern.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In @components/copy-email-button.tsx:
- Around line 40-55: The button's aria-label stays static ("Email") so
screen-reader users don't get feedback after copying; update the component to
track the copied state (e.g., add an isCopied state updated by handleCopy) and
render a dynamic aria-label on the button (use isCopied ? "Email copied" : "Copy
email" or similar) so the Hint/button reflects the new state; ensure you update
the handleCopy function to set isCopied and optionally reset it after a timeout
to allow repeated feedback; target the Hint-wrapped button and handleCopy when
making these changes.
🧹 Nitpick comments (2)
components/copy-email-button.tsx (2)
19-37: Consider providing user feedback for clipboard errors.The error handling correctly logs failures but provides no visual feedback to the user. If the clipboard API is unavailable or the copy operation fails, users might assume the action succeeded.
Consider showing an error tooltip or alternative feedback mechanism (e.g., "Copy failed - clipboard unavailable") to improve UX.
♻️ Example: Add error state and user feedback
const [copied, setCopied] = useState(false); + const [error, setError] = useState(false); const timeoutRef = useRef<NodeJS.Timeout | null>(null); const handleCopy = async () => { if (!navigator.clipboard) { console.error("Clipboard API not available"); + setError(true); + setTimeout(() => setError(false), 1500); return; } try { await navigator.clipboard.writeText(EMAIL); setCopied(true); + setError(false); if (timeoutRef.current) { clearTimeout(timeoutRef.current); } timeoutRef.current = setTimeout(() => { setCopied(false); timeoutRef.current = null; }, COPIED_TOOLTIP_DURATION); } catch (error) { console.error("Failed to copy email:", error); + setError(true); + setTimeout(() => setError(false), 1500); } };Then add error tooltip in the JSX (similar to the success tooltip).
38-64: Consider clarifying tooltip interaction behavior.The button is wrapped in a
Hintcomponent that displays "Email" on hover (bottom positioning), and a custom tooltip displays "Email Copied!" on click (top positioning at-top-9). While both tooltips can appear simultaneously if the user hovers and then clicks, they are positioned at different locations and the custom tooltip auto-dismisses after 1500ms, so visual conflicts are minimal. If desired, you could suppress the Hint tooltip while the copy feedback is visible by checking thecopiedstate, but the current implementation is acceptable as-is.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
components/copy-email-button.tsx
🔇 Additional comments (4)
components/copy-email-button.tsx (4)
1-5: LGTM: Clean imports and correct client directive.The "use client" directive is appropriate for this interactive component that uses browser APIs and React hooks.
7-8: LGTM: Well-defined constants.The email address and tooltip duration are appropriately extracted as constants with clear naming.
9-18: LGTM: Proper timeout cleanup on unmount.The cleanup effect correctly prevents memory leaks by clearing any pending timeout when the component unmounts.
47-54: No action needed. Thegmail.svgfile exists in thepublic/directory and the Image component reference is correct.
|
@naman79820 Please review it. |
|
@naman79820 i added the copy mail feature and slack icon both . ready to be reviewed and merged. |
There was a problem hiding this comment.
Looks good overall just a small thought that i have. Since this is a simple footer interaction (click icon and copy email), it could also be done inline without a separate component. It's not blocking anything although, just wanted to share the thought.
@Yana-do-code
|
@naman79820 |
Fix : #188
This PR improves the footer email interaction by making the email icon copy the support email address to the clipboard on click and providing immediate visual feedback to the user.
Previously, clicking the email icon did not give any confirmation or actionable feedback, which could be confusing for users.
Also adds , a slack icon in the footer nav for better communication with the community.
What’s changed
Screenshots:


Light View :
Dark view :

Redirection path :
Checklist before requesting a review
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.