-
Notifications
You must be signed in to change notification settings - Fork 590
Feature/add profile modal #1249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/add profile modal #1249
Conversation
…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
|
@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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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>
…c-keyan/devFind into feature/add-profile-modal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| return () => { | ||
| document.body.style.overflow = 'unset'; | ||
| }; |
Copilot
AI
Nov 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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'; }
| return () => { | |
| document.body.style.overflow = 'unset'; | |
| }; | |
| } else { | |
| document.body.style.overflow = 'unset'; |
| try { | ||
| localStorage.setItem("devFindCustomProfiles", JSON.stringify(profiles)); | ||
| } catch (error) { | ||
| if (error && (error.name === 'QuotaExceededError' || error.code === 22)) { |
Copilot
AI
Nov 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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()} |
Copilot
AI
Nov 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[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.
| 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} |
| 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"> |
Copilot
AI
Nov 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| <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" | |
| > |
| 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" |
Copilot
AI
Nov 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[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.
| 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"> |
Copilot
AI
Nov 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[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.
| <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"> |
| type="text" | ||
| name="name" | ||
| value={formData.name} | ||
| onChange={handleInputChange} |
Copilot
AI
Nov 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
|
|
||
| const newProfile = { | ||
| ...profileData, | ||
| id: `custom_${Date.now()}`, |
Copilot
AI
Nov 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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)}``
| id: `custom_${Date.now()}`, | |
| id: `custom_${crypto.randomUUID()}`, |
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
Form Features
State Management & Persistence
pages/index.jsUI Updates
components/Sidebar.jsxto use button click handler instead of external linkonAddProfileClickprop to trigger modalCleanup
docs.ymlissue template fileChecklist
Screenshots
Note to reviewers
devFindCustomProfiles/public/data/custom_[timestamp]