1
- "use client"
2
- import { useState , useEffect , useRef } from "react"
3
- import { Instagram , Linkedin , Github , Twitter } from "lucide-react"
4
- import Link from "next/link"
5
- import Image from "next/image"
6
- import Logo from "./components/Logo"
7
- import { useLoading } from "./providers/LoadingProvider"
1
+ "use client" ;
2
+ import { useState , useEffect , useRef } from "react" ;
3
+ import { Instagram , Linkedin , Github , Twitter } from "lucide-react" ;
4
+ import Link from "next/link" ;
5
+ import Image from "next/image" ;
6
+ import Logo from "./components/Logo" ;
7
+ import { useLoading } from "./providers/LoadingProvider" ;
8
8
import AboutPic from "../public/portfolio-pic.jpg" ;
9
9
10
10
// Types for company data
@@ -28,7 +28,10 @@ const ExperienceTabs = ({ companies }: { companies: Company[] }) => {
28
28
const tabsContainerRef = useRef < HTMLDivElement > ( null ) ;
29
29
const [ indicatorStyle , setIndicatorStyle ] = useState < React . CSSProperties > ( {
30
30
top : 0 ,
31
+ left : 0 ,
32
+ bottom : 0 ,
31
33
height : 0 ,
34
+ width : 0 ,
32
35
opacity : 0 ,
33
36
transition : 'none'
34
37
} ) ;
@@ -38,12 +41,26 @@ const ExperienceTabs = ({ companies }: { companies: Company[] }) => {
38
41
if ( tabsContainerRef . current ) {
39
42
const activeTabElement = tabsContainerRef . current . children [ activeTab ] as HTMLElement ;
40
43
if ( activeTabElement ) {
41
- setIndicatorStyle ( {
42
- top : activeTabElement . offsetTop + 'px' ,
43
- height : activeTabElement . offsetHeight + 'px' ,
44
- opacity : 1 ,
45
- transition : 'none'
46
- } ) ;
44
+ if ( document . documentElement . clientWidth > 768 ) {
45
+ setIndicatorStyle ( {
46
+ ...indicatorStyle ,
47
+ top : activeTabElement . offsetTop + 'px' ,
48
+ height : activeTabElement . offsetHeight + 'px' ,
49
+ width : '2px' ,
50
+ opacity : 1 ,
51
+ transition : 'none'
52
+ } ) ;
53
+ } else {
54
+ setIndicatorStyle ( {
55
+ ...indicatorStyle ,
56
+ left : activeTabElement . offsetLeft + 'px' ,
57
+ top : activeTabElement . offsetHeight - 2 + 'px' ,
58
+ height : '2px' ,
59
+ width : activeTabElement . offsetWidth + 'px' ,
60
+ opacity : 1 ,
61
+ transition : 'none'
62
+ } ) ;
63
+ }
47
64
}
48
65
}
49
66
} , [ ] ) ;
@@ -53,12 +70,26 @@ const ExperienceTabs = ({ companies }: { companies: Company[] }) => {
53
70
const targetTabElement = tabsContainerRef . current . children [ index ] as HTMLElement ;
54
71
if ( targetTabElement ) {
55
72
// Set smooth transition for subsequent tab changes
56
- setIndicatorStyle ( {
57
- top : targetTabElement . offsetTop + 'px' ,
58
- height : targetTabElement . offsetHeight + 'px' ,
59
- opacity : 1 ,
60
- transition : 'all 0.3s ease-out'
61
- } ) ;
73
+ if ( document . documentElement . clientWidth > 768 ) {
74
+ setIndicatorStyle ( {
75
+ ...indicatorStyle ,
76
+ top : targetTabElement . offsetTop + 'px' ,
77
+ height : targetTabElement . offsetHeight + 'px' ,
78
+ width : '2px' ,
79
+ opacity : 1 ,
80
+ transition : 'all 0.3s ease-out'
81
+ } ) ;
82
+ } else {
83
+ setIndicatorStyle ( {
84
+ ...indicatorStyle ,
85
+ left : targetTabElement . offsetLeft + 'px' ,
86
+ top : targetTabElement . offsetHeight - 2 + 'px' ,
87
+ height : '2px' ,
88
+ width : targetTabElement . offsetWidth + 'px' ,
89
+ opacity : 1 ,
90
+ transition : 'all 0.3s ease-out'
91
+ } ) ;
92
+ }
62
93
setActiveTab ( index ) ;
63
94
}
64
95
}
@@ -67,21 +98,21 @@ const ExperienceTabs = ({ companies }: { companies: Company[] }) => {
67
98
return (
68
99
< div className = "relative flex flex-col md:flex-row" >
69
100
{ /* Tab list - vertical company names */ }
70
- < div className = "w-full md:w-60 mb-8 md:mb-0 border-b md:border-b-0 md:border-l border-[#64ffda]/30 relative" >
101
+ < div className = "w-full overflow-x-auto md:w-60 mb-8 md:mb-0 border-b border-l-0 md:border-b-0 md:border-l border-[#64ffda]/30 relative" >
71
102
{ /* Animated indicator */ }
72
103
< span
73
- className = "absolute left-0 w-0.5 bg-[#64ffda] z-10"
104
+ className = "absolute left-0 bg-[#64ffda] z-10"
74
105
style = { indicatorStyle }
75
106
> </ span >
76
107
77
- < div ref = { tabsContainerRef } >
108
+ < div ref = { tabsContainerRef } className = "flex flex-row md:flex-col" >
78
109
{ companies . map ( ( company : Company , index : number ) => (
79
110
< button
80
111
key = { company . name }
81
- className = { `text-left py-3 px-5 w-full focus: outline-none transition-all font-mono text-sm cursor-pointer
112
+ className = { `text-left py-3 px-5 w-full outline-none transition-all font-mono text-sm cursor-pointer
82
113
${ index === activeTab ?
83
114
'text-[#64ffda] bg-[#112240]/50' :
84
- 'text-gray-400 hover:text-[#64ffda] hover:bg-[#112240]/20' } `}
115
+ 'text-gray-300 hover:text-[#64ffda] hover:bg-[#112240]/20' } `}
85
116
onClick = { ( ) => handleTabChange ( index ) }
86
117
>
87
118
{ company . name }
@@ -116,12 +147,12 @@ const ExperienceTabs = ({ companies }: { companies: Company[] }) => {
116
147
</ Link >
117
148
</ span >
118
149
</ h3 >
119
- < p className = "text-xs text-gray-400 mt-1" >
150
+ < p className = "text-xs text-gray-300 mt-1" >
120
151
{ company . description . startDate } - { company . description . lastDate }
121
152
</ p >
122
153
</ div >
123
154
124
- < ul className = "space-y-3 text-sm text-gray-400 mt-5" >
155
+ < ul className = "space-y-3 text-sm text-gray-300 mt-5" >
125
156
{ company . description . details . map ( ( detail : string , i : number ) => (
126
157
< li key = { i } className = "flex" >
127
158
< span className = "text-[#64ffda] mr-2 flex-shrink-0" > ▹</ span >
@@ -152,7 +183,7 @@ export default function Home() {
152
183
companyName : "American Express" ,
153
184
link : "https://www.americanexpress.com/" ,
154
185
startDate : "January 2023" ,
155
- lastDate : "Present " ,
186
+ lastDate : "May 2025 " ,
156
187
details : [
157
188
"Developing highly interactive web applications for American Express using React" ,
158
189
"Developing Common Libraries used internally and Managing CI/CD Pipelines" ,
@@ -351,7 +382,7 @@ export default function Home() {
351
382
</ li >
352
383
< li >
353
384
< Link
354
- href = "https://drive.google.com/file/d/19r3mIyShOkOAAXVclH_0EaxNQAp-kUsk /view"
385
+ href = "https://drive.google.com/file/d/12llr7QvEY7TpPMgiO0gi8hYvh1DjmiAc /view"
355
386
target = "_blank"
356
387
className = "border border-[#64ffda] text-[#64ffda] px-3 py-2 rounded-sm hover:bg-[#64ffda]/10 transition-colors"
357
388
>
@@ -432,7 +463,7 @@ export default function Home() {
432
463
</ li >
433
464
< li className = "w-full text-center mt-6" >
434
465
< Link
435
- href = "https://drive.google.com/file/d/19r3mIyShOkOAAXVclH_0EaxNQAp-kUsk /view"
466
+ href = "https://drive.google.com/file/d/12llr7QvEY7TpPMgiO0gi8hYvh1DjmiAc /view"
436
467
target = "_blank"
437
468
className = "border border-[#64ffda] text-[#64ffda] px-8 py-4 rounded-sm hover:bg-[#64ffda]/10 transition-colors inline-block text-base"
438
469
>
@@ -476,9 +507,9 @@ export default function Home() {
476
507
{ /* Hero section */ }
477
508
< section id = "hero" className = { `min-h-[80vh] flex flex-col justify-center ${ isLoading ? 'opacity-0' : 'opacity-100 animate-fadeInUp' } ` } >
478
509
< p className = "text-[#64ffda] mb-5 font-mono text-sm" > Hi, my name is</ p >
479
- < h1 className = "text-4xl sm:text-5xl md:text-6xl font-bold text-gray-200 mb-4" > Harsh Dave.</ h1 >
510
+ < h1 className = "text-4xl sm:text-5xl md:text-6xl font-bold text-gray-100 mb-4" > Harsh Dave.</ h1 >
480
511
< h2 className = "text-3xl sm:text-4xl md:text-5xl font-bold text-gray-400 mb-6" > I build things for the web.</ h2 >
481
- < p className = "max-w-xl text-gray-400 mb-12 text-sm sm:text-md" >
512
+ < p className = "max-w-xl text-gray-300 mb-12 text-sm sm:text-md" >
482
513
I'm a software engineer based in Bengaluru specializing in building and occasionally designing
483
514
high-quality websites and applications.
484
515
</ p >
@@ -500,22 +531,22 @@ export default function Home() {
500
531
501
532
< div className = "grid grid-cols-1 md:grid-cols-3 gap-10" >
502
533
< div className = "md:col-span-2" >
503
- < p className = "mb-4 text-sm sm:text-md text-gray-400 " >
534
+ < p className = "mb-4 text-sm sm:text-md text-gray-300 " >
504
535
Hello! I'm Harsh, a software engineer based in Bengaluru, who
505
536
enjoys building things that live on the internet. I develop websites
506
537
and web applications that provide intuitive, pixel-perfect user interfaces
507
538
with efficient and modern backends.
508
539
</ p >
509
- < p className = "mb-4 text-sm sm:text-md text-gray-400 " >
540
+ < p className = "mb-4 text-sm sm:text-md text-gray-300 " >
510
541
< span > Shortly after graduating from{ ' ' } </ span > < Link href = "https://gtu.ac.in/" target = "_blank" className = "text-[#64ffda]" > Gujarat Technological University</ Link >
511
542
< span > , I joined the development team at{ ' ' } </ span > < Link href = "https://www.ashutec.com/" target = "_blank" className = "text-[#64ffda]" > Ashutec Solutions</ Link >
512
543
< span > , where I work on a wide variety of interesting and meaningful projects on a daily basis.</ span >
513
544
< span > Currently I work at{ ' ' } </ span > < Link href = "https://www.americanexpress.com/" target = "_blank" className = "text-[#64ffda]" > American Express</ Link >
514
545
< span > , where I work on a wide variety of interesting and meaningful projects on a daily basis.</ span >
515
546
</ p >
516
- < p className = "mb-6 text-sm sm:text-md text-gray-400 " > Here are a few technologies I've been working with recently:</ p >
547
+ < p className = "mb-6 text-sm sm:text-md text-gray-300 " > Here are a few technologies I've been working with recently:</ p >
517
548
518
- < div className = "grid grid-cols-2 gap-2 text-xs text-gray-400 " >
549
+ < div className = "grid grid-cols-2 gap-2 text-xs text-gray-300 " >
519
550
< div className = "flex items-center" >
520
551
< span className = "text-[#64ffda] mr-2" > ▹</ span > HTML & ( S ) CSS
521
552
< / d i v >
@@ -585,12 +616,12 @@ export default function Home() {
585
616
</ svg >
586
617
</ div >
587
618
< div className = "flex gap-3" >
588
- < a href = "#" className = "text-gray-400 hover:text-[#64ffda]" >
619
+ { /* <a href="#" className="text-gray-300 hover:text-[#64ffda]">
589
620
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
590
621
<path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path>
591
622
</svg>
592
- </ a >
593
- < a href = "#" className = "text-gray-400 hover:text-[#64ffda]" >
623
+ </a> */ }
624
+ < a href = "https://diypc.vercel.app" target = "_blank" className = "text-gray-300 hover:text-[#64ffda]" >
594
625
< svg xmlns = "http://www.w3.org/2000/svg" width = "20" height = "20" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" strokeWidth = "2" strokeLinecap = "round" strokeLinejoin = "round" >
595
626
< path d = "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" > </ path >
596
627
< polyline points = "15 3 21 3 21 9" > </ polyline >
@@ -599,15 +630,16 @@ export default function Home() {
599
630
</ a >
600
631
</ div >
601
632
</ div >
602
- < h3 className = "text-gray-200 text-lg sm:text-xl mb-2 font-medium" > E-commerce Platform </ h3 >
603
- < p className = "text-xs text-gray-400 mb-4" >
604
- A full-featured e-commerce solution with product management, cart functionality , and secure payment processing .
633
+ < h3 className = "text-gray-200 text-lg sm:text-xl mb-2 font-medium" > DIYPC </ h3 >
634
+ < p className = "text-xs text-gray-300 mb-4" >
635
+ DIYPC helps you create a custom PC that meets your needs and budget with AI-powered recommendations, compatibility checking , and expert guidance .
605
636
</ p >
606
- < div className = "flex flex-wrap gap-2 text-xs text-gray-400" >
607
- < span > React</ span >
608
- < span > Node.js</ span >
609
- < span > MongoDB</ span >
610
- < span > Stripe API</ span >
637
+ < div className = "flex flex-wrap gap-2 text-xs text-gray-300" >
638
+ < span > Next.js</ span >
639
+ < span > Tailwind CSS</ span >
640
+ < span > Framer Motion</ span >
641
+ < span > Firebase</ span >
642
+ < span > Gemini</ span >
611
643
</ div >
612
644
</ div >
613
645
@@ -619,12 +651,12 @@ export default function Home() {
619
651
</ svg >
620
652
</ div >
621
653
< div className = "flex gap-3" >
622
- < a href = "#" className = "text-gray-400 hover:text-[#64ffda]" >
654
+ < a href = "https://github.com/coderhd/ds-algo-flashcards" target = "_blank" className = "text-gray-300 hover:text-[#64ffda]" >
623
655
< svg xmlns = "http://www.w3.org/2000/svg" width = "20" height = "20" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" strokeWidth = "2" strokeLinecap = "round" strokeLinejoin = "round" >
624
656
< path d = "M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22" > </ path >
625
657
</ svg >
626
658
</ a >
627
- < a href = "#" className = "text-gray-400 hover:text-[#64ffda]" >
659
+ < a href = "https://ds-algo-flashcards.vercel.app" target = "_blank" className = "text-gray-300 hover:text-[#64ffda]" >
628
660
< svg xmlns = "http://www.w3.org/2000/svg" width = "20" height = "20" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" strokeWidth = "2" strokeLinecap = "round" strokeLinejoin = "round" >
629
661
< path d = "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" > </ path >
630
662
< polyline points = "15 3 21 3 21 9" > </ polyline >
@@ -633,15 +665,14 @@ export default function Home() {
633
665
</ a >
634
666
</ div >
635
667
</ div >
636
- < h3 className = "text-gray-200 text-lg sm:text-xl mb-2 font-medium" > Analytics Dashboard < / h 3 >
637
- < p className = "text-xs text-gray-400 mb-4" >
638
- Interactive data visualization dashboard with real-time analytics, customizable widgets, and reporting .
668
+ < h3 className = "text-gray-200 text-lg sm:text-xl mb-2 font-medium" > DSA Flashcards < / h 3 >
669
+ < p className = "text-xs text-gray-300 mb-4" >
670
+ A modern, mobile-friendly web application for studying data structures and algorithms on the go. It's a perfect companion for technical interview preparation .
639
671
</ p >
640
- < div className = "flex flex-wrap gap-2 text-xs text-gray-400" >
641
- < span > React</ span >
642
- < span > D3 . js < / s p a n >
643
- < span > Firebase</ span >
644
- < span > Chart . js < / s p a n >
672
+ < div className = "flex flex-wrap gap-2 text-xs text-gray-300" >
673
+ < span > Next.js</ span >
674
+ < span > Shadcn UI < / s p a n >
675
+ < span > Tailwind CSS</ span >
645
676
< / d i v >
646
677
</div >
647
678
@@ -653,12 +684,12 @@ export default function Home() {
653
684
</ svg >
654
685
</ div >
655
686
< div className = "flex gap-3" >
656
- < a href = "#" className = "text-gray-400 hover:text-[#64ffda]" >
687
+ { /* <a href="#" className="text-gray-300 hover:text-[#64ffda]">
657
688
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
658
689
<path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path>
659
690
</svg>
660
- </ a >
661
- < a href = "#" className = "text-gray-400 hover:text-[#64ffda]" >
691
+ </a> */ }
692
+ < a href = "https://play.google.com/store/apps/details?id=com.instacaptions" target = "_blank" className = "text-gray-300 hover:text-[#64ffda]" >
662
693
< svg xmlns = "http://www.w3.org/2000/svg" width = "20" height = "20" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" strokeWidth = "2" strokeLinecap = "round" strokeLinejoin = "round" >
663
694
< path d = "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" > </ path >
664
695
< polyline points = "15 3 21 3 21 9" > </ polyline >
@@ -667,15 +698,15 @@ export default function Home() {
667
698
</ a >
668
699
</ div >
669
700
</ div >
670
- < h3 className = "text-gray-200 text-lg sm:text-xl mb-2 font-medium" > Social Media App </ h3 >
671
- < p className = "text-xs text-gray-400 mb-4" >
672
- Mobile-first social networking application with real-time messaging, post sharing, and user profiles .
701
+ < h3 className = "text-gray-200 text-lg sm:text-xl mb-2 font-medium" > Insta Caption </ h3 >
702
+ < p className = "text-xs text-gray-300 mb-4" >
703
+ Insta Caption is a mobile application that helps users generate AI-based content for social media including captions, hashtags, and profile bios .
673
704
</ p >
674
- < div className = "flex flex-wrap gap-2 text-xs text-gray-400 " >
705
+ < div className = "flex flex-wrap gap-2 text-xs text-gray-300 " >
675
706
< span > React Native</ span >
676
- < span > Express </ span >
677
- < span > Socket.io </ span >
678
- < span > AWS </ span >
707
+ < span > Firebase </ span >
708
+ < span > GPT 4.1 </ span >
709
+ < span > AdMob </ span >
679
710
</ div >
680
711
</ div >
681
712
< / d i v >
@@ -688,7 +719,7 @@ export default function Home() {
688
719
</ h2 >
689
720
690
721
< h3 className = "text-3xl md:text-4xl font-bold text-gray-200 mb-6" > Get In Touch < / h 3 >
691
- < p className = "max-w-md mx-auto text-gray-400 mb-10 text-sm sm:text-md" >
722
+ < p className = "max-w-md mx-auto text-gray-300 mb-10 text-sm sm:text-md" >
692
723
I'm currently open to freelance opportunities and new projects. If you have an exciting project in mind or just want to say hi, feel free to reach out and I'll get back to you as soon as possible!
693
724
</ p >
694
725
0 commit comments