-
Notifications
You must be signed in to change notification settings - Fork 1.6k
first up #189
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
base: main
Are you sure you want to change the base?
first up #189
Conversation
WalkthroughA portfolio site rebranding from Adrian's "3dfolio" to Ho Thien Ty's portfolio. Changes include migrating from react-tilt to react-parallax-tilt, removing testimonials, updating the tech stack (Python, Golang, Rust, PostgreSQL), restructuring the About section with personal details, and refreshing all personal content references. Changes
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✨ 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 (1)
src/constants/index.js (1)
50-67: Remove the unusedservicesarray.The
servicesarray is exported fromsrc/constants/index.jsbut is not imported by any component in the codebase. It's dead code and should be removed from both the array definition (lines 50-67) and the export statement (line 148).
🧹 Nitpick comments (4)
package.json (1)
2-2: Consider a more descriptive package name.The name "frontend" is quite generic. Consider using something more specific like "hothientyportfolio" or "ty-portfolio" to better reflect the project's purpose.
src/components/Navbar.jsx (1)
6-6: Inconsistent asset handling: hardcoded logo path.The logo path is hardcoded as
'/newlogo.svg'instead of being imported from the assets module like other images (menu, close). This creates inconsistency and reduces maintainability.Consider importing the logo from assets for consistency:
-import { menu, close } from "../assets"; +import { menu, close, logo } from "../assets";Then use it in the component:
-<img src='/newlogo.svg' alt='logo' className='w-9 h-9 object-contain' /> +<img src={logo} alt='logo' className='w-9 h-9 object-contain' />Note: Ensure the logo export in
src/assets/index.jspoints to the correctnewlogo.svgfile, or update the asset file accordingly.Also applies to: 45-45
src/components/About.jsx (2)
27-90: Improve alt text for accessibility.The alt text for icons (e.g.,
alt='Birth',alt='Email') merely repeats the field name and doesn't add meaningful context for screen readers. Consider using more descriptive alternatives likealt='Date of birth icon'oralt='Email icon'.Apply this diff to improve the alt text:
- <img src={birth} alt='Birth' className='w-6 h-6 object-contain' /> + <img src={birth} alt='Date of birth icon' className='w-6 h-6 object-contain' /> <div> <p className='text-secondary text-[14px]'>Date of birth</p> <p className='text-white text-[16px]'>12/07/2003</p> </div> </motion.div> {/* Email */} <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> - <img src={email} alt='Email' className='w-6 h-6 object-contain' /> + <img src={email} alt='Email icon' className='w-6 h-6 object-contain' /> <div> <p className='text-secondary text-[14px]'>Email</p> <a href='mailto:[email protected]' className='text-white text-[16px] hover:text-[#66ffa6]'> [email protected] </a> </div> </motion.div> {/* Location (đổi vị trí với Phone) */} <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> - <img src={location} alt='Location' className='w-6 h-6 object-contain' /> + <img src={location} alt='Location icon' className='w-6 h-6 object-contain' /> <div> <p className='text-secondary text-[14px]'>Location</p> <p className='text-white text-[16px]'>Chau Doc, An Giang</p> </div> </motion.div> {/* LinkedIn */} <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> - <img src={linkedin} alt='LinkedIn' className='w-6 h-6 object-contain' /> + <img src={linkedin} alt='LinkedIn icon' className='w-6 h-6 object-contain' /> <div> <p className='text-secondary text-[14px]'>LinkedIn</p> <a href='https://linkedin.com/in/htty' target='_blank' rel='noreferrer' className='text-white text-[16px] hover:text-[#66ffa6]'> linkedin.com/in/htty </a> </div> </motion.div> {/* Phone */} <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> - <img src={phone} alt='Phone' className='w-6 h-6 object-contain' /> + <img src={phone} alt='Phone icon' className='w-6 h-6 object-contain' /> <div> <p className='text-secondary text-[14px]'>Phone</p> <p className='text-white text-[16px]'>+84 399623947</p> </div> </motion.div> {/* CV item */} <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> - <img src={cv} alt='CV' className='w-6 h-6 object-contain' /> + <img src={cv} alt='CV icon' className='w-6 h-6 object-contain' />
27-47: Use English for code comments.Comments are written in Vietnamese (e.g., lines 27, 47: "đổi vị trí với Phone"). For international collaboration and code maintainability, consider using English for all code comments.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (15)
package-lock.jsonis excluded by!**/package-lock.jsonpublic/newlogo.svgis excluded by!**/*.svgsrc/assets/CV.pngis excluded by!**/*.pngsrc/assets/birth.pngis excluded by!**/*.pngsrc/assets/company/plpsoft.pngis excluded by!**/*.pngsrc/assets/email.pngis excluded by!**/*.pngsrc/assets/linkedin.pngis excluded by!**/*.pngsrc/assets/location.pngis excluded by!**/*.pngsrc/assets/phone.pngis excluded by!**/*.pngsrc/assets/realtimechat.pngis excluded by!**/*.pngsrc/assets/tech/archlinux.pngis excluded by!**/*.pngsrc/assets/tech/golang.pngis excluded by!**/*.pngsrc/assets/tech/postgresql.pngis excluded by!**/*.pngsrc/assets/tech/python.pngis excluded by!**/*.pngsrc/assets/tech/rust.pngis excluded by!**/*.png
📒 Files selected for processing (10)
index.html(1 hunks)package.json(2 hunks)src/App.jsx(2 hunks)src/assets/index.js(2 hunks)src/components/About.jsx(1 hunks)src/components/Experience.jsx(1 hunks)src/components/Hero.jsx(1 hunks)src/components/Navbar.jsx(2 hunks)src/components/Works.jsx(2 hunks)src/constants/index.js(4 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/components/Hero.jsx (1)
src/styles.js (1)
styles(1-15)
src/components/About.jsx (1)
src/styles.js (1)
styles(1-15)
🔇 Additional comments (11)
index.html (1)
5-7: LGTM! Metadata updates are consistent with the rebranding.The favicon and page title changes align with the portfolio rebranding to "Ho Thien Ty".
package.json (1)
20-20: Dependency migration looks good.The migration from
react-tilttoreact-parallax-tiltis properly reflected here and the usage is updated insrc/components/Works.jsx.src/assets/index.js (1)
23-27: LGTM! Asset additions are properly structured.All new imports have corresponding exports, and the additions follow the existing pattern consistently.
Also applies to: 33-33, 38-44, 68-72, 77-77, 81-87
src/components/Experience.jsx (1)
64-64: LGTM! Minor text improvement.The contraction makes the text more natural and conversational.
src/App.jsx (1)
3-3: LGTM! Clean removal of Feedbacks component.The Feedbacks/Testimonials section has been cleanly removed from both the imports and the render. The comment indicates this is intentional.
Also applies to: 17-17
src/components/Hero.jsx (1)
19-23: LGTM! Hero section updated with new branding.The name and subtext updates are consistent with the portfolio rebranding.
src/components/Navbar.jsx (1)
47-47: LGTM! Brand text updated.The navbar branding is now consistent with the portfolio rebranding.
src/components/Works.jsx (1)
21-26: The react-parallax-tilt API usage is correct.The props
tiltMaxAngleX,tiltMaxAngleY,scale, andtransitionSpeedare all confirmed valid props in the official react-parallax-tilt v1.7.x API. The migration mapping fromreact-tiltis accurate:
max: 45→tiltMaxAngleX={45}andtiltMaxAngleY={45}✓speed: 450→transitionSpeed={450}✓No issues found.
src/constants/index.js (3)
120-146: LGTM!The project entry is well-structured with appropriate tags, description, and source code link.
93-118: The testimonials array is actively used and not unused placeholder data.Verification shows that
src/components/Feedbacks.jsxactively imports and uses the testimonials array (line 7:import { testimonials } from "../constants"and line 58:testimonials.map((testimonial, index) => ...)). The Feedbacks component is functional and rendering the testimonial data. The original review comment's premise—that testimonials are "no longer used" or that "the testimonials component" was removed—is incorrect.Likely an incorrect or invalid review comment.
1-33: ****The review comment is based on an incorrect premise. The verification confirms that ALL 19 imports are actively used and exported from
src/assets/index.js, making them necessary imports insrc/constants/index.js. These assets are being re-exported as part of the module's public API and are referenced throughout the codebase and documentation. No changes are needed.Likely an incorrect or invalid review comment.
| <motion.div | ||
| variants={staggerContainer(0.2, 0)} | ||
| className='mt-10 grid sm:grid-cols-2 gap-6' | ||
| > | ||
| {/* Birth (đổi vị trí với Phone) */} | ||
| <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | ||
| <img src={birth} alt='Birth' className='w-6 h-6 object-contain' /> | ||
| <div> | ||
| <p className='text-secondary text-[14px]'>Date of birth</p> | ||
| <p className='text-white text-[16px]'>12/07/2003</p> | ||
| </div> | ||
| </motion.div> | ||
|
|
||
| {/* Email */} | ||
| <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | ||
| <img src={email} alt='Email' className='w-6 h-6 object-contain' /> | ||
| <div> | ||
| <p className='text-secondary text-[14px]'>Email</p> | ||
| <a href='mailto:[email protected]' className='text-white text-[16px] hover:text-[#66ffa6]'> | ||
| [email protected] | ||
| </a> | ||
| </div> | ||
| </motion.div> | ||
|
|
||
| <div className='mt-20 flex flex-wrap gap-10'> | ||
| {services.map((service, index) => ( | ||
| <ServiceCard key={service.title} index={index} {...service} /> | ||
| ))} | ||
| </div> | ||
| {/* Location (đổi vị trí với Phone) */} | ||
| <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | ||
| <img src={location} alt='Location' className='w-6 h-6 object-contain' /> | ||
| <div> | ||
| <p className='text-secondary text-[14px]'>Location</p> | ||
| <p className='text-white text-[16px]'>Chau Doc, An Giang</p> | ||
| </div> | ||
| </motion.div> | ||
|
|
||
| {/* LinkedIn */} | ||
| <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | ||
| <img src={linkedin} alt='LinkedIn' className='w-6 h-6 object-contain' /> | ||
| <div> | ||
| <p className='text-secondary text-[14px]'>LinkedIn</p> | ||
| <a href='https://linkedin.com/in/htty' target='_blank' rel='noreferrer' className='text-white text-[16px] hover:text-[#66ffa6]'> | ||
| linkedin.com/in/htty | ||
| </a> | ||
| </div> | ||
| </motion.div> | ||
|
|
||
| {/* Phone */} | ||
| <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | ||
| <img src={phone} alt='Phone' className='w-6 h-6 object-contain' /> | ||
| <div> | ||
| <p className='text-secondary text-[14px]'>Phone</p> | ||
| <p className='text-white text-[16px]'>+84 399623947</p> | ||
| </div> | ||
| </motion.div> | ||
|
|
||
| {/* CV item */} | ||
| <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | ||
| <img src={cv} alt='CV' className='w-6 h-6 object-contain' /> | ||
| <div> | ||
| <p className='text-secondary text-[14px]'>CV</p> | ||
| <a | ||
| href='https://drive.google.com/file/d/1VKtMubxBp8E_iKZzRoKDP_Ldmdsrurnd/view?usp=drive_link' | ||
| target='_blank' | ||
| rel='noreferrer' | ||
| className='text-white text-[16px] hover:text-[#66ffa6]' | ||
| > | ||
| View CV | ||
| </a> | ||
| </div> | ||
| </motion.div> | ||
| </motion.div> |
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.
Fix animation timing to enable stagger effect.
All personal detail blocks use fadeIn("up", "spring", 0, 0.75) with a delay of 0, which prevents the staggerContainer(0.2, 0) from producing a staggered animation. For a proper stagger effect, each child should have an incrementing delay or rely on the parent's stagger behavior.
Apply this diff to fix the stagger timing:
<motion.div
- variants={staggerContainer(0.2, 0)}
+ variants={staggerContainer()}
+ initial="hidden"
+ whileInView="show"
className='mt-10 grid sm:grid-cols-2 gap-6'
>
{/* Birth (đổi vị trí với Phone) */}
- <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'>
+ <motion.div variants={fadeIn("up", "spring", 0.1, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'>
<img src={birth} alt='Birth' className='w-6 h-6 object-contain' />
<div>
<p className='text-secondary text-[14px]'>Date of birth</p>
<p className='text-white text-[16px]'>12/07/2003</p>
</div>
</motion.div>
{/* Email */}
- <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'>
+ <motion.div variants={fadeIn("up", "spring", 0.2, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'>
<img src={email} alt='Email' className='w-6 h-6 object-contain' />
<div>
<p className='text-secondary text-[14px]'>Email</p>
<a href='mailto:[email protected]' className='text-white text-[16px] hover:text-[#66ffa6]'>
[email protected]
</a>
</div>
</motion.div>
{/* Location (đổi vị trí với Phone) */}
- <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'>
+ <motion.div variants={fadeIn("up", "spring", 0.3, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'>
<img src={location} alt='Location' className='w-6 h-6 object-contain' />
<div>
<p className='text-secondary text-[14px]'>Location</p>
<p className='text-white text-[16px]'>Chau Doc, An Giang</p>
</div>
</motion.div>
{/* LinkedIn */}
- <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'>
+ <motion.div variants={fadeIn("up", "spring", 0.4, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'>
<img src={linkedin} alt='LinkedIn' className='w-6 h-6 object-contain' />
<div>
<p className='text-secondary text-[14px]'>LinkedIn</p>
<a href='https://linkedin.com/in/htty' target='_blank' rel='noreferrer' className='text-white text-[16px] hover:text-[#66ffa6]'>
linkedin.com/in/htty
</a>
</div>
</motion.div>
{/* Phone */}
- <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'>
+ <motion.div variants={fadeIn("up", "spring", 0.5, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'>
<img src={phone} alt='Phone' className='w-6 h-6 object-contain' />
<div>
<p className='text-secondary text-[14px]'>Phone</p>
<p className='text-white text-[16px]'>+84 399623947</p>
</div>
</motion.div>
{/* CV item */}
- <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'>
+ <motion.div variants={fadeIn("up", "spring", 0.6, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'>
<img src={cv} alt='CV' className='w-6 h-6 object-contain' />
<div>
<p className='text-secondary text-[14px]'>CV</p>📝 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.
| <motion.div | |
| variants={staggerContainer(0.2, 0)} | |
| className='mt-10 grid sm:grid-cols-2 gap-6' | |
| > | |
| {/* Birth (đổi vị trí với Phone) */} | |
| <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | |
| <img src={birth} alt='Birth' className='w-6 h-6 object-contain' /> | |
| <div> | |
| <p className='text-secondary text-[14px]'>Date of birth</p> | |
| <p className='text-white text-[16px]'>12/07/2003</p> | |
| </div> | |
| </motion.div> | |
| {/* Email */} | |
| <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | |
| <img src={email} alt='Email' className='w-6 h-6 object-contain' /> | |
| <div> | |
| <p className='text-secondary text-[14px]'>Email</p> | |
| <a href='mailto:[email protected]' className='text-white text-[16px] hover:text-[#66ffa6]'> | |
| tytybill123@gmail.com | |
| </a> | |
| </div> | |
| </motion.div> | |
| <div className='mt-20 flex flex-wrap gap-10'> | |
| {services.map((service, index) => ( | |
| <ServiceCard key={service.title} index={index} {...service} /> | |
| ))} | |
| </div> | |
| {/* Location (đổi vị trí với Phone) */} | |
| <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | |
| <img src={location} alt='Location' className='w-6 h-6 object-contain' /> | |
| <div> | |
| <p className='text-secondary text-[14px]'>Location</p> | |
| <p className='text-white text-[16px]'>Chau Doc, An Giang</p> | |
| </div> | |
| </motion.div> | |
| {/* LinkedIn */} | |
| <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | |
| <img src={linkedin} alt='LinkedIn' className='w-6 h-6 object-contain' /> | |
| <div> | |
| <p className='text-secondary text-[14px]'>LinkedIn</p> | |
| <a href='https://linkedin.com/in/htty' target='_blank' rel='noreferrer' className='text-white text-[16px] hover:text-[#66ffa6]'> | |
| linkedin.com/in/htty | |
| </a> | |
| </div> | |
| </motion.div> | |
| {/* Phone */} | |
| <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | |
| <img src={phone} alt='Phone' className='w-6 h-6 object-contain' /> | |
| <div> | |
| <p className='text-secondary text-[14px]'>Phone</p> | |
| <p className='text-white text-[16px]'>+84 399623947</p> | |
| </div> | |
| </motion.div> | |
| {/* CV item */} | |
| <motion.div variants={fadeIn("up", "spring", 0, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | |
| <img src={cv} alt='CV' className='w-6 h-6 object-contain' /> | |
| <div> | |
| <p className='text-secondary text-[14px]'>CV</p> | |
| <a | |
| href='https://drive.google.com/file/d/1VKtMubxBp8E_iKZzRoKDP_Ldmdsrurnd/view?usp=drive_link' | |
| target='_blank' | |
| rel='noreferrer' | |
| className='text-white text-[16px] hover:text-[#66ffa6]' | |
| > | |
| View CV | |
| </a> | |
| </div> | |
| </motion.div> | |
| </motion.div> | |
| <motion.div | |
| variants={staggerContainer()} | |
| initial="hidden" | |
| whileInView="show" | |
| className='mt-10 grid sm:grid-cols-2 gap-6' | |
| > | |
| {/* Birth (đổi vị trí với Phone) */} | |
| <motion.div variants={fadeIn("up", "spring", 0.1, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | |
| <img src={birth} alt='Birth' className='w-6 h-6 object-contain' /> | |
| <div> | |
| <p className='text-secondary text-[14px]'>Date of birth</p> | |
| <p className='text-white text-[16px]'>12/07/2003</p> | |
| </div> | |
| </motion.div> | |
| {/* Email */} | |
| <motion.div variants={fadeIn("up", "spring", 0.2, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | |
| <img src={email} alt='Email' className='w-6 h-6 object-contain' /> | |
| <div> | |
| <p className='text-secondary text-[14px]'>Email</p> | |
| <a href='mailto:[email protected]' className='text-white text-[16px] hover:text-[#66ffa6]'> | |
| tytybill123@gmail.com | |
| </a> | |
| </div> | |
| </motion.div> | |
| {/* Location (đổi vị trí với Phone) */} | |
| <motion.div variants={fadeIn("up", "spring", 0.3, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | |
| <img src={location} alt='Location' className='w-6 h-6 object-contain' /> | |
| <div> | |
| <p className='text-secondary text-[14px]'>Location</p> | |
| <p className='text-white text-[16px]'>Chau Doc, An Giang</p> | |
| </div> | |
| </motion.div> | |
| {/* LinkedIn */} | |
| <motion.div variants={fadeIn("up", "spring", 0.4, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | |
| <img src={linkedin} alt='LinkedIn' className='w-6 h-6 object-contain' /> | |
| <div> | |
| <p className='text-secondary text-[14px]'>LinkedIn</p> | |
| <a href='https://linkedin.com/in/htty' target='_blank' rel='noreferrer' className='text-white text-[16px] hover:text-[#66ffa6]'> | |
| linkedin.com/in/htty | |
| </a> | |
| </div> | |
| </motion.div> | |
| {/* Phone */} | |
| <motion.div variants={fadeIn("up", "spring", 0.5, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | |
| <img src={phone} alt='Phone' className='w-6 h-6 object-contain' /> | |
| <div> | |
| <p className='text-secondary text-[14px]'>Phone</p> | |
| <p className='text-white text-[16px]'>+84 399623947</p> | |
| </div> | |
| </motion.div> | |
| {/* CV item */} | |
| <motion.div variants={fadeIn("up", "spring", 0.6, 0.75)} whileHover={{ scale: 1.05 }} className='flex items-center gap-3'> | |
| <img src={cv} alt='CV' className='w-6 h-6 object-contain' /> | |
| <div> | |
| <p className='text-secondary text-[14px]'>CV</p> | |
| <a | |
| href='https://drive.google.com/file/d/1VKtMubxBp8E_iKZzRoKDP_Ldmdsrurnd/view?usp=drive_link' | |
| target='_blank' | |
| rel='noreferrer' | |
| className='text-white text-[16px] hover:text-[#66ffa6]' | |
| > | |
| View CV | |
| </a> | |
| </div> | |
| </motion.div> | |
| </motion.div> |
🤖 Prompt for AI Agents
In src/components/About.jsx lines 23-91, the child motion.divs all call
fadeIn("up", "spring", 0, 0.75) which sets an explicit delay of 0 and overrides
the parent's staggerContainer, preventing staggered entry; remove the explicit
per-child delay (omit the third argument or pass undefined) in each fadeIn call
so the parent staggerContainer(0.2, 0) can control stagger timing, keeping the
direction/type and duration intact.
Summary by CodeRabbit
New Features
Updates