Skip to content

Conversation

@karthic-keyan
Copy link

Description

This PR implements the "Add your profile" feature that was missing from the UI. Users can now click the "Add your profile" button to open a modal with a form to submit their profile information. The feature includes form validation, localStorage persistence, and seamless integration with the existing profile listing system.

Related Issues

This PR addresses the issue: "The 'Add your profile' button in the UI currently does not open any modal or form. Users have no way to add their profile information."

Changes Proposed

New Component: AddProfileModal

  • Created a comprehensive modal component with form fields for:
    • Full Name (required)
    • GitHub Profile Link (required, with URL validation)
    • LinkedIn Profile Link (optional)
    • Twitter Profile Link (optional)
    • Profile Photo URL (required, with URL validation)
    • Portfolio Link (optional, defaults to GitHub if empty)
    • Location (optional)
    • Bio (optional)
    • Skills (comma-separated, optional)

Form Features

  • Real-time form validation with error messages
  • URL validation for GitHub and profile photo fields
  • Error messages clear as users start typing
  • Submit and Cancel buttons with proper styling
  • Dark mode support with Tailwind CSS
  • Close button (X) in top-right corner

State Management & Persistence

  • Added modal state management in pages/index.js
  • Implemented localStorage integration to persist custom profiles
  • New profiles are automatically merged with existing profiles
  • Profiles persist across browser sessions and page refreshes

UI Updates

  • Modified components/Sidebar.jsx to use button click handler instead of external link
  • Added onAddProfileClick prop to trigger modal
  • Maintained all existing styling and theme functionality

Cleanup

  • Removed docs.yml issue template file

Checklist

  • I have read and followed the Contribution Guidelines.
  • All new and existing tests passed.
  • I have updated the documentation to reflect the changes I've made.
  • My code follows the code style of this project.
  • The title of my pull request is a short description of the requested changes.

Screenshots

Screenshot 2025-11-17 192658

Note to reviewers

  • The new profiles are stored in browser localStorage under the key devFindCustomProfiles
  • Profiles follow the same data structure as existing profiles in /public/data/
  • Each custom profile gets a unique ID with format custom_[timestamp]
  • The implementation maintains backward compatibility with existing functionality
  • Form validation ensures data integrity before submission
  • The modal is fully responsive and supports both light and dark modes

…ence

- Create AddProfileModal component with form validation
- Add fields for name, GitHub, LinkedIn, Twitter, avatar, portfolio, location, bio, and skills
- Implement localStorage integration to persist custom profiles
- Integrate modal into main page with state management
- Update Sidebar button to trigger modal instead of external link
- Remove docs.yml issue template

Features:
- Form validation for required fields (name, GitHub link, profile photo URL)
- URL validation for GitHub and profile photos
- Real-time error clearing as users type
- Dark mode support with Tailwind CSS
- New profiles display immediately in the developer list
- Profiles persist across browser sessions
Copilot AI review requested due to automatic review settings November 17, 2025 13:57
@vercel
Copy link

vercel bot commented Nov 17, 2025

@karthic-keyan is attempting to deploy a commit to the Shyam Tawli's projects Team on Vercel.

A member of the Team first needs to authorize it.

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.

Great job, @karthic-keyan! 🎉 Thank you for opening a pull request. Your contribution is valuable and we appreciate your efforts to improve our project.

Soon the maintainers/owner will review it and provide you with feedback/suggestions.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements a comprehensive "Add Your Profile" modal feature that allows users to submit their profile information directly through the UI, with localStorage persistence for custom profiles. The implementation includes form validation, dark mode support, and seamless integration with the existing profile listing system.

Key Changes

  • Created a new AddProfileModal component with comprehensive form fields and validation for profile submission
  • Integrated localStorage-based persistence to store and retrieve custom user profiles across browser sessions
  • Modified Sidebar component to trigger the modal instead of linking to external documentation

Reviewed Changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 9 comments.

File Description
pages/index.js Added modal state management, localStorage integration functions, and profile submission handler with automatic data merging
components/Sidebar.jsx Replaced anchor tag with button element and added click handler prop to trigger the modal
components/AddProfileModal.jsx New modal component with form fields, validation logic, error handling, and responsive design for both light and dark modes
.github/ISSUE_TEMPLATE/docs.yml Whitespace-only formatting change with no functional impact

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

karthic-keyan and others added 6 commits November 17, 2025 19:33
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +23 to +25
return () => {
document.body.style.overflow = 'unset';
};
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

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

The cleanup function only runs when the modal is open, but document.body.style.overflow should be reset when isOpen becomes false. The current implementation may leave overflow: 'hidden' set if the effect doesn't cleanup properly. Move the reset logic to run whenever isOpen changes by adding an else clause: if (isOpen) { document.body.style.overflow = 'hidden'; } else { document.body.style.overflow = 'unset'; }

Suggested change
return () => {
document.body.style.overflow = 'unset';
};
} else {
document.body.style.overflow = 'unset';

Copilot uses AI. Check for mistakes.
try {
localStorage.setItem("devFindCustomProfiles", JSON.stringify(profiles));
} catch (error) {
if (error && (error.name === 'QuotaExceededError' || error.code === 22)) {
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

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

The magic number 22 used for error code checking is unclear. Consider defining a constant like const QUOTA_EXCEEDED_ERROR_CODE = 22 or adding a comment explaining that code 22 is the legacy error code for QuotaExceededError in older browsers.

Copilot uses AI. Check for mistakes.
Comment on lines +121 to +126
if (!isOpen) return null;

return (
<div
className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
onClick={(e) => e.target === e.currentTarget && handleClose()}
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

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

[nitpick] The inline arrow function in the onClick handler is unnecessarily complex. Extract this to a separate handler function like handleBackdropClick for better readability and testability.

Suggested change
if (!isOpen) return null;
return (
<div
className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
onClick={(e) => e.target === e.currentTarget && handleClose()}
const handleBackdropClick = (e) => {
if (e.target === e.currentTarget) {
handleClose();
}
};
if (!isOpen) return null;
return (
<div
className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
onClick={handleBackdropClick}

Copilot uses AI. Check for mistakes.
className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
onClick={(e) => e.target === e.currentTarget && handleClose()}
>
<div className="relative w-full max-w-2xl rounded-lg bg-white p-8 shadow-lg dark:bg-textPrimary md:max-h-[90vh] md:overflow-y-auto">
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

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

The modal dialog is missing essential ARIA attributes for accessibility. Add role=\"dialog\", aria-modal=\"true\", aria-labelledby=\"modal-title\", and aria-describedby=\"modal-description\" to the modal container div to properly announce it to screen readers.

Suggested change
<div className="relative w-full max-w-2xl rounded-lg bg-white p-8 shadow-lg dark:bg-textPrimary md:max-h-[90vh] md:overflow-y-auto">
<div
className="relative w-full max-w-2xl rounded-lg bg-white p-8 shadow-lg dark:bg-textPrimary md:max-h-[90vh] md:overflow-y-auto"
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
aria-describedby="modal-description"
>

Copilot uses AI. Check for mistakes.
value={formData.linkedin}
onChange={handleInputChange}
placeholder="https://linkedin.com/in/johndoe"
className="w-full px-4 py-2 mt-1 border-2 rounded-lg outline-none focus:border-primaryFocus focus:bg-primaryLight dark:focus:border-secondaryFocus dark:focus:bg-secondaryLight border-borderSecondary bg-primaryColor text-secondaryColor dark:border-borderColor dark:bg-secondaryColor dark:text-white"
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

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

[nitpick] The className string for optional input fields (LinkedIn, Twitter, Portfolio, Location, Bio, Skills) contains repetitive Tailwind classes. Consider extracting these to a shared constant or CSS class to reduce duplication and improve maintainability. The same pattern appears on lines 196, 210, 246, 263, 277, and 291.

Copilot uses AI. Check for mistakes.
return currentUrl === "/" ? (
<div className="App flex flex-col bg-primaryColor dark:bg-secondaryColor md:flex-row">
<Sidebar />
<div className="flex flex-col App bg-primaryColor dark:bg-secondaryColor md:flex-row">
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

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

[nitpick] The order of className values changed from App flex flex-col to flex flex-col App. While this works, it's better to place custom class names after utility classes to follow Tailwind CSS best practices and maintain consistent ordering throughout the codebase.

Suggested change
<div className="flex flex-col App bg-primaryColor dark:bg-secondaryColor md:flex-row">
<div className="flex flex-col bg-primaryColor dark:bg-secondaryColor md:flex-row App">

Copilot uses AI. Check for mistakes.
Comment on lines +153 to +156
type="text"
name="name"
value={formData.name}
onChange={handleInputChange}
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

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

Input fields are missing id attributes that should match the htmlFor attribute on their labels. Add id props to all input elements (e.g., id=\"name\", id=\"github\", etc.) and corresponding htmlFor attributes on the labels to properly associate them for accessibility.

Copilot uses AI. Check for mistakes.

const newProfile = {
...profileData,
id: `custom_${Date.now()}`,
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

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

Using Date.now() for ID generation can result in duplicate IDs if multiple profiles are added rapidly in quick succession (within the same millisecond). Consider using a more robust approach like crypto.randomUUID() or combining timestamp with a random component: id: \custom_${Date.now()}_${Math.random().toString(36).substr(2, 9)}``

Suggested change
id: `custom_${Date.now()}`,
id: `custom_${crypto.randomUUID()}`,

Copilot uses AI. Check for mistakes.
@karthic-keyan karthic-keyan closed this by deleting the head repository Nov 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant