Skip to content

Conversation

@Sindhura-Karumuri
Copy link
Contributor

@Sindhura-Karumuri Sindhura-Karumuri commented Aug 18, 2025

Related Issue


Description

This PR improves the Contact page by making it fully responsive across devices (mobile, tablet, and desktop).
Enhancements include:

  • Adjusted layout with grid and flex utilities.
  • Scalable typography and spacing using Tailwind’s responsive classes.
  • Improved form controls for smaller screens.
  • Ensured success popup is mobile-friendly.

How Has This Been Tested?

  • Manually tested on Chrome and Firefox.
  • Verified layout responsiveness on mobile (iPhone SE, Pixel 6) and desktop (1080p, 1440p).
  • Confirmed that form submission still triggers simulated API call and success popup.

Screenshots (if applicable)

Before

image

After

image

Type of Change

  • [x]🐛 Bug fix
  • ✨ New feature (UI responsiveness)
  • 🎨 Code style update (formatting, renaming)
  • 💥 Breaking change
  • 📝 Documentation update

Summary by CodeRabbit

  • Style
    • Made Contact page fully responsive: headings/subtitles scale by breakpoint; grid collapses to one column on small screens; improved padding, radii, and typography; dark mode-friendly colors.
    • Enabled vertical scrolling with full-height layout and added bottom padding to prevent content clipping.
    • Refined form controls: smaller padding, rounded corners, responsive text sizes; textarea reduced to 4 rows; responsive submit button spacing and sizing.
    • Improved success popup responsiveness: adaptive width, top offset, border radii, and scalable icon/text/close button.

@netlify
Copy link

netlify bot commented Aug 18, 2025

Deploy Preview for github-spy ready!

Name Link
🔨 Latest commit b304861
🔍 Latest deploy log https://app.netlify.com/projects/github-spy/deploys/68a3507dae310800083b84a4
😎 Deploy Preview https://deploy-preview-196--github-spy.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 18, 2025

Walkthrough

Responsive UI updates applied to the Contact page component, adjusting layout, typography, spacing, and containers for small and large screens. No changes to business logic, data handling, or exported signatures. All modifications are presentational within src/pages/Contact/Contact.tsx.

Changes

Cohort / File(s) Summary
Contact page responsive layout refactor
src/pages/Contact/Contact.tsx
Updated root container to support vertical scrolling and padding; reworked header to responsive stack/row; responsive typography for title/subtitle; grid shifts to 1-col on small and 2-col on large; adjusted card/form paddings, radii, inputs, textarea rows (5→4); responsive submit button spacing; responsive success popup sizing/positioning; import formatting adjusted.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Assessment against linked issues

Objective Addressed Explanation
Make Contact page responsive (#195)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Import formatting restructuring (src/pages/Contact/Contact.tsx) Formatting-only, not tied to responsiveness objective; nonetheless non-functional and harmless.

Suggested labels

gssoc2025, level2

Poem

I nibbled CSS like clover in spring,
Tucked grids to one, let headings sing.
Buttons scoot, popups shrink just right—
Small screens cozy, large take flight.
With paws on paddings, I hop with glee—
Behold! A responsive burrow for thee. 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
src/pages/Contact/Contact.tsx (1)

206-321: Critical: Built-in “required” validation isn’t triggered (no form submit). Make it a form and wire onSubmit

Right now the button’s onClick bypasses native constraint validation. Wrap controls in a form, use onSubmit, and associate labels with inputs for accessibility. This also lets Enter submit the form.

Apply this diff within the form block:

-            <div className="space-y-3 sm:space-y-4 flex-1 flex flex-col">
+            <form onSubmit={handleSubmit} aria-busy={isSubmitting} className="space-y-3 sm:space-y-4 flex-1 flex flex-col">
               <div className="space-y-3 flex-1">
                 {/* Full Name */}
                 <div>
-                  <label
-                    className={`block text-xs font-medium mb-1 ${
+                  <label
+                    htmlFor="fullName"
+                    className={`block text-xs font-medium mb-1 ${
                       mode === "dark"
                         ? "text-gray-300"
                         : "text-gray-700"
                     }`}
                   >
                     Full Name
                   </label>
                   <input
                     type="text"
                     placeholder="Enter your full name"
                     required
+                    id="fullName"
+                    name="fullName"
+                    autoComplete="name"
                     className={`w-full p-2 sm:p-3 rounded-lg sm:rounded-xl text-sm sm:text-base transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-purple-500 ${
                       mode === "dark"
                         ? "bg-white/5 border border-white/20 text-white placeholder-gray-400"
                         : "bg-gray-50 border border-gray-300 text-gray-800 placeholder-gray-500"
                     }`}
                   />
                 </div>

                 {/* Email */}
                 <div>
-                  <label
-                    className={`block text-xs font-medium mb-1 ${
+                  <label
+                    htmlFor="email"
+                    className={`block text-xs font-medium mb-1 ${
                       mode === "dark"
                         ? "text-gray-300"
                         : "text-gray-700"
                     }`}
                   >
                     Email Address
                   </label>
                   <input
                     type="email"
                     placeholder="your.email@example.com"
                     required
+                    id="email"
+                    name="email"
+                    autoComplete="email"
                     className={`w-full p-2 sm:p-3 rounded-lg sm:rounded-xl text-sm sm:text-base transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-purple-500 ${
                       mode === "dark"
                         ? "bg-white/5 border border-white/20 text-white placeholder-gray-400"
                         : "bg-gray-50 border border-gray-300 text-gray-800 placeholder-gray-500"
                     }`}
                   />
                 </div>

                 {/* Subject */}
                 <div>
-                  <label
-                    className={`block text-xs font-medium mb-1 ${
+                  <label
+                    htmlFor="subject"
+                    className={`block text-xs font-medium mb-1 ${
                       mode === "dark"
                         ? "text-gray-300"
                         : "text-gray-700"
                     }`}
                   >
                     Subject
                   </label>
-                  <select
+                  <select
+                    id="subject"
+                    name="subject"
                     className={`w-full p-2 sm:p-3 rounded-lg sm:rounded-xl text-sm sm:text-base transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-purple-500 ${
                       mode === "dark"
                         ? "bg-white/5 border border-white/20 text-white placeholder-gray-400"
                         : "bg-gray-50 border border-gray-300 text-gray-800 placeholder-gray-500"
                     }`}
                     required
                     defaultValue=""
                   >
                     <option value="" disabled>
                       Select a subject
                     </option>
                     <option>General Inquiry</option>
                     <option>Bug Report</option>
                     <option>Feature Request</option>
                     <option>Other</option>
                   </select>
                 </div>

                 {/* Message */}
                 <div className="relative">
-                  <label
-                    className={`block text-xs font-medium mb-1 ${
+                  <label
+                    htmlFor="message"
+                    className={`block text-xs font-medium mb-1 ${
                       mode === "dark"
                         ? "text-gray-300"
                         : "text-gray-700"
                     }`}
                   >
                     Message
                   </label>
                   <textarea
                     placeholder="Type your message here..."
                     required
                     rows={4}
+                    id="message"
+                    name="message"
                     className={`w-full p-2 sm:p-3 rounded-lg sm:rounded-xl text-sm sm:text-base resize-none transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-purple-500 ${
                       mode === "dark"
                         ? "bg-white/5 border border-white/20 text-white placeholder-gray-400"
                         : "bg-gray-50 border border-gray-300 text-gray-800 placeholder-gray-500"
                     }`}
                   ></textarea>

                   <button
-                    onClick={handleSubmit}
+                    type="submit"
                     disabled={isSubmitting}
                     className={`absolute bottom-2 sm:bottom-3 right-2 sm:right-3 flex items-center gap-1.5 sm:gap-2 rounded-full px-3 sm:px-4 py-1.5 sm:py-2 text-xs sm:text-sm font-semibold transition-all duration-300 hover:scale-105 focus:outline-none focus:ring-2 focus:ring-purple-500 ${
                       isSubmitting
                         ? "bg-purple-400 cursor-wait text-white"
                         : "bg-purple-600 hover:bg-purple-700 text-white"
                     }`}
                   >
                     {isSubmitting ? "Sending..." : "Send"}
                     <Send className="w-4 h-4" />
                   </button>
                 </div>
               </div>
-            </div>
+            </form>

Additionally update handler and imports outside this range:

// imports (line 1)
import { useState, useContext, useEffect, useRef, type FormEvent } from "react";

// inside Contact()
const timeoutRef = useRef<number | null>(null);

const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
  e.preventDefault(); // enable native constraint validation first
  setIsSubmitting(true);

  await new Promise((resolve) => setTimeout(resolve, 1500));

  setIsSubmitting(false);
  setShowPopup(true);

  if (timeoutRef.current) clearTimeout(timeoutRef.current);
  timeoutRef.current = window.setTimeout(() => setShowPopup(false), 5000);
};

useEffect(() => {
  return () => {
    if (timeoutRef.current) clearTimeout(timeoutRef.current);
  };
}, []);

const handleClosePopup = () => {
  if (timeoutRef.current) {
    clearTimeout(timeoutRef.current);
    timeoutRef.current = null;
  }
  setShowPopup(false);
};
🧹 Nitpick comments (5)
src/pages/Contact/Contact.tsx (5)

40-40: Prevent horizontal scrollbars on mobile and better handle dynamic viewport heights

Using w-screen often introduces a subtle horizontal scrollbar on iOS and desktop when vertical scrollbars appear. Prefer w-full + overflow-x-hidden; also add min-h-dvh for better behavior with dynamic viewports.

-      className={`min-h-screen w-screen relative overflow-y-auto ${
+      className={`min-h-screen min-h-dvh w-full relative overflow-y-auto overflow-x-hidden ${

106-133: Avoid recomputing config inside map; iterate directly over data

The current pattern builds contactTypes array on every iteration and indexes into it. Map directly over the array to improve clarity and avoid unnecessary work.

-            <div className="space-y-3 sm:space-y-4 flex-1 flex flex-col justify-center">
-              {[...Array(3)].map((_, index) => {
-                const contactTypes = [
-                  {
-                    title: "Phone Support",
-                    iconBg: "from-blue-500 to-cyan-500",
-                    detail: "(123) 456-7890",
-                    sub: "Mon-Fri, 9AM-6PM EST",
-                    Icon: Phone,
-                  },
-                  {
-                    title: "Email Us",
-                    iconBg: "from-purple-500 to-pink-500",
-                    detail: "support@githubtracker.com",
-                    sub: "We'll respond within 24 hours",
-                    Icon: Mail,
-                  },
-                  {
-                    title: "GitHub Issues",
-                    iconBg: "from-green-500 to-teal-500",
-                    detail: "github.com/yourorg/githubtracker",
-                    sub: "Report bugs & feature requests",
-                    Icon: Github,
-                  },
-                ];
-                const { title, iconBg, detail, sub, Icon } =
-                  contactTypes[index];
-                return (
+            <div className="space-y-3 sm:space-y-4 flex-1 flex flex-col justify-center">
+              {[
+                {
+                  title: "Phone Support",
+                  iconBg: "from-blue-500 to-cyan-500",
+                  detail: "(123) 456-7890",
+                  sub: "Mon-Fri, 9AM-6PM EST",
+                  Icon: Phone,
+                },
+                {
+                  title: "Email Us",
+                  iconBg: "from-purple-500 to-pink-500",
+                  detail: "support@githubtracker.com",
+                  sub: "We'll respond within 24 hours",
+                  Icon: Mail,
+                },
+                {
+                  title: "GitHub Issues",
+                  iconBg: "from-green-500 to-teal-500",
+                  detail: "github.com/yourorg/githubtracker",
+                  sub: "Report bugs & feature requests",
+                  Icon: Github,
+                },
+              ].map(({ title, iconBg, detail, sub, Icon }) => (
                   <div
                     key={title}
                     className={`group p-3 sm:p-5 rounded-xl sm:rounded-2xl backdrop-blur-lg transition-all duration-300 hover:scale-105 ${
                       mode === "dark"
                         ? "bg-white/10 border border-white/20 hover:bg-white/20"
                         : "bg-white border border-gray-300 hover:bg-gray-100"
                     }`}
                   >
                     <div className="flex items-center gap-3 sm:gap-4">
                       <div
                         className={`p-2 sm:p-2.5 rounded-full transition-transform duration-300 group-hover:scale-110 bg-gradient-to-r ${iconBg}`}
                       >
                         <Icon
                           className={`w-4 h-4 sm:w-5 sm:h-5 ${
                             mode === "dark"
                               ? "text-white"
                               : "text-gray-800"
                           }`}
                         />
                       </div>
                       <div>
                         <h3
                           className={`text-sm sm:text-base font-semibold ${
                             mode === "dark"
                               ? "text-white"
                               : "text-gray-800"
                           }`}
                         >
                           {title}
                         </h3>
                         <p
                           className={`text-xs sm:text-sm ${
                             mode === "dark"
                               ? "text-gray-300"
                               : "text-gray-600"
                           }`}
                         >
                           {detail}
                         </p>
                         <p
                           className={`text-xs ${
                             mode === "dark"
                               ? "text-gray-400"
                               : "text-gray-500"
                           }`}
                         >
                           {sub}
                         </p>
                       </div>
                     </div>
                   </div>
-                );
-              })}
+              ))}
             </div>

328-336: Toast a11y: announce success to screen readers and hide decorative icons

Add role and aria-live to the toast; mark icons as aria-hidden.

-        <div
-          className={`fixed top-4 sm:top-6 left-1/2 transform -translate-x-1/2 z-50 w-[90%] sm:w-auto max-w-sm sm:max-w-md px-4 sm:px-6 py-3 sm:py-4 rounded-xl sm:rounded-2xl shadow-lg flex items-center gap-3 sm:gap-4 ${
+        <div
+          role="status"
+          aria-live="polite"
+          aria-atomic="true"
+          className={`fixed top-4 sm:top-6 left-1/2 transform -translate-x-1/2 z-50 w-[90%] sm:w-auto max-w-sm sm:max-w-md px-4 sm:px-6 py-3 sm:py-4 rounded-xl sm:rounded-2xl shadow-lg flex items-center gap-3 sm:gap-4 ${
             mode === "dark"
               ? "bg-green-900 border border-green-700 text-green-100"
               : "bg-green-100 border border-green-400 text-green-900"
           }`}
         >
-          <CheckCircle className="w-6 h-6 sm:w-7 sm:h-7" />
+          <CheckCircle aria-hidden="true" className="w-6 h-6 sm:w-7 sm:h-7" />
           <div className="flex-1 text-xs sm:text-sm font-semibold">
             Thank you for contacting us! We will get back to you shortly.
           </div>
           <button
             onClick={handleClosePopup}
             className="text-lg sm:text-xl px-2 sm:px-3 py-1 rounded-xl hover:bg-green-200/40 focus:outline-none focus:ring-2 focus:ring-green-400"
             aria-label="Close notification"
           >
-            <X />
+            <X aria-hidden="true" />
           </button>
         </div>

Also applies to: 334-336, 340-345


53-53: Optional semantic landmark: use

for primary content

Using a main landmark improves navigation for assistive tech without affecting visuals.

-      <div className="relative z-10 container mx-auto px-4 py-6 max-w-7xl flex flex-col pb-20">
+      <main className="relative z-10 container mx-auto px-4 py-6 max-w-7xl flex flex-col pb-20">
...
-      </div>
+      </main>

Also applies to: 323-324


165-172: Make contact details actionable (tap-to-call, mailto, and link)

Turning these into anchor tags improves UX on mobile:

  • Phone: ...
  • Email: ...
  • URL: ...

If you’d like, I can wire this up by adding an href to each contactTypes item and rendering conditionally.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 00a00d6 and b304861.

📒 Files selected for processing (1)
  • src/pages/Contact/Contact.tsx (12 hunks)
🔇 Additional comments (1)
src/pages/Contact/Contact.tsx (1)

69-71: LGTM: Responsive typography scales well across breakpoints

The heading’s responsive size ramp and gradient text are clean and readable across sizes.

@Sindhura-Karumuri
Copy link
Contributor Author

Please verify my pr

@mehul-m-prajapati mehul-m-prajapati merged commit cda5a3a into GitMetricsLab:main Aug 20, 2025
6 of 7 checks passed
@github-actions
Copy link

🎉🎉 Thank you for your contribution! Your PR #196 has been merged! 🎉🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 Bug Report: Responsiveness

2 participants