fix: redesign contact page as multi-section premium component layout#186
fix: redesign contact page as multi-section premium component layout#186Shivangi1515 wants to merge 5 commits into
Conversation
|
@Shivangi1515 is attempting to deploy a commit to the Kunal Verma's projects Team on Vercel. A member of the Team first needs to authorize it. |
🚀 PR Received SuccessfullyHello @Shivangi1515, Thank you for taking the initiative to contribute to this project. Please ensure that your PR follows all project guidelines properly before requesting review.
|
|
Warning Review limit reached
More reviews will be available in 43 minutes and 11 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, 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 include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughRefactors the Contact page into six focused components (Hero, ChannelCards, Form, Sidebar, FAQ, SuccessState). Implements category-driven form schemas and validation, GitHub repo stats fetching with caching and error handling, accessible FAQ accordion, and an animated post-submit success state; the page composes these components. ChangesContact Page Component-Driven Architecture
Sequence Diagram(s)sequenceDiagram
participant User
participant ContactForm
participant FormValidation
participant ContactSuccessState
participant GitHubStatsAPI
User->>ContactForm: Select category & fill fields
ContactForm->>FormValidation: Validate on change/blur
FormValidation-->>ContactForm: Return errors & touched state
User->>ContactForm: Submit (enabled when valid)
ContactForm->>ContactForm: Prevent default, show alert
ContactForm->>ContactSuccessState: AnimatePresence → success UI
ContactSuccessState->>User: Display category & response time
User->>ContactSuccessState: Click "Send Another Message"
ContactSuccessState-->>ContactForm: onReset callback
Note over GitHubStatsAPI: GitHubStats runs on mount, fetches repo stats with cache/TTL
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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
🧹 Nitpick comments (8)
frontend/src/components/contact/ContactForm.jsx (4)
117-127: ⚡ Quick winRemove unused ref.
The
refis created and attached to the textarea but never read or accessed. Line 119 usese.targetdirectly to manipulate the element's height, making the ref unnecessary.♻️ Proposed cleanup
function AutoTextarea({ value, onChange, onBlur, maxLength, id, name, required, placeholder, hasError, hasSuccess }) { - const ref = useRef(null); const handleInput = useCallback((e) => { const el = e.target; el.style.height = "auto"; el.style.height = el.scrollHeight + "px"; onChange(e); }, [onChange]); return ( <textarea - ref={ref} id={id}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactForm.jsx` around lines 117 - 127, The ref named "ref" is created with useRef and attached to the textarea but never used; remove the unused ref declaration and its ref={ref} prop to clean up the component, and ensure handleInput continues to use e.target for resizing (refer to useRef(null), ref, handleInput, and the textarea JSX to locate and remove the unused pieces).
244-247: ⚡ Quick winUnnecessary useCallback wrapping.
currentMaxLengthhas no dependencies and only reads from the module-levelFIELD_MAX_LENGTHconstant. Wrapping it inuseCallbackadds no value since the function has no closure over component state.♻️ Proposed simplification
Move to module scope:
+const getMaxLength = (fieldName) => FIELD_MAX_LENGTH[fieldName] || 2000; + export default function ContactForm() { // ... - const currentMaxLength = useCallback( - (fieldName) => FIELD_MAX_LENGTH[fieldName] || 2000, - [], - );Then use
getMaxLength(name)instead ofcurrentMaxLength(name)on line 290.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactForm.jsx` around lines 244 - 247, Remove the unnecessary useCallback wrapper around currentMaxLength: extract a pure helper function (e.g., getMaxLength(fieldName)) to module scope that returns FIELD_MAX_LENGTH[fieldName] || 2000, delete the currentMaxLength hook, and update all local references (calls to currentMaxLength(...) — e.g., where it’s used around line 290) to call getMaxLength(...) instead.
2-3: ⚡ Quick winRemove incorrect eslint-disable comment.
The
eslint-disable-line no-unused-varscomment on line 2 claimsframer-motionis unused, but bothAnimatePresence(line 250) andmotion(lines 252, 262) are actively used throughout the file. This comment is misleading and should be removed.🧹 Proposed fix
-// eslint-disable-next-line no-unused-vars -import { AnimatePresence, motion } from "framer-motion"; +import { AnimatePresence, motion } from "framer-motion";🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactForm.jsx` around lines 2 - 3, Remove the incorrect eslint-disable comment that suppresses the no-unused-vars rule for the framer-motion import; the file does use AnimatePresence and motion (referenced in AnimatePresence and motion usage around the ContactForm component), so delete the line "// eslint-disable-next-line no-unused-vars" above the import of { AnimatePresence, motion } from "framer-motion" so ESLint correctly reflects actual usage.
83-104: ⚡ Quick winSimplify validator factory.
buildValidatoris a factory function that takes no arguments and closes over no variables. The wrapper adds unnecessary indirection. Consider definingvalidateFielddirectly at module scope.♻️ Proposed simplification
-function buildValidator() { - return function validateField(name, value) { +function validateField(name, value) { if (name === "email") { if (!value) return "Email is required"; if (!validateEmail(value)) return "Invalid email address"; } // ... rest of validation return null; - }; -} +}Then update line 187:
- const validate = useMemo(() => buildValidator(), []); + const validate = validateField;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactForm.jsx` around lines 83 - 104, The buildValidator wrapper is unnecessary because it takes no args or closed-over state; replace it by defining validateField at module scope (move the inner function out and remove buildValidator), then update all call sites that currently invoke buildValidator() to call validateField directly (e.g., where buildValidator() was used in ContactForm.jsx). Keep the exact validation logic (email/name/company/platform/message/stepsToReproduce/expectedBehavior/actualBehavior/description/proposal checks) intact when moving the function.frontend/src/components/contact/ContactSuccessState.jsx (3)
82-99: 💤 Low valueConsider extracting GitHub URL to a constant.
The GitHub repository URL is hardcoded on line 83. For better maintainability, especially if this URL is used elsewhere (e.g., in ContactChannelCards), consider extracting it to a shared constant or configuration file.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactSuccessState.jsx` around lines 82 - 99, Extract the hardcoded GitHub URL used in the ContactSuccessState component into a shared constant (e.g., GITHUB_REPO_URL) in a central config or constants module and import it into ContactSuccessState.jsx; replace the href value on the anchor element in the ContactSuccessState component with the imported constant so other components (like ContactChannelCards) can reuse the same constant and you avoid duplicated hardcoded URLs.
1-2: ⚡ Quick winRemove incorrect eslint-disable comment.
The
eslint-disable-line no-unused-varscomment claimsmotionis unused, butmotion.div,motion.svg, andmotion.pathare used throughout the component (lines 18, 24, 38). This comment should be removed.🧹 Proposed fix
-// eslint-disable-next-line no-unused-vars -import { motion } from "framer-motion"; +import { motion } from "framer-motion";🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactSuccessState.jsx` around lines 1 - 2, Remove the incorrect eslint-disable comment before the motion import in ContactSuccessState.jsx: delete the line "// eslint-disable-next-line no-unused-vars" that precedes "import { motion } from 'framer-motion'"; confirm that the component continues to use motion via motion.div, motion.svg, and motion.path so no eslint suppression is needed and no other unused-vars disables are left in the file.
24-44: ⚡ Quick winRemove redundant pathLength animation on svg element.
Lines 34-36 define a
pathLengthanimation on themotion.svgelement, butpathLengthis a property of SVG path elements, not the svg container itself. The working animation is on themotion.pathelement (lines 40-42). The svg-level animation properties are ineffective and should be removed to avoid confusion.♻️ Proposed cleanup
<motion.svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" className="text-emerald-600" - initial={{ pathLength: 0 }} - animate={{ pathLength: 1 }} - transition={{ duration: 0.5, delay: 0.2, ease: "easeOut" }} > <motion.path d="M5 13l4 4L19 7" initial={{ pathLength: 0 }} animate={{ pathLength: 1 }} transition={{ duration: 0.5, delay: 0.2, ease: "easeOut" }} /> </motion.svg>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactSuccessState.jsx` around lines 24 - 44, The motion.svg element in ContactSuccessState.jsx is incorrectly given pathLength animation props (initial/animate transition using pathLength) which are only effective on SVG path elements; remove the redundant initial/animate/transition that reference pathLength from the motion.svg element so the animation is only applied on the motion.path (d="M5 13l4 4L19 7") and keep the existing animation props on motion.path; ensure only motion.path uses initial={{ pathLength: 0 }} animate={{ pathLength: 1 }} transition={{ ... }} and delete those same props from motion.svg to avoid confusion.frontend/src/components/contact/ContactSidebar.jsx (1)
57-58: 💤 Low valueOptional: Log errors to aid debugging.
The empty catch block silently swallows errors, making it harder to diagnose issues during development (e.g., network failures, API changes, CORS problems).
🔍 Suggested enhancement
} catch { + console.error('Failed to fetch GitHub stats:', error); if (!cancelled) setError(true); } finally {Alternatively, integrate with an error tracking service (e.g., Sentry) for production error monitoring.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactSidebar.jsx` around lines 57 - 58, The catch block in ContactSidebar.jsx currently swallows errors; change it to accept the error (e.g., "catch (err)") and log the error (e.g., console.error or send to your Sentry/logger) while preserving the existing cancelled check and setError(true) call; update the catch surrounding the async logic that uses the "cancelled" variable and "setError" so errors are visible in dev and optionally forwarded to your monitoring service.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontend/src/components/contact/ContactChannelCards.jsx`:
- Line 26: The Discord card currently uses a placeholder href ("#") in the
ContactChannelCards component (and the Footer component has the same
placeholder); update the Discord link to the real invite URL or hide/disable the
Discord card until a valid invite is available by replacing the placeholder href
in the Discord card JSX (look for the Discord card render inside
ContactChannelCards.jsx and Footer.jsx) with the actual invite URL constant or
conditional rendering that omits the card when no DISCORD_INVITE is provided;
ensure you reference a single source (e.g., a DISCORD_INVITE env constant or
prop) so both components use the same real link or both hide when it's absent.
In `@frontend/src/components/contact/ContactSidebar.jsx`:
- Around line 45-68: ContactSidebar.jsx currently calls GitHub API directly
inside fetchStats which causes unauthenticated rate-limit failures and swallows
errors; change fetchStats to call a new server-side cached public endpoint (e.g.
GET /api/public/github-stats) or implement a short client TTL cache keyed by
repo (store timestamp + stats) before falling back to network, and update UI via
setStats/setError/setLoading accordingly; also surface a graceful "try again
later" message when X-RateLimit-Remaining is low or failed, and log the caught
error (e.g. console.error) instead of swallowing it so failures are visible for
debugging.
---
Nitpick comments:
In `@frontend/src/components/contact/ContactForm.jsx`:
- Around line 117-127: The ref named "ref" is created with useRef and attached
to the textarea but never used; remove the unused ref declaration and its
ref={ref} prop to clean up the component, and ensure handleInput continues to
use e.target for resizing (refer to useRef(null), ref, handleInput, and the
textarea JSX to locate and remove the unused pieces).
- Around line 244-247: Remove the unnecessary useCallback wrapper around
currentMaxLength: extract a pure helper function (e.g., getMaxLength(fieldName))
to module scope that returns FIELD_MAX_LENGTH[fieldName] || 2000, delete the
currentMaxLength hook, and update all local references (calls to
currentMaxLength(...) — e.g., where it’s used around line 290) to call
getMaxLength(...) instead.
- Around line 2-3: Remove the incorrect eslint-disable comment that suppresses
the no-unused-vars rule for the framer-motion import; the file does use
AnimatePresence and motion (referenced in AnimatePresence and motion usage
around the ContactForm component), so delete the line "//
eslint-disable-next-line no-unused-vars" above the import of { AnimatePresence,
motion } from "framer-motion" so ESLint correctly reflects actual usage.
- Around line 83-104: The buildValidator wrapper is unnecessary because it takes
no args or closed-over state; replace it by defining validateField at module
scope (move the inner function out and remove buildValidator), then update all
call sites that currently invoke buildValidator() to call validateField directly
(e.g., where buildValidator() was used in ContactForm.jsx). Keep the exact
validation logic
(email/name/company/platform/message/stepsToReproduce/expectedBehavior/actualBehavior/description/proposal
checks) intact when moving the function.
In `@frontend/src/components/contact/ContactSidebar.jsx`:
- Around line 57-58: The catch block in ContactSidebar.jsx currently swallows
errors; change it to accept the error (e.g., "catch (err)") and log the error
(e.g., console.error or send to your Sentry/logger) while preserving the
existing cancelled check and setError(true) call; update the catch surrounding
the async logic that uses the "cancelled" variable and "setError" so errors are
visible in dev and optionally forwarded to your monitoring service.
In `@frontend/src/components/contact/ContactSuccessState.jsx`:
- Around line 82-99: Extract the hardcoded GitHub URL used in the
ContactSuccessState component into a shared constant (e.g., GITHUB_REPO_URL) in
a central config or constants module and import it into ContactSuccessState.jsx;
replace the href value on the anchor element in the ContactSuccessState
component with the imported constant so other components (like
ContactChannelCards) can reuse the same constant and you avoid duplicated
hardcoded URLs.
- Around line 1-2: Remove the incorrect eslint-disable comment before the motion
import in ContactSuccessState.jsx: delete the line "// eslint-disable-next-line
no-unused-vars" that precedes "import { motion } from 'framer-motion'"; confirm
that the component continues to use motion via motion.div, motion.svg, and
motion.path so no eslint suppression is needed and no other unused-vars disables
are left in the file.
- Around line 24-44: The motion.svg element in ContactSuccessState.jsx is
incorrectly given pathLength animation props (initial/animate transition using
pathLength) which are only effective on SVG path elements; remove the redundant
initial/animate/transition that reference pathLength from the motion.svg element
so the animation is only applied on the motion.path (d="M5 13l4 4L19 7") and
keep the existing animation props on motion.path; ensure only motion.path uses
initial={{ pathLength: 0 }} animate={{ pathLength: 1 }} transition={{ ... }} and
delete those same props from motion.svg to avoid confusion.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3ee13742-b0b3-4f78-9e73-c90e7c23e2d2
📒 Files selected for processing (7)
frontend/src/components/contact/ContactChannelCards.jsxfrontend/src/components/contact/ContactFAQ.jsxfrontend/src/components/contact/ContactForm.jsxfrontend/src/components/contact/ContactHero.jsxfrontend/src/components/contact/ContactSidebar.jsxfrontend/src/components/contact/ContactSuccessState.jsxfrontend/src/pages/Contact.jsx
|
@Shivangi1515 Fantastic work Still some more changes needed before final merge
|
|
@Shivangi1515 you can support this project by starring the repository Also if you are working on what I said before then just write a ping message so as to know whether you started or not |
|
Yes m working on it
…On Fri, 12 Jun 2026, 3:29 pm Kunal Verma, ***@***.***> wrote:
*kunalverma2512* left a comment (kunalverma2512/CodeLens#186)
<#186 (comment)>
@Shivangi1515 <https://github.com/Shivangi1515> you can support this
project by starring the repository
Also if you are working on what I said before then just write a ping
message so as to know whether you started or not
—
Reply to this email directly, view it on GitHub
<#186?email_source=notifications&email_token=BPX6ITACQWQDXEOFTOSZIZD47PH6NA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTINRYHE4TEMRQHEZ2M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-4689922093>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/BPX6ITAA35C5R2PNIZIKL4D47PH6NAVCNFSNUABGKJSXA33TNF2G64TZHMYTCOJSGQ3DSOJZHE5US43TOVSTWNBWGQ3TOOJUHA2TFILWAI>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/BPX6ITB73J6LGCL5LSW6KAT47PH6NA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTINRYHE4TEMRQHEZ2M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJKTGN5XXIZLSL5UW64Y>
and Android
<https://github.com/notifications/mobile/android/BPX6ITGDD6X4HDMPGH23EVL47PH6NA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTINRYHE4TEMRQHEZ2M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLTGN5XXIZLSL5QW4ZDSN5UWI>.
Download it today!
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
…th sections, confident copy, remove Discord
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
frontend/src/components/contact/ContactSuccessState.jsx (4)
18-45:⚠️ Potential issue | 🟠 Major | ⚡ Quick winRespect
prefers-reduced-motionfor animations.The PR objectives explicitly require "minimal motion respecting prefers-reduced-motion," but the scale and path-drawing animations run unconditionally. Users with motion sensitivity will experience the full animations.
[accessibility]
♿ Proposed fix to respect motion preferences
export default function ContactSuccessState({ category, onReset }) { const navigate = useNavigate(); + const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; return ( <div className="flex flex-col items-start"> <motion.div - initial={{ scale: 0 }} - animate={{ scale: 1 }} - transition={{ type: "spring", stiffness: 260, damping: 20 }} + initial={prefersReducedMotion ? { scale: 1 } : { scale: 0 }} + animate={{ scale: 1 }} + transition={prefersReducedMotion ? { duration: 0 } : { type: "spring", stiffness: 260, damping: 20 }} className="flex h-14 w-14 items-center justify-center bg-neutral-100 mb-6" > <motion.svg ... - initial={{ pathLength: 0 }} - animate={{ pathLength: 1 }} - transition={{ duration: 0.5, delay: 0.2, ease: "easeOut" }} + initial={prefersReducedMotion ? { pathLength: 1 } : { pathLength: 0 }} + animate={{ pathLength: 1 }} + transition={prefersReducedMotion ? { duration: 0 } : { duration: 0.5, delay: 0.2, ease: "easeOut" }} > <motion.path d="M5 13l4 4L19 7" - initial={{ pathLength: 0 }} - animate={{ pathLength: 1 }} - transition={{ duration: 0.5, delay: 0.2, ease: "easeOut" }} + initial={prefersReducedMotion ? { pathLength: 1 } : { pathLength: 0 }} + animate={{ pathLength: 1 }} + transition={prefersReducedMotion ? { duration: 0 } : { duration: 0.5, delay: 0.2, ease: "easeOut" }} /> </motion.svg> </motion.div>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactSuccessState.jsx` around lines 18 - 45, The animations in ContactSuccessState.jsx (the motion.div, motion.svg and motion.path elements) ignore users' prefers-reduced-motion; use Framer Motion's useReducedMotion (or window.matchMedia) to detect reduced motion and, when true, disable or short-circuit the animations by providing non-animating props (e.g., set initial/animate to the final state: scale: 1 and pathLength: 1, omit transitions or set duration 0) for those symbols so the check occurs before rendering and avoids running spring/path-draw animations for motion-sensitive users.
65-67:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd fallback for undefined response time.
If an invalid
categoryis passed (one not defined inRESPONSE_TIME), line 66 will renderundefined. While the current form implementation passes valid categories, defensive coding suggests adding a fallback.🛡️ Proposed fix to add fallback
<p className="text-sm font-medium text-neutral-900"> - {RESPONSE_TIME[category]} + {RESPONSE_TIME[category] || "We'll respond as soon as possible"} </p>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactSuccessState.jsx` around lines 65 - 67, The rendering of RESPONSE_TIME[category] in ContactSuccessState.jsx can produce undefined for unknown categories; update the display to use a safe fallback (e.g., 'N/A' or a localized fallback string) when RESPONSE_TIME[category] is falsy/undefined. Locate the JSX that references RESPONSE_TIME[category] (inside the <p> with className "text-sm font-medium text-neutral-900") and replace the direct lookup with a fallback expression so the UI never renders "undefined" for invalid category values.
24-44:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd accessible label to the success checkmark icon.
The animated checkmark SVG has no ARIA attributes, so screen reader users won't receive feedback that the message was successfully sent.
[accessibility]
♿ Proposed fix to add ARIA label
<motion.svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" className="text-neutral-900" + role="img" + aria-label="Success" initial={{ pathLength: 0 }} animate={{ pathLength: 1 }} transition={{ duration: 0.5, delay: 0.2, ease: "easeOut" }} >🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactSuccessState.jsx` around lines 24 - 44, The animated checkmark SVG in ContactSuccessState.jsx (the motion.svg element) lacks ARIA labeling; add an accessible name by giving the motion.svg a role="img" and either an aria-label (e.g., "Message sent") or aria-labelledby pointing to a <title> text node, and mark the decorative path (motion.path) as aria-hidden="true" so screen readers read only the SVG label; update the motion.svg attributes (role/aria-label or aria-labelledby) and add a <title> element or aria-label accordingly while keeping motion.path aria-hidden.
1-2:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRemove the incorrect eslint-disable comment.
The
motionimport is actively used throughout the component (lines 18-44), so theno-unused-varssuppression is incorrect and should be removed.🧹 Proposed fix
-// eslint-disable-next-line no-unused-vars import { motion } from "framer-motion";🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactSuccessState.jsx` around lines 1 - 2, Remove the incorrect eslint suppression above the motion import: delete the comment "// eslint-disable-next-line no-unused-vars" so the import line remains "import { motion } from 'framer-motion';" (the component uses motion in ContactSuccessState.jsx across the animated JSX). Ensure no other unused-vars disable comments remain for that import and run lint to confirm.
♻️ Duplicate comments (1)
frontend/src/components/contact/ContactSidebar.jsx (1)
65-70:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winCheck HTTP status codes for rate-limit detection instead of relying on header value.
The current logic checks
rateLimitRemaining === "0"after a failed response, but if theX-RateLimit-Remainingheader is missing or null (edge case), the check fails silently and falls through to the generic error message. Checkingres.status === 403 || res.status === 429is more robust and doesn't depend on header presence.🛡️ Proposed fix
- if (!res.ok) { - if (rateLimitRemaining === "0") { - throw new Error("Rate limit exceeded. Please try again later."); - } - throw new Error(`GitHub API responded with ${res.status}`); - } + if (!res.ok) { + if (res.status === 403 || res.status === 429) { + throw new Error("Rate limit exceeded. Please try again later."); + } + throw new Error(`GitHub API responded with ${res.status}`); + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactSidebar.jsx` around lines 65 - 70, The error handling uses rateLimitRemaining to detect rate limits which can be missing; update the failure branch in ContactSidebar.jsx (the block using res and rateLimitRemaining) to check HTTP status codes instead: if res.status === 403 || res.status === 429 then throw the "Rate limit exceeded. Please try again later." error, otherwise throw the generic `GitHub API responded with ${res.status}` error; keep using rateLimitRemaining as supplemental information if present but do not rely on it as the primary check.
🧹 Nitpick comments (3)
frontend/src/components/contact/ContactChannelCards.jsx (1)
32-51: 💤 Low valueConsider adding screen-reader indication for external links.
The channel cards open in new tabs (via
target="_blank"), and theArrowUpRighticon provides a visual cue. For screen-reader users, consider adding anaria-labelthat mentions the link opens externally.♿ Optional enhancement for screen-reader users
<a key={channel.title} href={channel.href} target="_blank" rel="noopener noreferrer" + aria-label={`${channel.title} (opens in new tab)`} className="group relative flex flex-col border border-neutral-200 bg-white p-5 shadow-sm transition-all duration-200 hover:-translate-y-0.5 hover:scale-[1.01] hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-900 focus-visible:ring-offset-2" >🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactChannelCards.jsx` around lines 32 - 51, Add an accessible label to the channel card anchor so screen readers know the link opens in a new tab: update the anchor used in ContactChannelCards.jsx (the <a> that uses channel.href and target="_blank") to include an aria-label that composes channel.title plus a suffix like "opens in a new tab" (or reference a visually-hidden text via aria-describedby); ensure the ArrowUpRight visual cue is preserved and the rel attribute remains "noopener noreferrer".frontend/src/components/contact/ContactSuccessState.jsx (2)
82-82: ⚡ Quick winConsider making the GitHub repository URL configurable.
The GitHub Issues URL is hardcoded. If the repository is forked or the owner changes, this link will break. Consider moving it to a configuration constant or environment variable.
♻️ Suggested approach
Create a config file or add to an existing one:
// config/constants.js or similar export const GITHUB_REPO = { owner: 'kunalverma2512', repo: 'CodeLens' }; export const GITHUB_ISSUES_URL = `https://github.com/${GITHUB_REPO.owner}/${GITHUB_REPO.repo}/issues`;Then import and use:
+import { GITHUB_ISSUES_URL } from '../../config/constants'; <a - href="https://github.com/kunalverma2512/CodeLens/issues" + href={GITHUB_ISSUES_URL} target="_blank" rel="noopener noreferrer"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactSuccessState.jsx` at line 82, The hardcoded GitHub issues link in ContactSuccessState.jsx (the href "https://github.com/kunalverma2512/CodeLens/issues") should be made configurable: add a constant (e.g., GITHUB_ISSUES_URL) in a shared config module (or read from an env var like REACT_APP_GITHUB_ISSUES_URL) and import it into ContactSuccessState.jsx, then replace the literal href with that constant; ensure the config exports GITHUB_REPO owner/repo or a full URL and add a sensible default so forks or owner changes don’t break the link.
88-97: 💤 Low valueConsider using lucide-react's
Githubicon for consistency.The component imports
ArrowRightfromlucide-reactbut uses an inline SVG for the GitHub icon. Usinglucide-react'sGithubicon would improve consistency and reduce code.♻️ Proposed refactor
-import { ArrowRight } from "lucide-react"; +import { ArrowRight, Github } from "lucide-react"; <a ... className="inline-flex items-center gap-2 border border-neutral-200 bg-white px-5 py-2.5 text-sm font-medium text-neutral-700 shadow-sm transition-all duration-200 hover:border-neutral-300 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-900 focus-visible:ring-offset-2" > Check GitHub Issues - <svg - width="16" - height="16" - viewBox="0 0 24 24" - fill="currentColor" - aria-hidden="true" - className="text-neutral-400" - > - <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z" /> - </svg> + <Github className="h-4 w-4 text-neutral-400" /> </a>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactSuccessState.jsx` around lines 88 - 97, The component is using an inline GitHub SVG instead of the lucide-react icon already used for ArrowRight; import the Github icon from "lucide-react" alongside ArrowRight, remove the inline <svg> markup in ContactSuccessState (the GitHub icon block) and render the <Github /> component with the same props/className (width/height, aria-hidden, className="text-neutral-400") so visuals and accessibility remain identical.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontend/src/components/contact/ContactSidebar.jsx`:
- Around line 75-82: The code assumes GitHub fields exist when building
statsData in the ContactSidebar component; validate that `data` has numeric
`stargazers_count`, `forks_count`, and `open_issues_count` before using them (in
the block that sets `statsData`, updates `STATS_CACHE`, and calls `setStats`),
and provide safe fallbacks (e.g., 0 or null) so downstream code calling
`stats.stars.toLocaleString()` won't throw; update the cached object and
`setStats` with the normalized values and set a non-empty `setError` or leave it
unchanged only on fatal failures so UI can handle missing values gracefully.
---
Outside diff comments:
In `@frontend/src/components/contact/ContactSuccessState.jsx`:
- Around line 18-45: The animations in ContactSuccessState.jsx (the motion.div,
motion.svg and motion.path elements) ignore users' prefers-reduced-motion; use
Framer Motion's useReducedMotion (or window.matchMedia) to detect reduced motion
and, when true, disable or short-circuit the animations by providing
non-animating props (e.g., set initial/animate to the final state: scale: 1 and
pathLength: 1, omit transitions or set duration 0) for those symbols so the
check occurs before rendering and avoids running spring/path-draw animations for
motion-sensitive users.
- Around line 65-67: The rendering of RESPONSE_TIME[category] in
ContactSuccessState.jsx can produce undefined for unknown categories; update the
display to use a safe fallback (e.g., 'N/A' or a localized fallback string) when
RESPONSE_TIME[category] is falsy/undefined. Locate the JSX that references
RESPONSE_TIME[category] (inside the <p> with className "text-sm font-medium
text-neutral-900") and replace the direct lookup with a fallback expression so
the UI never renders "undefined" for invalid category values.
- Around line 24-44: The animated checkmark SVG in ContactSuccessState.jsx (the
motion.svg element) lacks ARIA labeling; add an accessible name by giving the
motion.svg a role="img" and either an aria-label (e.g., "Message sent") or
aria-labelledby pointing to a <title> text node, and mark the decorative path
(motion.path) as aria-hidden="true" so screen readers read only the SVG label;
update the motion.svg attributes (role/aria-label or aria-labelledby) and add a
<title> element or aria-label accordingly while keeping motion.path aria-hidden.
- Around line 1-2: Remove the incorrect eslint suppression above the motion
import: delete the comment "// eslint-disable-next-line no-unused-vars" so the
import line remains "import { motion } from 'framer-motion';" (the component
uses motion in ContactSuccessState.jsx across the animated JSX). Ensure no other
unused-vars disable comments remain for that import and run lint to confirm.
---
Duplicate comments:
In `@frontend/src/components/contact/ContactSidebar.jsx`:
- Around line 65-70: The error handling uses rateLimitRemaining to detect rate
limits which can be missing; update the failure branch in ContactSidebar.jsx
(the block using res and rateLimitRemaining) to check HTTP status codes instead:
if res.status === 403 || res.status === 429 then throw the "Rate limit exceeded.
Please try again later." error, otherwise throw the generic `GitHub API
responded with ${res.status}` error; keep using rateLimitRemaining as
supplemental information if present but do not rely on it as the primary check.
---
Nitpick comments:
In `@frontend/src/components/contact/ContactChannelCards.jsx`:
- Around line 32-51: Add an accessible label to the channel card anchor so
screen readers know the link opens in a new tab: update the anchor used in
ContactChannelCards.jsx (the <a> that uses channel.href and target="_blank") to
include an aria-label that composes channel.title plus a suffix like "opens in a
new tab" (or reference a visually-hidden text via aria-describedby); ensure the
ArrowUpRight visual cue is preserved and the rel attribute remains "noopener
noreferrer".
In `@frontend/src/components/contact/ContactSuccessState.jsx`:
- Line 82: The hardcoded GitHub issues link in ContactSuccessState.jsx (the href
"https://github.com/kunalverma2512/CodeLens/issues") should be made
configurable: add a constant (e.g., GITHUB_ISSUES_URL) in a shared config module
(or read from an env var like REACT_APP_GITHUB_ISSUES_URL) and import it into
ContactSuccessState.jsx, then replace the literal href with that constant;
ensure the config exports GITHUB_REPO owner/repo or a full URL and add a
sensible default so forks or owner changes don’t break the link.
- Around line 88-97: The component is using an inline GitHub SVG instead of the
lucide-react icon already used for ArrowRight; import the Github icon from
"lucide-react" alongside ArrowRight, remove the inline <svg> markup in
ContactSuccessState (the GitHub icon block) and render the <Github /> component
with the same props/className (width/height, aria-hidden,
className="text-neutral-400") so visuals and accessibility remain identical.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3a727a2a-6052-43bd-9805-994f47ebd3b1
📒 Files selected for processing (7)
frontend/src/components/contact/ContactChannelCards.jsxfrontend/src/components/contact/ContactFAQ.jsxfrontend/src/components/contact/ContactForm.jsxfrontend/src/components/contact/ContactHero.jsxfrontend/src/components/contact/ContactSidebar.jsxfrontend/src/components/contact/ContactSuccessState.jsxfrontend/src/pages/Contact.jsx
🚧 Files skipped from review as they are similar to previous changes (2)
- frontend/src/components/contact/ContactFAQ.jsx
- frontend/src/components/contact/ContactForm.jsx
| const statsData = { | ||
| stars: data.stargazers_count, | ||
| forks: data.forks_count, | ||
| openIssues: data.open_issues_count, | ||
| }; | ||
| STATS_CACHE.set(repo, { stats: statsData, timestamp: Date.now() }); | ||
| setStats(statsData); | ||
| setError(""); |
There was a problem hiding this comment.
Validate GitHub API response structure before accessing nested fields.
If the GitHub API response structure changes or returns unexpected data, accessing data.stargazers_count, data.forks_count, or data.open_issues_count without validation will cause a runtime crash when stats.stars.toLocaleString() is called at line 127.
🛡️ Proposed fix
const data = await res.json();
if (!cancelled) {
+ if (
+ typeof data.stargazers_count !== "number" ||
+ typeof data.forks_count !== "number" ||
+ typeof data.open_issues_count !== "number"
+ ) {
+ throw new Error("Invalid API response structure");
+ }
const statsData = {
stars: data.stargazers_count,
forks: data.forks_count,
openIssues: data.open_issues_count,
};
STATS_CACHE.set(repo, { stats: statsData, timestamp: Date.now() });
setStats(statsData);
setError("");
}📝 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 statsData = { | |
| stars: data.stargazers_count, | |
| forks: data.forks_count, | |
| openIssues: data.open_issues_count, | |
| }; | |
| STATS_CACHE.set(repo, { stats: statsData, timestamp: Date.now() }); | |
| setStats(statsData); | |
| setError(""); | |
| const data = await res.json(); | |
| if (!cancelled) { | |
| if ( | |
| typeof data.stargazers_count !== "number" || | |
| typeof data.forks_count !== "number" || | |
| typeof data.open_issues_count !== "number" | |
| ) { | |
| throw new Error("Invalid API response structure"); | |
| } | |
| const statsData = { | |
| stars: data.stargazers_count, | |
| forks: data.forks_count, | |
| openIssues: data.open_issues_count, | |
| }; | |
| STATS_CACHE.set(repo, { stats: statsData, timestamp: Date.now() }); | |
| setStats(statsData); | |
| setError(""); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/src/components/contact/ContactSidebar.jsx` around lines 75 - 82, The
code assumes GitHub fields exist when building statsData in the ContactSidebar
component; validate that `data` has numeric `stargazers_count`, `forks_count`,
and `open_issues_count` before using them (in the block that sets `statsData`,
updates `STATS_CACHE`, and calls `setStats`), and provide safe fallbacks (e.g.,
0 or null) so downstream code calling `stats.stars.toLocaleString()` won't
throw; update the cached object and `setStats` with the normalized values and
set a non-empty `setError` or leave it unchanged only on fatal failures so UI
can handle missing values gracefully.
|
@Shivangi1515 make sure to provide a video for this PR work |
|
@coderabbitai please completely check this PR that is the work done is compatible with nearby codes, files and folder and is it ready to merge ? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
echo "=== Directory structure ==="
tree frontend/src/components/contact/ 2>/dev/null || find frontend/src/components/contact -type f | sort
echo ""
echo "=== Contact.jsx (page) ==="
cat frontend/src/pages/Contact.jsx
echo ""
echo "=== ContactHero.jsx ==="
cat frontend/src/components/contact/ContactHero.jsx
echo ""
echo "=== ContactChannelCards.jsx ==="
cat frontend/src/components/contact/ContactChannelCards.jsx
echo ""
echo "=== ContactForm.jsx ==="
cat frontend/src/components/contact/ContactForm.jsx
echo ""
echo "=== ContactSidebar.jsx ==="
cat frontend/src/components/contact/ContactSidebar.jsx
echo ""
echo "=== ContactFAQ.jsx ==="
cat frontend/src/components/contact/ContactFAQ.jsx
echo ""
echo "=== ContactSuccessState.jsx ==="
cat frontend/src/components/contact/ContactSuccessState.jsxLength of output: 33161 🏁 Script executed: #!/bin/bash
echo "=== Router / App entry to check Contact route wiring ==="
fd -e jsx -e js App frontend/src/ | head -5 | xargs cat 2>/dev/null || true
fd -e jsx -e js -e tsx router frontend/src/ | head -5 | xargs cat 2>/dev/null || true
echo ""
echo "=== Check for any existing router file ==="
fd "router" frontend/src --type f | xargs cat 2>/dev/null || true
fd "routes" frontend/src --type f | xargs cat 2>/dev/null || true
echo ""
echo "=== Check package.json for framer-motion dependency ==="
cat frontend/package.json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); deps={**d.get('dependencies',{}), **d.get('devDependencies',{})}; [print(k,v) for k,v in deps.items() if k in ['framer-motion','lucide-react','react','react-dom','react-router-dom']]"
echo ""
echo "=== Check for any existing Contact component to see what was replaced ==="
git log --oneline -10
echo ""
echo "=== Check for any other files that import from Contact ==="
rg -rn "from.*Contact" frontend/src/ --type jsx 2>/dev/null || rg -rn "from.*Contact" frontend/src/ 2>/dev/null | grep -v "node_modules"
echo ""
echo "=== Check for green color classes in components (should only be in availability dot) ==="
rg -n "green|emerald" frontend/src/components/contact/ 2>/dev/null
echo ""
echo "=== Check for rounded corners ==="
rg -n "rounded" frontend/src/components/contact/ 2>/dev/null
echo ""
echo "=== Check for Discord references ==="
rg -n -i "discord" frontend/src/components/contact/ 2>/dev/null
echo ""
echo "=== Check for sidebar layout in Contact.jsx ==="
grep -n "sidebar\|Sidebar\|grid\|flex\|w-full\|100%" frontend/src/pages/Contact.jsx 2>/dev/nullLength of output: 9834
PR Description ImagesThe three screenshots in the PR description (hero section, form with sidebar, FAQ) appear to be from the earlier commit ( Reviewer's 9 Requests — Compliance Check
Code Compatibility
Bugs That Must Be Fixed Before Merge🔴 Bug: Raw HTML entities in JS string literals (
|
|
@Shivangi1515 Please see the coderabbitai comment for fixing remaining issues |
|
@Shivangi1515 for form , just use alert when tapping on send for the form as it backend will be going to be written in future issues |
|
update @Shivangi1515 ? |
…etTimeout with alert in contact page
There was a problem hiding this comment.
🧹 Nitpick comments (1)
frontend/src/components/contact/ContactForm.jsx (1)
219-227: ⚡ Quick winConsider removing the alert to avoid blocking the success animation.
The
alert()call creates redundant messaging and interrupts the polished user experience. When the user submits, they see a blocking browser alert, must click OK, and only then see the animated success state. SinceContactSuccessStatealready provides comprehensive feedback—animated checkmark, "Message sent!" heading, submitted category, and estimated response time—the alert is unnecessary and degrades the flow.Removing the alert and keeping only
setSubmitted(true)would create a smoother, more modern experience where the success animation plays immediately.✨ Suggested improvement
const handleSubmit = useCallback( (e) => { e.preventDefault(); if (!valid) return; - alert("Your message has been sent! We'll get back to you soon."); setSubmitted(true); }, [valid], );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/contact/ContactForm.jsx` around lines 219 - 227, Remove the alert() call from the handleSubmit function in ContactForm.jsx to allow the success animation to display immediately without blocking user interaction. The alert creates redundant messaging since ContactSuccessState already provides comprehensive visual feedback (animated checkmark, success heading, etc.). Keep the setSubmitted(true) call which triggers the smooth success animation—this single state change is sufficient to notify the user of successful submission and will provide a more polished, modern user experience.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@frontend/src/components/contact/ContactForm.jsx`:
- Around line 219-227: Remove the alert() call from the handleSubmit function in
ContactForm.jsx to allow the success animation to display immediately without
blocking user interaction. The alert creates redundant messaging since
ContactSuccessState already provides comprehensive visual feedback (animated
checkmark, success heading, etc.). Keep the setSubmitted(true) call which
triggers the smooth success animation—this single state change is sufficient to
notify the user of successful submission and will provide a more polished,
modern user experience.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f7dcebb8-ad4c-4078-9ce7-485636e49bbc
📒 Files selected for processing (3)
frontend/src/components/contact/ContactChannelCards.jsxfrontend/src/components/contact/ContactForm.jsxfrontend/src/components/contact/ContactSuccessState.jsx
💤 Files with no reviewable changes (1)
- frontend/src/components/contact/ContactSuccessState.jsx
🚧 Files skipped from review as they are similar to previous changes (1)
- frontend/src/components/contact/ContactChannelCards.jsx
…cess animation show immediately
@coderabbitai please check latest commits and tell whether @Shivangi1515 has resolved issues told by you previously and is things are implemented according to what I told in this comment ? i.e this comment And finally tell is this ready to merge ? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
echo "=== Recent commits ==="
git log --oneline -10
echo ""
echo "=== ContactChannelCards.jsx (check HTML entities & Discord) ==="
cat frontend/src/components/contact/ContactChannelCards.jsx
echo ""
echo "=== ContactForm.jsx (check eslint-disable & setTimeout/alert) ==="
cat frontend/src/components/contact/ContactForm.jsx
echo ""
echo "=== ContactSuccessState.jsx (check eslint-disable) ==="
cat frontend/src/components/contact/ContactSuccessState.jsx
echo ""
echo "=== ContactHero.jsx ==="
cat frontend/src/components/contact/ContactHero.jsx
echo ""
echo "=== ContactSidebar.jsx (check green colors, rounded, full-width) ==="
cat frontend/src/components/contact/ContactSidebar.jsx
echo ""
echo "=== ContactFAQ.jsx (check rounded corners) ==="
cat frontend/src/components/contact/ContactFAQ.jsx
echo ""
echo "=== Contact.jsx (check section order) ==="
cat frontend/src/pages/Contact.jsx
echo ""
echo "=== Check for green/emerald classes ==="
rg -n "green|emerald" frontend/src/components/contact/
echo ""
echo "=== Check for rounded (non-full) ==="
rg -n "rounded-" frontend/src/components/contact/ | grep -v "rounded-full"
echo ""
echo "=== Check for Discord ==="
rg -ni "discord" frontend/src/components/contact/
echo ""
echo "=== Check for HTML entities ==="
rg -n "'\|&\|"\|<\|>" frontend/src/components/contact/
echo ""
echo "=== Check for setTimeout ==="
rg -n "setTimeout" frontend/src/components/contact/
echo ""
echo "=== Check for alert ==="
rg -n "alert(" frontend/src/components/contact/
echo ""
echo "=== Check for eslint-disable comments ==="
rg -n "eslint-disable" frontend/src/components/contact/Length of output: 35419 PR description images (all three): These screenshots are from an older commit — they still show the green "Send Message" button, green "General" pill tab, sidebar alongside the form, and "Discord Community" card. They do not reflect the current code.
Previously Flagged Bugs — All Fixed ✅
Your 9 Reviewer Requirements — All Implemented ✅
VerdictReady to merge from a code perspective. All bugs fixed, all 9 requirements implemented, no regressions detected. One remaining action for
🐇 |
|
@Shivangi1515 current screenshots in PR description are outdated and must be replaced by newer and all UIs you developed |
📌 Pull Request Summary
🔗 Related Issue
Closes #183
📝 Description
Completely redesigned the Contact page into a multi-section, component-driven, premium communication hub that matches the quality of the rest of the CodeLens product. The new layout offers contextual information, multiple contact channels, a smart dynamic form, project trust signals, and a delightful success state.
Changes Made
frontend/src/components/contact/ContactHero.jsx— left-aligned hero with heading, welcome subtext, and animated green availability badge ("Usually replies within 24 hours")ContactChannelCards.jsx— 4 premium cards (Email, GitHub Issues, GitHub Discussions, Discord) with thin borders, subtle hover lift, and external linksContactForm.jsx— dynamic category selector (Bug Report, Feature Request, Partnership, General) that progressively discloses relevant fields, real-time email validation with green checkmark, character counters, auto-growing textarea, accessible labels, and loading state on submitContactSidebar.jsx— sticky sidebar with availability signal, timezone (IST / UTC+5:30), live GitHub API stats (stars, forks, open issues) with loading skeleton and error handling, plus a builder cardContactFAQ.jsx— accessible accordion with 5 developer-focused questions, smooth CSS expand/collapse, chevron rotation, and single-open behaviorContactSuccessState.jsx— animated checkmark via framer-motion, submitted category, estimated response time, and action buttons (Dashboard, GitHub Issues, Send Another Message)Contact.jsxto only import and compose the 6 components — zero UI logic in the page fileMotivation
The previous Contact page was a minimal single-form layout with no contextual information, no alternative contact channels, and no visual hierarchy. It did not reflect the quality of the rest of CodeLens and failed to communicate trust, response expectations, or developer-preferred support channels. This redesign brings the page up to the same premium standard as the rest of the product.
🚀 Type of Change
Select all that apply:
🧪 Testing
Verification
Test Details
npm run build) passes with zero errorseslint) passes with zero errors📸 Screenshots / Demo (If Applicable)
✅ Checklist
📚 Additional Notes
prefers-reduced-motionthroughoutSummary by CodeRabbit