Skip to content

Commit 5461232

Browse files
Merge branch 'master' into dependabot/npm_and_yarn/npm_and_yarn-6195bffe15
2 parents 1c3224f + 343cd54 commit 5461232

18 files changed

+13089
-42
lines changed

bun.lockb

-462 KB
Binary file not shown.

package.json

+7-2
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,20 @@
1717
"@radix-ui/react-label": "^2.1.0",
1818
"@radix-ui/react-slot": "^1.1.0",
1919
"@radix-ui/react-tooltip": "^1.1.3",
20+
"@sanity/client": "^6.28.2",
21+
"@sanity/icons": "^3.7.0",
2022
"@sanity/image-url": "^1.1.0",
21-
"@sanity/vision": "3",
23+
"@sanity/ui": "^2.14.4",
24+
"@sanity/vision": "^3.77.2",
2225
"@studio-freight/lenis": "^1.0.42",
2326
"@types/canvas-confetti": "^1.6.4",
27+
"@vercel/analytics": "^1.5.0",
28+
"@vercel/speed-insights": "^1.2.0",
2429
"canvas-confetti": "^1.9.3",
2530
"class-variance-authority": "^0.7.0",
2631
"clsx": "^2.1.1",
27-
"framer-motion": "^11.11.17",
2832
"lucide-react": "^0.453.0",
33+
"motion": "^12.4.7",
2934
"next": "15.1.2",
3035
"next-sanity": "^9.8.8",
3136
"next-themes": "^0.3.0",

pnpm-lock.yaml

+12,900
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/resume.pdf

71.3 KB
Binary file not shown.

src/app/(root)/layout.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import FooterGradient from "@/components/common/footer-gradient";
55
import Header from "@/components/common/header";
66
import HeaderGradient from "@/components/common/header-gradient";
77
import { ThemeProvider } from "@/components/theme/theme-provider";
8-
import { ThemeSwitch } from "@/components/theme/theme-switch";
98
import { TooltipProvider } from "@/components/ui/tooltip";
109
import { SanityLive } from "@/sanity/lib/live";
10+
import VercelAnalytics from "./vercel-analytics";
1111

1212
const inter = Inter({
1313
weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"],
@@ -25,13 +25,13 @@ export default function RootLayout({
2525
<ThemeProvider attribute="class" defaultTheme="dark">
2626
<TooltipProvider>
2727
<Header />
28-
<ThemeSwitch className="fixed bottom-10 left-10 z-10" />
2928
{children}
3029
<Footer />
3130
</TooltipProvider>
3231
</ThemeProvider>
3332
<FooterGradient />
3433
<SanityLive />
34+
<VercelAnalytics />
3535
</body>
3636
);
3737
}

src/app/(root)/page.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ const HomePage = () => {
5858
</div>
5959
</section>
6060

61-
<section className="flex items-center justify-between py-16">
62-
<div className="space-y-3">
61+
<section className="flex flex-col sm:flex-row items-center justify-between py-16 gap-y-4">
62+
<div className="space-y-3 text-center sm:text-left">
6363
<h2 className="text-3xl font-bold md:text-5xl">
6464
Let&apos;s work together
6565
</h2>

src/app/(root)/vercel-analytics.tsx

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Analytics } from "@vercel/analytics/next";
2+
import { SpeedInsights } from "@vercel/speed-insights/next";
3+
4+
const VercelAnalytics = () => {
5+
return (
6+
<>
7+
<Analytics />
8+
<SpeedInsights />
9+
</>
10+
);
11+
};
12+
13+
export default VercelAnalytics;

src/app/not-found.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"use client";
22

33
import clsx from "clsx";
4-
import { motion } from "framer-motion";
4+
import { motion } from "motion/react"
55
import { ArrowLeft } from "lucide-react";
66
import Link from "next/link";
77

src/components/common/footer.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const Footer = () => {
2525
</Link>
2626
</p>
2727
</div>
28-
<div className="grid gap-16 -order-1 md:order-2 grid-cols-2 md:gap-20">
28+
<div className="grid gap-16 -order-1 md:order-2 grid-cols-2 md:grid-cols-3">
2929
<div className="flex flex-col gap-8">
3030
<p className="font-bold text-onyx dark:text-white">Links</p>
3131
<ul className="flex flex-col gap-4">
@@ -45,7 +45,7 @@ const Footer = () => {
4545
))}
4646
</ul>
4747
</div>
48-
<div className="flex flex-col gap-8">
48+
<div className="flex flex-col gap-8 md:col-span-2">
4949
<p className="font-bold text-onyx dark:text-white">Elsewhere</p>
5050
<ul className="flex flex-col gap-4 text-muted">
5151
{socials.map((social) => (

src/components/common/header.tsx

+30-6
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,39 @@
1-
"use client"
1+
"use client";
22

33
import Link from "next/link";
4-
import { motion } from "framer-motion";
4+
import { motion, useMotionValueEvent, useScroll } from "motion/react";
55

66
import { navLinks, socials } from "@/lib/constants";
77
import Logo from "./logo";
88
import MobileNav from "./mobile-nav";
9+
import { useState } from "react";
10+
import { ThemeSwitch } from "../theme/theme-switch";
911

1012
const Header = () => {
13+
const [hidden, setHidden] = useState(false);
14+
15+
const { scrollY } = useScroll();
16+
17+
useMotionValueEvent(scrollY, "change", (latest: number) => {
18+
const prev = scrollY.getPrevious() || 0;
19+
20+
if (latest > prev && latest > 100) {
21+
setHidden(true);
22+
} else {
23+
setHidden(false);
24+
}
25+
});
1126
return (
1227
<>
1328
<motion.header
14-
initial={{ translateY: -100 }}
15-
animate={{ translateY: 0 }}
29+
variants={{
30+
visible: { y: 0 },
31+
hidden: { y: -200 },
32+
}}
33+
initial={{ y: -200 }}
34+
animate={hidden ? "hidden" : "visible"}
1635
transition={{ duration: 0.2 }}
17-
className="relative z-[999] pt-10 hidden px-4 md:block"
36+
className="hidden px-4 md:block sticky top-5 w-full z-50"
1837
>
1938
<div className="container mx-auto flex h-16 w-full max-w-[1024px] items-center justify-between rounded-full border-[1px] border-white/25 bg-white/25 px-8 backdrop-blur-md dark:border-[#5E5E5E]/20 dark:bg-[#18181D]/30">
2039
<div className="flex items-center gap-10">
@@ -44,7 +63,7 @@ const Header = () => {
4463
</nav>
4564
</div>
4665
<div className="flex items-center gap-4">
47-
<div className="flex gap-6 text-onyx/70 dark:text-white/70">
66+
<div className="flex gap-6 text-onyx/70 dark:text-white/70 items-center">
4867
{socials.map((social) => (
4968
<Link
5069
key={`header-social-${social.name}`}
@@ -56,10 +75,13 @@ const Header = () => {
5675
<social.icon className="size-6" />
5776
</Link>
5877
))}
78+
<ThemeSwitch variant="ghost" />
5979
</div>
6080
</div>
6181
</div>
6282
</motion.header>
83+
84+
{/* Logo on the top in mobile view */}
6385
<Link
6486
href="/"
6587
aria-label="Vignesh Gupta Logo"
@@ -71,6 +93,8 @@ const Header = () => {
7193
className="block mx-auto md:hidden opacity-60"
7294
/>
7395
</Link>
96+
97+
{/* Mobile navigation bar */}
7498
<MobileNav />
7599
</>
76100
);

src/components/common/mobile-nav.tsx

+31-8
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,39 @@
1+
12
import Link from "next/link";
2-
import { motion } from "framer-motion";
3+
import { motion, useMotionValueEvent, useScroll } from "motion/react";
34

4-
import { navLinks, socials } from "@/lib/constants";
5+
import { navLinks } from "@/lib/constants";
56
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
67
import Logo from "./logo";
8+
import { useState } from "react";
9+
import MobileSocialMenu from "./mobile-social-menu";
710

811
const MobileNav = () => {
12+
const [hidden, setHidden] = useState(false);
13+
14+
const { scrollY } = useScroll();
15+
16+
useMotionValueEvent(scrollY, "change", (latest: number) => {
17+
const prev = scrollY.getPrevious() || 0;
18+
19+
if (latest > prev && latest > 100) {
20+
setHidden(true);
21+
} else {
22+
setHidden(false);
23+
}
24+
});
925
return (
1026
<motion.header
11-
initial={{ translateY: 100 }}
12-
animate={{ translateY: 0 }}
27+
variants={{
28+
visible: { y: 0 },
29+
hidden: { y: 200 },
30+
}}
31+
initial={"hidden"}
32+
animate={hidden ? "hidden" : "visible"}
1333
transition={{ duration: 0.2 }}
14-
className="fixed z-[999] md:hidden px-4 bottom-10 inset-x-0 block"
34+
className="fixed z-50 md:hidden px-4 bottom-5 inset-x-0 block"
1535
>
16-
<div className="container mx-auto flex h-16 w-full max-w-[1024px] items-center justify-between rounded-full border-[1px] border-white/25 bg-white/25 px-8 backdrop-blur-md dark:border-[#5E5E5E]/20 dark:bg-[#18181D]/30">
36+
<div className="container mx-auto flex h-16 w-full max-w-lg items-center justify-between rounded-full border-[1px] border-white/25 bg-white/25 px-8 backdrop-blur-md dark:border-[#5E5E5E]/20 dark:bg-[#18181D]/30">
1737
<div className="flex items-center flex-1">
1838
<Link aria-label="Vignesh Gupta Logo" href="/">
1939
<Logo width={50} height={50} />
@@ -39,8 +59,11 @@ const MobileNav = () => {
3959
))}
4060
</ul>
4161
</nav>
62+
63+
<MobileSocialMenu />
64+
4265
</div>
43-
<div className="hidden items-center gap-4 sm:flex">
66+
{/* <div className="hidden items-center gap-4 sm:flex">
4467
<div className="flex gap-6 text-onyx/70 dark:text-white/70">
4568
{socials.map((social) => (
4669
<Link
@@ -54,7 +77,7 @@ const MobileNav = () => {
5477
</Link>
5578
))}
5679
</div>
57-
</div>
80+
</div> */}
5881
</div>
5982
</motion.header>
6083
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"use client";
2+
3+
import { useState } from "react";
4+
import { Button } from "../ui/button";
5+
import { socials } from "@/lib/constants";
6+
import { MenuIcon } from "lucide-react";
7+
import Link from "next/link";
8+
import { ThemeSwitch } from "../theme/theme-switch";
9+
import { AnimatePresence } from "motion/react";
10+
import * as motion from "motion/react-client";
11+
12+
const MobileSocialMenu = () => {
13+
const [dropdownOpen, setDropdownOpen] = useState(false);
14+
15+
return (
16+
<div className="relative">
17+
<Button
18+
variant="ghost"
19+
className="size-6 [&_svg]:size-5 hover:bg-transparent"
20+
size="icon"
21+
onClick={() => setDropdownOpen((prev) => !prev)}
22+
>
23+
<MenuIcon />
24+
</Button>
25+
<AnimatePresence initial={false}>
26+
{dropdownOpen && (
27+
<motion.div
28+
className="absolute bottom-10 -right-5 mb-2 rounded-lg border-[1px] border-white/25 bg-white/50 px-8 backdrop-blur-md dark:border-[#5E5E5E]/20 dark:bg-[#18181D]/50 py-3"
29+
30+
variants={{
31+
visible: { opacity: 1, y: 0, scale: 1 },
32+
hidden: { opacity: 0, y: 10, scale: 0.95 },
33+
}}
34+
initial={"hidden"}
35+
animate={"visible"}
36+
exit={"hidden"}
37+
transition={{ duration: 0.2 }}
38+
>
39+
<div className="flex gap-4">
40+
{socials.map((social) => (
41+
<Link
42+
key={`mobile-social-${social.name}`}
43+
className="group transition hover:text-onyx dark:hover:text-white"
44+
target="_blank"
45+
aria-label={social.name}
46+
href={social.href}
47+
onClick={() => setDropdownOpen(false)}
48+
>
49+
<social.icon className="size-6" />
50+
</Link>
51+
))}
52+
53+
{/* Create a vertical separator */}
54+
<div className="w-[1px] h-6 bg-white/25 dark:bg-[#5E5E5E]/20" />
55+
<ThemeSwitch onClick={()=> setDropdownOpen(false)} />
56+
</div>
57+
</motion.div>
58+
)}
59+
</AnimatePresence>
60+
</div>
61+
);
62+
};
63+
64+
export default MobileSocialMenu;

src/components/contact/contact-form.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { zodResolver } from "@hookform/resolvers/zod";
22
import { useForm } from "react-hook-form";
33
import { z } from "zod";
4-
import { motion } from "framer-motion";
4+
import * as motion from "motion/react-client";
55

66
import { Button } from "@/components/ui/button";
77
import {

src/components/hero/hero-section.tsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { calculateYearsFromNov2021 } from "@/lib/utils";
55

66
const HeroSection = () => {
77
return (
8-
<section className="relative grid grid-cols-1 py-32 lg:grid-cols-3 group">
8+
<section className="relative grid grid-cols-1 py-12 sm:py-20 md:py-32 lg:grid-cols-3 group">
99
<div className="flex flex-col text-center gap-y-10 lg:text-left lg:col-span-2 ">
1010
<div>
1111
<span className="text-lg font-semibold md:text-xl lg:text-2xl text-muted">
@@ -28,12 +28,14 @@ const HeroSection = () => {
2828
<span>
2929
I&apos;m a passionate learner who&apos;s always willing to learn and
3030
work across technologies and domains. I love to explore new
31-
technologies and leverage them to solve real-life problems.
31+
technologies and leverage them to solve real-world problems.
3232
</span>
3333
</div>
3434
<div className="flex flex-col items-center gap-3 md:flex-row ">
3535
<Link
36-
href={"/"}
36+
prefetch={false}
37+
target="_blank"
38+
href={"/resume.pdf"}
3739
className="cursor-pointer rounded-lg flex justify-center items-center bg-gradient min-h-[60px] px-8 py-4 primary-button hover:translate-y-[-1px] dark:text-muted text-white hover:text-white active:translate-y-[1px] font-medium transition duration-300 w-full lg:w-fit"
3840
>
3941
See my resume

src/components/project/project-card.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import { useTransform, useScroll, motion, MotionValue } from "framer-motion";
3+
import { useTransform, useScroll, motion, MotionValue } from "motion/react"
44
import { useRef } from "react";
55
import { MoveRightIcon } from "lucide-react";
66
import Image from "next/image";
@@ -62,6 +62,7 @@ const ProjectCard = ({
6262
alt="Project Name"
6363
width={60}
6464
height={60}
65+
className="rounded-full"
6566
/>
6667
) : null}
6768
<CardTitle className="my-5">{title}</CardTitle>

0 commit comments

Comments
 (0)