├── .eslintrc.json ├── src ├── app │ ├── globals.css │ ├── favicon.ico │ ├── project │ │ └── page.tsx │ ├── page.tsx │ ├── layout.tsx │ └── cv │ │ └── page.tsx ├── types │ ├── appbarType.ts │ ├── spotlightType.ts │ ├── dockType.ts │ ├── projectType.ts │ └── skillType.ts ├── stores │ ├── bootWords.ts │ ├── skillStore.ts │ ├── projectStore.ts │ └── dockStore.ts ├── lib │ └── utils.ts ├── components │ ├── elements │ │ ├── skill │ │ │ ├── Circle.tsx │ │ │ ├── cards │ │ │ │ ├── CardType2.tsx │ │ │ │ └── CardType1.tsx │ │ │ ├── RevealAnimation.tsx │ │ │ └── AnimatedBeam.tsx │ │ ├── project │ │ │ ├── Project.tsx │ │ │ └── Modal.tsx │ │ ├── hero │ │ │ ├── Spotlight.tsx │ │ │ └── CliCommand.tsx │ │ ├── bootscreen │ │ │ └── BootElement.tsx │ │ └── dock │ │ │ └── DockElement.tsx │ └── ui │ │ ├── Dock.tsx │ │ ├── Skills.tsx │ │ ├── Projects.tsx │ │ ├── Hero.tsx │ │ └── AppBar.tsx └── screens │ ├── BootScreen.tsx │ └── Landing.tsx ├── public ├── snapshot.png ├── projects │ ├── cma.png │ ├── oms.png │ ├── blog-web.png │ ├── readhubmd.png │ ├── typing-test.png │ └── alfa-leetcode-api.png ├── alfaarghyaAvtar.png ├── svg │ ├── front-html.svg │ ├── front-css.svg │ ├── front-tailwind.svg │ ├── back-mongodb.svg │ ├── back-express.svg │ ├── tools-git.svg │ ├── back-front-typescript.svg │ ├── tools-openai.svg │ ├── tools-vs-code.svg │ ├── back-front-nextjs.svg │ ├── tools-docker.svg │ ├── tools.svg │ ├── back-node-js.svg │ ├── front-react.svg │ ├── front.svg │ ├── back.svg │ ├── tools-linux.svg │ ├── complete-site.svg │ ├── tools-postman.svg │ ├── back-postgresql.svg │ └── tools-excalidraw.svg └── dockSvg │ ├── terminal-dock.svg │ ├── email-circle-fill-svgrepo-com.svg │ ├── dock-menu.svg │ ├── linkedin-dock.svg │ ├── mail-5-svgrepo-com.svg │ ├── cv-dock.svg │ ├── code-dock.svg │ ├── leetcode-dock.svg │ ├── twitter-dock.svg │ ├── instagram-dock.svg │ └── github-dock.svg ├── next.config.mjs ├── postcss.config.mjs ├── .gitignore ├── README.md ├── tsconfig.json ├── package.json └── tailwind.config.ts /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /public/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfaarghya/alfaarghya.dev/main/public/snapshot.png -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfaarghya/alfaarghya.dev/main/src/app/favicon.ico -------------------------------------------------------------------------------- /public/projects/cma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfaarghya/alfaarghya.dev/main/public/projects/cma.png -------------------------------------------------------------------------------- /public/projects/oms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfaarghya/alfaarghya.dev/main/public/projects/oms.png -------------------------------------------------------------------------------- /public/alfaarghyaAvtar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfaarghya/alfaarghya.dev/main/public/alfaarghyaAvtar.png -------------------------------------------------------------------------------- /public/projects/blog-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfaarghya/alfaarghya.dev/main/public/projects/blog-web.png -------------------------------------------------------------------------------- /src/types/appbarType.ts: -------------------------------------------------------------------------------- 1 | export type AppBarProps = { 2 | isRoot?: boolean; // Optional prop, defaults to false 3 | }; -------------------------------------------------------------------------------- /src/types/spotlightType.ts: -------------------------------------------------------------------------------- 1 | export type spotlightType = { 2 | className?: string; 3 | fill?: string; 4 | }; 5 | -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /public/projects/readhubmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfaarghya/alfaarghya.dev/main/public/projects/readhubmd.png -------------------------------------------------------------------------------- /public/projects/typing-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfaarghya/alfaarghya.dev/main/public/projects/typing-test.png -------------------------------------------------------------------------------- /public/projects/alfa-leetcode-api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alfaarghya/alfaarghya.dev/main/public/projects/alfa-leetcode-api.png -------------------------------------------------------------------------------- /src/types/dockType.ts: -------------------------------------------------------------------------------- 1 | export type dockType = { 2 | title: string; 3 | icon: string; 4 | href: string; 5 | newTab: boolean; 6 | }; 7 | -------------------------------------------------------------------------------- /src/app/project/page.tsx: -------------------------------------------------------------------------------- 1 | import Projects from "@/components/ui/Projects" 2 | 3 | const page = () => { 4 | return 5 | }; 6 | 7 | export default page; -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /src/stores/bootWords.ts: -------------------------------------------------------------------------------- 1 | export const bootWords = [ 2 | "Hello", 3 | "こんにちは", 4 | "Bonjour", 5 | "안녕하세요", 6 | "Hallo", 7 | "नमस्ते", 8 | "Ciao", 9 | "নমস্কার", 10 | ]; 11 | -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { ClassValue, clsx } from "clsx"; 2 | import { twMerge } from "tailwind-merge"; 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | -------------------------------------------------------------------------------- /src/app/page.tsx: -------------------------------------------------------------------------------- 1 | import BootScreen from "@/screens/BootScreen"; 2 | import Landing from "@/screens/Landing"; 3 | import React from "react"; 4 | 5 | const Home = () => { 6 | return ( 7 | <> 8 | 9 |
10 | 11 |
12 | 13 | ); 14 | }; 15 | 16 | export default Home; 17 | -------------------------------------------------------------------------------- /public/svg/front-html.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /public/svg/front-css.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /public/svg/front-tailwind.svg: -------------------------------------------------------------------------------- 1 | 2 | file_type_tailwind -------------------------------------------------------------------------------- /src/types/projectType.ts: -------------------------------------------------------------------------------- 1 | export type modal = { 2 | active: boolean; 3 | index: number; 4 | }; 5 | 6 | export interface ProjectProps { 7 | index: number; 8 | title: string; 9 | description: string; 10 | link: string; 11 | setModal: ({}: modal) => void; 12 | } 13 | 14 | export interface modalProps { 15 | modal: modal; 16 | projects: project[]; 17 | } 18 | 19 | export interface project { 20 | title: string; 21 | description: string; 22 | src: string; 23 | link: string; 24 | color: string; 25 | } 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | 38 | -------------------------------------------------------------------------------- /src/components/elements/skill/Circle.tsx: -------------------------------------------------------------------------------- 1 | import { forwardRef } from "react"; 2 | import { cn } from "@/lib/utils"; 3 | 4 | export const Circle = forwardRef< 5 | HTMLDivElement, 6 | { className?: string; children?: React.ReactNode } 7 | >(({ className, children }, ref) => { 8 | return ( 9 |
16 | {children} 17 |
18 | ); 19 | }); 20 | 21 | Circle.displayName = "Circle"; 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | # alfaarghya.dev 5 | 6 | ### Shape Ideas with Technology 7 | 8 | 🚀 A personal portfolio created by Arghya Das (alfaarghya), a full-stack software developer, focused on crafting meaningful web applications with creativity and technical expertise, turning intricate ideas into real-world digital solutions, one line of code at a time 9 | 10 |
11 | 12 | ## A Glance of My Portfolio 13 | 14 | 15 | 16 | # 17 | 18 |
19 | Website is Complete, But I Will add more things over the time, so stay tuned :) 20 |
21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["dom", "dom.iterable", "esnext"], 4 | "allowJs": true, 5 | "skipLibCheck": true, 6 | "strict": true, 7 | "noEmit": true, 8 | "esModuleInterop": true, 9 | "module": "esnext", 10 | "moduleResolution": "bundler", 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "jsx": "preserve", 14 | "incremental": true, 15 | "plugins": [ 16 | { 17 | "name": "next" 18 | } 19 | ], 20 | "paths": { 21 | "@/*": ["./src/*"] 22 | } 23 | }, 24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 25 | "exclude": ["node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /src/screens/BootScreen.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import Preloader from "@/components/elements/bootscreen/BootElement"; 4 | import { AnimatePresence } from "framer-motion"; 5 | import React, { useEffect, useState } from "react"; 6 | 7 | const BootScreen = () => { 8 | const [isLoading, setIsLoading] = useState(true); 9 | useEffect(() => { 10 | (async () => { 11 | setTimeout(() => { 12 | setIsLoading(false); 13 | document.body.style.cursor = "default"; 14 | window.scrollTo(0, 0); 15 | }, 2000); 16 | })(); 17 | }, []); 18 | return ( 19 | {isLoading && } 20 | ); 21 | }; 22 | 23 | export default BootScreen; 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alfaarghya.dev", 3 | "version": "0.0.0", 4 | "author": "alfaarghya", 5 | "private": true, 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "start": "next start", 10 | "lint": "next lint" 11 | }, 12 | "dependencies": { 13 | "clsx": "^2.1.1", 14 | "framer-motion": "^11.9.0", 15 | "gsap": "^3.12.5", 16 | "next": "^14.2.13", 17 | "react": "^18", 18 | "react-dom": "^18", 19 | "tailwind-merge": "^2.5.2" 20 | }, 21 | "devDependencies": { 22 | "@types/node": "^20", 23 | "@types/react": "^18", 24 | "@types/react-dom": "^18", 25 | "eslint": "^8", 26 | "eslint-config-next": "14.2.7", 27 | "postcss": "^8", 28 | "tailwindcss": "^3.4.1", 29 | "typescript": "^5" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/screens/Landing.tsx: -------------------------------------------------------------------------------- 1 | import AppBar from "@/components/ui/AppBar"; 2 | import Dock from "@/components/ui/Dock"; 3 | import Hero from "@/components/ui/Hero"; 4 | import Projects from "@/components/ui/Projects"; 5 | import Skills from "@/components/ui/Skills"; 6 | import React from "react"; 7 | 8 | const Landing = () => { 9 | return ( 10 |
11 | 12 | 13 | 14 | 15 |
16 |

17 | Website is Complete, But I Will add more things over the time, so stay 18 | tuned :) 19 |

20 |
21 | 22 |
23 | ); 24 | }; 25 | 26 | export default Landing; 27 | -------------------------------------------------------------------------------- /public/dockSvg/terminal-dock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/components/ui/Dock.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import React from "react"; 3 | import DockElement from "@/components/elements/dock/DockElement"; 4 | import { motion } from "framer-motion"; 5 | import { dockItems } from "@/stores/dockStore"; 6 | 7 | const Dock = () => { 8 | return ( 9 | 21 | 26 | 27 | ); 28 | }; 29 | 30 | export default Dock; 31 | -------------------------------------------------------------------------------- /public/dockSvg/email-circle-fill-svgrepo-com.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/elements/skill/cards/CardType2.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Circle } from "../Circle"; 3 | import Image from "next/image"; 4 | 5 | const CardType2 = () => { 6 | return ( 7 |
8 |
9 |
10 | complete-site 16 |
17 |

Complete Site

18 |
19 |
20 | ); 21 | }; 22 | 23 | export default CardType2; 24 | -------------------------------------------------------------------------------- /src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Syne } from "next/font/google"; 3 | import "./globals.css"; 4 | 5 | const syne = Syne({ 6 | subsets: ["latin"], 7 | weight: ["400", "500", "600", "700", "800"], 8 | }); 9 | 10 | export const metadata: Metadata = { 11 | title: "alfaarghya.dev - Shape Ideas with Technology", 12 | description: 13 | "A personal portfolio created by Arghya Das (alfaarghya), a full-stack software developer, focused on crafting meaningful web applications with creativity and technical expertise, turning intricate ideas into real-world digital solutions, one line of code at a time", 14 | }; 15 | 16 | export default function RootLayout({ 17 | children, 18 | }: Readonly<{ 19 | children: React.ReactNode; 20 | }>) { 21 | return ( 22 | 23 | 24 | {children} 25 | 26 | 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /src/types/skillType.ts: -------------------------------------------------------------------------------- 1 | import { ReactNode, RefObject } from "react"; 2 | 3 | export type card1Type = { 4 | title: string; 5 | icon: string; 6 | }; 7 | 8 | export interface CardRevealProps { 9 | children: ReactNode; // Accept children instead of cards 10 | className?: string; 11 | } 12 | 13 | export interface CardProps { 14 | children: ReactNode; 15 | progress: any; 16 | range: [number, number]; 17 | index: number; 18 | } 19 | 20 | export interface AnimatedBeamProps { 21 | className?: string; 22 | containerRef: RefObject; // Container ref 23 | fromRef: RefObject; 24 | toRef: RefObject; 25 | curvature?: number; 26 | reverse?: boolean; 27 | pathColor?: string; 28 | pathWidth?: number; 29 | pathOpacity?: number; 30 | gradientStartColor?: string; 31 | gradientStopColor?: string; 32 | delay?: number; 33 | duration?: number; 34 | startXOffset?: number; 35 | startYOffset?: number; 36 | endXOffset?: number; 37 | endYOffset?: number; 38 | } 39 | -------------------------------------------------------------------------------- /public/dockSvg/dock-menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/dockSvg/linkedin-dock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/svg/back-mongodb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/dockSvg/mail-5-svgrepo-com.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/elements/project/Project.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import { ProjectProps } from "@/types/projectType"; 3 | 4 | const Project = ({ 5 | index, 6 | title, 7 | description, 8 | setModal, 9 | link, 10 | }: ProjectProps) => { 11 | return ( 12 |
setModal({ active: true, index })} 15 | onMouseLeave={() => setModal({ active: false, index })} 16 | > 17 | 18 |
19 |

20 | {title} 21 |

22 |

23 | {description} 24 |

25 |
26 | 27 |
28 | ); 29 | }; 30 | 31 | export default Project; 32 | -------------------------------------------------------------------------------- /public/dockSvg/cv-dock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/ui/Skills.tsx: -------------------------------------------------------------------------------- 1 | import { backendSkills, frontendSkills, toolsSkill } from "@/stores/skillStore"; 2 | import RevealAnimation from "../elements/skill/RevealAnimation"; 3 | import CardType1 from "../elements/skill/cards/CardType1"; 4 | import CardType2 from "../elements/skill/cards/CardType2"; 5 | 6 | const Skills = () => { 7 | return ( 8 |
9 |
10 | 11 |
12 | 13 |
14 |
15 | 16 |
17 |
18 | 19 |
20 |
21 | 22 |
23 |
24 |
25 |
26 | ); 27 | }; 28 | 29 | export default Skills; 30 | -------------------------------------------------------------------------------- /public/svg/back-express.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /public/dockSvg/code-dock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/dockSvg/leetcode-dock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/components/ui/Projects.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useState } from "react"; 4 | import Modal from "../elements/project/Modal"; 5 | import Project from "../elements/project/Project"; 6 | import { modal } from "@/types/projectType"; 7 | import { projects } from "@/stores/projectStore"; 8 | 9 | const Projects = () => { 10 | const [modal, setModal] = useState({ active: false, index: 0 }); 11 | return ( 12 |
13 |
14 |
15 | Recent 16 | Works 17 |
18 | 19 | {projects.map((project, index) => { 20 | return ( 21 | 29 | ); 30 | })} 31 |
32 | 33 |
34 | ); 35 | }; 36 | 37 | export default Projects; 38 | -------------------------------------------------------------------------------- /tailwind.config.ts: -------------------------------------------------------------------------------- 1 | const { 2 | default: flattenColorPalette, 3 | } = require("tailwindcss/lib/util/flattenColorPalette"); 4 | 5 | /** @type {import('tailwindcss').Config} */ 6 | module.exports = { 7 | content: [ 8 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", 9 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}", 10 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}", 11 | 12 | // Or if using `src` directory: 13 | "./src/**/*.{js,ts,jsx,tsx,mdx}", 14 | ], 15 | darkMode: "class", 16 | theme: { 17 | extend: { 18 | animation: { 19 | spotlight: "spotlight 2s ease 4.5s 1 forwards", 20 | }, 21 | keyframes: { 22 | spotlight: { 23 | "0%": { 24 | opacity: 0, 25 | transform: "translate(-72%, -62%) scale(0.5)", 26 | }, 27 | "100%": { 28 | opacity: 1, 29 | transform: "translate(-50%,-40%) scale(1)", 30 | }, 31 | }, 32 | }, 33 | }, 34 | }, 35 | plugins: [addVariablesForColors], 36 | }; 37 | 38 | // This plugin adds each Tailwind color as a global CSS variable, e.g. var(--gray-200). 39 | function addVariablesForColors({ addBase, theme }: any) { 40 | let allColors = flattenColorPalette(theme("colors")); 41 | let newVars = Object.fromEntries( 42 | Object.entries(allColors).map(([key, val]) => [`--${key}`, val]) 43 | ); 44 | 45 | addBase({ 46 | ":root": newVars, 47 | }); 48 | } 49 | -------------------------------------------------------------------------------- /src/app/cv/page.tsx: -------------------------------------------------------------------------------- 1 | // import { redirect } from 'next/navigation'; 2 | 3 | // const page = () => { 4 | // redirect('https://drive.google.com/file/d/1KxSHR2BzPfq-38XHw_q3gE0FpvBYDAp8/view'); 5 | // }; 6 | 7 | // export default page; 8 | 9 | // app/cv/page.tsx 10 | 'use client'; 11 | 12 | import { useEffect } from 'react'; 13 | import { useRouter } from 'next/navigation'; 14 | import AppBar from '@/components/ui/AppBar'; 15 | 16 | export default function CVPage() { 17 | const router = useRouter(); 18 | 19 | useEffect(() => { 20 | const timeout = setTimeout(() => { 21 | router.push('https://drive.google.com/file/d/1KxSHR2BzPfq-38XHw_q3gE0FpvBYDAp8/view'); 22 | }, 1000); // 1 seconds delay before redirect 23 | 24 | return () => clearTimeout(timeout); 25 | }, [router]); 26 | 27 | return ( 28 | <> 29 | 30 |
31 |
32 |
33 | Redirecting to Arghya's CV... 34 |
35 |
36 | If it doesn’t redirect, click here. 37 |
38 |
39 |
40 | 41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /src/stores/skillStore.ts: -------------------------------------------------------------------------------- 1 | import { card1Type } from "@/types/skillType"; 2 | 3 | export const toolsSkill: card1Type[] = [ 4 | { title: "Linux", icon: "/svg/tools-linux.svg" }, 5 | { title: "Git/GitHub", icon: "/svg/tools-git.svg" }, 6 | { title: "VS Code", icon: "/svg/tools-vs-code.svg" }, 7 | { title: "Tools", icon: "/svg/tools.svg" }, 8 | { title: "Postman", icon: "/svg/tools-postman.svg" }, 9 | { title: "Docker", icon: "/svg/tools-docker.svg" }, 10 | { title: "Excalidraw", icon: "/svg/tools-excalidraw.svg" }, 11 | ]; 12 | export const backendSkills: card1Type[] = [ 13 | { title: "Node.js", icon: "/svg/back-node-js.svg" }, 14 | { title: "Express.js", icon: "/svg/back-express.svg" }, 15 | { title: "TS", icon: "/svg/back-front-typescript.svg" }, 16 | { title: "Backend", icon: "/svg/back.svg" }, 17 | { title: "Next.js", icon: "/svg/back-front-nextjs.svg" }, 18 | { title: "PSQL", icon: "/svg/back-postgresql.svg" }, 19 | { title: "MongoDB", icon: "/svg/back-mongodb.svg" }, 20 | ]; 21 | export const frontendSkills: card1Type[] = [ 22 | { title: "HTML", icon: "/svg/front-html.svg" }, 23 | { title: "React", icon: "/svg/front-react.svg" }, 24 | { title: "TS", icon: "/svg/back-front-typescript.svg" }, 25 | { title: "Frontend", icon: "/svg/front.svg" }, 26 | { title: "Next.js", icon: "/svg/back-front-nextjs.svg" }, 27 | { title: "CSS", icon: "/svg/front-css.svg" }, 28 | { title: "tailwind", icon: "/svg/front-tailwind.svg" }, 29 | ]; 30 | -------------------------------------------------------------------------------- /public/svg/tools-git.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/stores/projectStore.ts: -------------------------------------------------------------------------------- 1 | import { project } from "@/types/projectType"; 2 | 3 | export const projects: project[] = [ 4 | { 5 | title: "alfa-leetcode-api", 6 | description: ` A custom LeetCode api to get User info, Problem, Contest & many more`, 7 | src: "/projects/alfa-leetcode-api.png", 8 | color: "#302F30", 9 | link: "https://github.com/alfaarghya/alfa-leetcode-api", 10 | }, 11 | { 12 | title: "CMA", 13 | description: `Real-time chat application to chat with groups and chat with one person`, 14 | src: "/projects/cma.png", 15 | color: "#9CA3AF", 16 | link: "https://github.com/alfaarghya/cma", 17 | }, 18 | { 19 | title: "OMS", 20 | description: `OMS is end-to-end order managment solution for Merchant & Customer. From Listing the product to deliver the order, OMS handles it all.`, 21 | src: "/projects/oms.png", 22 | color: "#50013A", 23 | link: "https://github.com/alfaarghya/oms", 24 | }, 25 | { 26 | title: "blog-web", 27 | description: "A simple blogging application to perform CURD operation", 28 | src: "/projects/blog-web.png", 29 | color: "#9CA3AF", 30 | link: "https://github.com/alfaarghya/blog-web", 31 | }, 32 | { 33 | title: "ReadHub.md", 34 | description: "Generate your own GitHub Profile README.md easily ", 35 | src: "/projects/readhubmd.png", 36 | color: "#D6EAFF", 37 | link: "https://readhubmd.netlify.app/", 38 | }, 39 | { 40 | title: "typing-test", 41 | description: "Improve your typing speed", 42 | src: "/projects/typing-test.png", 43 | color: "#808080", 44 | link: "https://alfa-typing-test.netlify.app/", 45 | }, 46 | ]; 47 | -------------------------------------------------------------------------------- /src/stores/dockStore.ts: -------------------------------------------------------------------------------- 1 | import { dockType } from "@/types/dockType"; 2 | 3 | export const dockItems: dockType[] = [ 4 | { 5 | title: "alfaarghya", 6 | icon: "/alfaarghyaAvtar.svg", 7 | href: "#", 8 | newTab: false, 9 | }, 10 | { 11 | title: "Mail", 12 | icon: "/dockSvg/email-circle-fill-svgrepo-com.svg", 13 | href: "mailto:arghya.coding@gmail.com", 14 | newTab: true, 15 | }, 16 | // { 17 | // title: "Skills", 18 | // icon: "/dockSvg/terminal-dock.svg", 19 | // href: "#", 20 | // }, 21 | // { 22 | // title: "Projects", 23 | // icon: "/dockSvg/code-dock.svg", 24 | // href: "#", 25 | // }, 26 | { 27 | title: "GitHub", 28 | icon: "/dockSvg/github-dock.svg", 29 | href: "https://github.com/alfaarghya", 30 | newTab: true, 31 | }, 32 | 33 | { 34 | title: "LinkedIN", 35 | icon: "/dockSvg/linkedin-dock.svg", 36 | href: "https://www.linkedin.com/in/alfaarghya/", 37 | newTab: true, 38 | }, 39 | { 40 | title: "X", 41 | icon: "/dockSvg/twitter-dock.svg", 42 | href: "https://x.com/alfaarghya", 43 | newTab: true, 44 | }, 45 | { 46 | title: "Instagram", 47 | icon: "/dockSvg/instagram-dock.svg", 48 | href: "https://www.instagram.com/alfaarghya/", 49 | newTab: true, 50 | }, 51 | { 52 | title: "LeetCode", 53 | icon: "/dockSvg/leetcode-dock.svg", 54 | href: "https://leetcode.com/u/alfaarghya/", 55 | newTab: true, 56 | }, 57 | { 58 | title: "CV", 59 | icon: "/dockSvg/cv-dock.svg", 60 | href: "https://drive.google.com/file/d/1KxSHR2BzPfq-38XHw_q3gE0FpvBYDAp8/view?usp=drive_link", 61 | newTab: true, 62 | }, 63 | ]; 64 | -------------------------------------------------------------------------------- /src/components/elements/hero/Spotlight.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils"; 2 | import { spotlightType } from "@/types/spotlightType"; 3 | import React from "react"; 4 | 5 | const Spotlight = ({ className, fill }: spotlightType) => { 6 | return ( 7 | 16 | 17 | 26 | 27 | 28 | 37 | 38 | 44 | 48 | 49 | 50 | 51 | ); 52 | }; 53 | 54 | export default Spotlight; 55 | -------------------------------------------------------------------------------- /public/dockSvg/twitter-dock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/svg/back-front-typescript.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | file_type_typescript_official 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/components/ui/Hero.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import { motion } from "framer-motion"; 3 | import HeroSvg from "../elements/hero/HeroSvg"; 4 | import CliCommand from "../elements/hero/CliCommand"; 5 | import Spotlight from "../elements/hero/Spotlight"; 6 | 7 | const Hero = () => { 8 | return ( 9 |
10 | 15 | 16 | 28 |
29 | 30 | Hii, I'm 31 | 32 |

33 | 34 | Arghya Das 35 | {" "} 36 |

37 |
38 |

39 | FullStack Developer , Bringing Ideas to Life through Code and Design. 40 |

41 | 42 | 43 |
44 |
45 | ); 46 | }; 47 | 48 | export default Hero; 49 | -------------------------------------------------------------------------------- /public/svg/tools-openai.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | OpenAI icon -------------------------------------------------------------------------------- /src/components/ui/AppBar.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React, { useEffect, useState } from "react"; 4 | import Image from "next/image"; 5 | import Link from "next/link"; 6 | import { AppBarProps } from "@/types/appbarType"; 7 | 8 | const AppBar = ({ isRoot = false }: AppBarProps) => { 9 | const [isVisible, setIsVisible] = useState(!isRoot); 10 | 11 | useEffect(() => { 12 | if (isRoot) { 13 | const timer = setTimeout(() => { 14 | setIsVisible(true); // Trigger animation only on root 15 | }, 0); // Optional: can delay mount visibility here 16 | return () => clearTimeout(timer); 17 | } 18 | }, [isRoot]); 19 | return ( 20 |
21 |
25 | 29 | alfaarghya logo 36 | 37 | alfaarghya.dev 38 | 39 | 40 |
41 | 42 | 43 | 44 | open to work 45 |
46 |
47 |
48 | ); 49 | }; 50 | 51 | export default AppBar; 52 | -------------------------------------------------------------------------------- /public/svg/tools-vs-code.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/svg/back-front-nextjs.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/svg/tools-docker.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/components/elements/skill/RevealAnimation.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React, { FC, useRef } from "react"; 4 | import { motion, useScroll, useTransform } from "framer-motion"; 5 | import { cn } from "@/lib/utils"; 6 | import { CardProps, CardRevealProps } from "@/types/skillType"; 7 | 8 | const RevealAnimation: FC = ({ children, className }) => { 9 | const targetRef = useRef(null); 10 | 11 | const { scrollYProgress } = useScroll({ 12 | target: targetRef, 13 | }); 14 | 15 | const opacity = useTransform(scrollYProgress, [0, 0.2], [0, 1]); 16 | const scale = useTransform(scrollYProgress, [0, 0.2], [0.5, 1]); 17 | 18 | return ( 19 |
23 |
24 | {/* Animated Text Section */} 25 | 29 | My 30 | Skillsets 31 | 32 | 33 |
34 | {/* Relative container to position cards */} 35 | {React.Children.map(children, (child, i) => { 36 | const start = i * 0.3; // Adjust this value for more/less scroll space 37 | const end = start + 0.1; // This keeps a small overlap while scrolling 38 | 39 | return ( 40 | 46 | {child} 47 | 48 | ); 49 | })} 50 |
51 |
52 |
53 | ); 54 | }; 55 | 56 | // Card component handling individual card animation 57 | const Card: FC = ({ children, progress, range, index }) => { 58 | const opacity = useTransform(progress, range, [0, 1]); 59 | const translateY = useTransform(progress, range, [50, 0]); // Control stacking position 60 | const zIndex = index + 1; // Ensure each card has a higher z-index as it appears 61 | 62 | return ( 63 | 67 | {children} 68 | 69 | ); 70 | }; 71 | 72 | export default RevealAnimation; 73 | -------------------------------------------------------------------------------- /public/dockSvg/instagram-dock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/svg/tools.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/components/elements/bootscreen/BootElement.tsx: -------------------------------------------------------------------------------- 1 | import { bootWords } from "@/stores/bootWords"; 2 | import { motion } from "framer-motion"; 3 | import React, { useEffect, useState } from "react"; 4 | 5 | const BootElement = () => { 6 | const [index, setIndex] = useState(0); 7 | const [dimension, setDimension] = useState({ width: 0, height: 0 }); 8 | 9 | useEffect(() => { 10 | setDimension({ width: window.innerWidth, height: window.innerHeight }); 11 | }, []); 12 | 13 | useEffect(() => { 14 | if (index == bootWords.length - 1) return; 15 | setTimeout( 16 | () => { 17 | setIndex(index + 1); 18 | }, 19 | index == 0 ? 1000 : 150 20 | ); 21 | }, [index]); 22 | 23 | const initialPath = `M0 0 L${dimension.width} 0 L${dimension.width} ${ 24 | dimension.height 25 | } Q${dimension.width / 2} ${dimension.height + 300} 0 ${ 26 | dimension.height 27 | } L0 0`; 28 | const targetPath = `M0 0 L${dimension.width} 0 L${dimension.width} ${ 29 | dimension.height 30 | } Q${dimension.width / 2} ${dimension.height} 0 ${dimension.height} L0 0`; 31 | 32 | const curve = { 33 | initial: { 34 | d: initialPath, 35 | transition: { duration: 0.7, ease: [0.76, 0, 0.24, 1] }, 36 | }, 37 | exit: { 38 | d: targetPath, 39 | transition: { duration: 0.7, ease: [0.76, 0, 0.24, 1], delay: 0.3 }, 40 | }, 41 | }; 42 | 43 | return ( 44 | 58 | {dimension.width > 0 && ( 59 | <> 60 | 74 | {bootWords[index]} 75 | 76 | 77 | 83 | 84 | 85 | )} 86 | 87 | ); 88 | }; 89 | 90 | export default BootElement; 91 | -------------------------------------------------------------------------------- /public/dockSvg/github-dock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/svg/back-node-js.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/elements/hero/CliCommand.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { motion } from "framer-motion"; 4 | import React, { useState } from "react"; 5 | 6 | const CliCommand = () => { 7 | const [copied, setCopied] = useState(false); 8 | 9 | const handleCopy = () => { 10 | navigator.clipboard.writeText("npx alfaarghya").then(() => { 11 | setCopied(true); 12 | setTimeout(() => setCopied(false), 2000); // Reset after 2 seconds 13 | }); 14 | }; 15 | return ( 16 |
17 |
npx alfaarghya
18 | 90 |
91 | ); 92 | }; 93 | 94 | export default CliCommand; 95 | -------------------------------------------------------------------------------- /src/components/elements/project/Modal.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from "react"; 2 | import Image from "next/image"; 3 | import { motion } from "framer-motion"; 4 | import { gsap } from "gsap"; 5 | import Link from "next/link"; 6 | import { modalProps } from "@/types/projectType"; 7 | 8 | const scaleAnimation = { 9 | initial: { scale: 0, x: "-50%", y: "-50%" }, 10 | enter: { 11 | scale: 1, 12 | x: "-50%", 13 | y: "-50%", 14 | transition: { duration: 0.4, ease: [0.76, 0, 0.24, 1] }, 15 | }, 16 | closed: { 17 | scale: 0, 18 | x: "-50%", 19 | y: "-50%", 20 | transition: { duration: 0.4, ease: [0.32, 0, 0.67, 0] }, 21 | }, 22 | }; 23 | const Modal = ({ modal, projects }: modalProps) => { 24 | const { active, index } = modal; 25 | const modalContainer = useRef(null); 26 | const cursor = useRef(null); 27 | const cursorLabel = useRef(null); 28 | useEffect(() => { 29 | //Move Container 30 | let xMoveContainer = gsap.quickTo(modalContainer.current, "left", { 31 | duration: 0.8, 32 | ease: "power3", 33 | }); 34 | let yMoveContainer = gsap.quickTo(modalContainer.current, "top", { 35 | duration: 0.8, 36 | ease: "power3", 37 | }); 38 | //Move cursor 39 | let xMoveCursor = gsap.quickTo(cursor.current, "left", { 40 | duration: 0.5, 41 | ease: "power3", 42 | }); 43 | let yMoveCursor = gsap.quickTo(cursor.current, "top", { 44 | duration: 0.5, 45 | ease: "power3", 46 | }); 47 | //Move cursor label 48 | let xMoveCursorLabel = gsap.quickTo(cursorLabel.current, "left", { 49 | duration: 0.45, 50 | ease: "power3", 51 | }); 52 | let yMoveCursorLabel = gsap.quickTo(cursorLabel.current, "top", { 53 | duration: 0.45, 54 | ease: "power3", 55 | }); 56 | 57 | window.addEventListener("mousemove", (e) => { 58 | const { pageX, pageY } = e; 59 | xMoveContainer(pageX); 60 | yMoveContainer(pageY); 61 | xMoveCursor(pageX); 62 | yMoveCursor(pageY); 63 | xMoveCursorLabel(pageX); 64 | yMoveCursorLabel(pageY); 65 | }); 66 | }, []); 67 | 68 | return ( 69 | <> 70 | 77 |
81 | {projects.map((project, index) => { 82 | const { src, color, link } = project; 83 | return ( 84 |
89 | {/* @ts-ignore */} 90 | 91 | image 98 | 99 |
100 | ); 101 | })} 102 |
103 |
104 | 111 | 118 | View 119 | 120 | 121 | ); 122 | }; 123 | 124 | export default Modal; 125 | -------------------------------------------------------------------------------- /public/svg/front-react.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/svg/front.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/elements/skill/AnimatedBeam.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useEffect, useId, useState } from "react"; 4 | import { motion } from "framer-motion"; 5 | 6 | import { cn } from "@/lib/utils"; 7 | import { AnimatedBeamProps } from "@/types/skillType"; 8 | 9 | export const AnimatedBeam: React.FC = ({ 10 | className, 11 | containerRef, 12 | fromRef, 13 | toRef, 14 | curvature = 0, 15 | reverse = false, // Include the reverse prop 16 | duration = Math.random() * 3 + 4, 17 | delay = 0, 18 | pathColor = "gray", 19 | pathWidth = 2, 20 | pathOpacity = 0.2, 21 | gradientStartColor = "#ffaa40", 22 | gradientStopColor = "#9c40ff", 23 | startXOffset = 0, 24 | startYOffset = 0, 25 | endXOffset = 0, 26 | endYOffset = 0, 27 | }) => { 28 | const id = useId(); 29 | const [pathD, setPathD] = useState(""); 30 | const [svgDimensions, setSvgDimensions] = useState({ width: 0, height: 0 }); 31 | 32 | // Calculate the gradient coordinates based on the reverse prop 33 | const gradientCoordinates = reverse 34 | ? { 35 | x1: ["90%", "-10%"], 36 | x2: ["100%", "0%"], 37 | y1: ["0%", "0%"], 38 | y2: ["0%", "0%"], 39 | } 40 | : { 41 | x1: ["10%", "110%"], 42 | x2: ["0%", "100%"], 43 | y1: ["0%", "0%"], 44 | y2: ["0%", "0%"], 45 | }; 46 | 47 | useEffect(() => { 48 | const updatePath = () => { 49 | if (containerRef.current && fromRef.current && toRef.current) { 50 | const containerRect = containerRef.current.getBoundingClientRect(); 51 | const rectA = fromRef.current.getBoundingClientRect(); 52 | const rectB = toRef.current.getBoundingClientRect(); 53 | 54 | const svgWidth = containerRect.width; 55 | const svgHeight = containerRect.height; 56 | setSvgDimensions({ width: svgWidth, height: svgHeight }); 57 | 58 | const startX = 59 | rectA.left - containerRect.left + rectA.width / 2 + startXOffset; 60 | const startY = 61 | rectA.top - containerRect.top + rectA.height / 2 + startYOffset; 62 | const endX = 63 | rectB.left - containerRect.left + rectB.width / 2 + endXOffset; 64 | const endY = 65 | rectB.top - containerRect.top + rectB.height / 2 + endYOffset; 66 | 67 | const controlY = startY - curvature; 68 | const d = `M ${startX},${startY} Q ${ 69 | (startX + endX) / 2 70 | },${controlY} ${endX},${endY}`; 71 | setPathD(d); 72 | } 73 | }; 74 | 75 | // Initialize ResizeObserver 76 | const resizeObserver = new ResizeObserver((entries) => { 77 | // For all entries, recalculate the path 78 | for (let entry of entries) { 79 | updatePath(); 80 | } 81 | }); 82 | 83 | // Observe the container element 84 | if (containerRef.current) { 85 | resizeObserver.observe(containerRef.current); 86 | } 87 | 88 | // Call the updatePath initially to set the initial path 89 | updatePath(); 90 | 91 | // Clean up the observer on component unmount 92 | return () => { 93 | resizeObserver.disconnect(); 94 | }; 95 | }, [ 96 | containerRef, 97 | fromRef, 98 | toRef, 99 | curvature, 100 | startXOffset, 101 | startYOffset, 102 | endXOffset, 103 | endYOffset, 104 | ]); 105 | 106 | return ( 107 | 118 | 125 | 132 | 133 | 157 | 158 | 159 | 160 | 165 | 166 | 167 | 168 | ); 169 | }; 170 | -------------------------------------------------------------------------------- /public/svg/back.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/svg/tools-linux.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/components/elements/skill/cards/CardType1.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React, { useRef } from "react"; 4 | import { AnimatedBeam } from "../AnimatedBeam"; 5 | import { Circle } from "../Circle"; 6 | import Image from "next/image"; 7 | import { card1Type } from "@/types/skillType"; 8 | 9 | const CardType1 = ({ items }: { items: card1Type[] }) => { 10 | const containerRef = useRef(null); 11 | const div1Ref = useRef(null); 12 | const div2Ref = useRef(null); 13 | const div3Ref = useRef(null); 14 | const div4Ref = useRef(null); 15 | const div5Ref = useRef(null); 16 | const div6Ref = useRef(null); 17 | const div7Ref = useRef(null); 18 | 19 | return ( 20 |
24 |
25 |
26 |
27 | 28 | {items[0].title} 34 | 35 |

36 | {items[0].title} 37 |

38 |
39 |
40 | 41 | {items[1].title} 47 | 48 |

49 | {items[1].title} 50 |

51 |
52 |
53 |
54 |
55 | 56 | {items[2].title} 62 | 63 |

64 | {items[2].title} 65 |

66 |
67 |
68 | 69 | {items[3].title} 75 | 76 |

77 | {items[3].title} 78 |

79 |
80 |
81 | 82 | {items[4].title} 88 | 89 |

90 | {items[4].title} 91 |

92 |
93 |
94 |
95 |
96 | 97 | {items[5].title} 103 | 104 |

105 | {items[5].title} 106 |

107 |
108 |
109 | 110 | {items[6].title} 116 | 117 |

118 | {items[6].title} 119 |

120 |
121 |
122 |
123 | 124 | 131 | 136 | 143 | 151 | 157 | 165 |
166 | ); 167 | }; 168 | 169 | export default CardType1; 170 | -------------------------------------------------------------------------------- /src/components/elements/dock/DockElement.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React from "react"; 4 | import { cn } from "@/lib/utils"; 5 | import { 6 | AnimatePresence, 7 | MotionValue, 8 | motion, 9 | useMotionValue, 10 | useSpring, 11 | useTransform, 12 | } from "framer-motion"; 13 | import Link from "next/link"; 14 | import Image from "next/image"; 15 | import { useRef, useState } from "react"; 16 | import { dockType } from "@/types/dockType"; 17 | 18 | const DockElement = ({ 19 | items, 20 | desktopClassName, 21 | mobileClassName, 22 | }: { 23 | items: dockType[]; 24 | desktopClassName?: string; 25 | mobileClassName?: string; 26 | }) => { 27 | return ( 28 | <> 29 | 30 | 31 | 32 | ); 33 | }; 34 | 35 | const DockMobile = ({ 36 | items, 37 | className, 38 | }: { 39 | items: dockType[]; 40 | className?: string; 41 | }) => { 42 | const [open, setOpen] = useState(false); 43 | return ( 44 |
45 | 46 | {open && ( 47 | 51 | {items.map((item, idx) => ( 52 | 68 | 75 |
76 | {item.title} 82 |
83 | 84 |
85 | ))} 86 |
87 | )} 88 |
89 | 95 |
96 | ); 97 | }; 98 | 99 | const DockDesktop = ({ 100 | items, 101 | className, 102 | }: { 103 | items: dockType[]; 104 | className?: string; 105 | }) => { 106 | let mouseX = useMotionValue(Infinity); 107 | return ( 108 | mouseX.set(e.pageX)} 110 | onMouseLeave={() => mouseX.set(Infinity)} 111 | className={cn( 112 | "mx-auto hidden md:flex h-16 gap-4 items-end rounded-2xl bg-neutral-500/10 backdrop-blur-sm px-4 pb-3", 113 | className 114 | )} 115 | > 116 | {items.map((item) => ( 117 | 118 | ))} 119 | 120 | ); 121 | }; 122 | 123 | function IconContainer({ 124 | mouseX, 125 | title, 126 | icon, 127 | href, 128 | newTab, 129 | }: { 130 | mouseX: MotionValue; 131 | title: string; 132 | icon: string; 133 | href: string; 134 | newTab: boolean; 135 | }) { 136 | let ref = useRef(null); 137 | 138 | let distance = useTransform(mouseX, (val) => { 139 | let bounds = ref.current?.getBoundingClientRect() ?? { x: 0, width: 0 }; 140 | 141 | return val - bounds.x - bounds.width / 2; 142 | }); 143 | 144 | let widthTransform = useTransform(distance, [-150, 0, 150], [40, 80, 40]); 145 | let heightTransform = useTransform(distance, [-150, 0, 150], [40, 80, 40]); 146 | 147 | let widthTransformIcon = useTransform(distance, [-150, 0, 150], [20, 40, 20]); 148 | let heightTransformIcon = useTransform( 149 | distance, 150 | [-150, 0, 150], 151 | [20, 40, 20] 152 | ); 153 | 154 | let width = useSpring(widthTransform, { 155 | mass: 0.1, 156 | stiffness: 150, 157 | damping: 12, 158 | }); 159 | let height = useSpring(heightTransform, { 160 | mass: 0.1, 161 | stiffness: 150, 162 | damping: 12, 163 | }); 164 | 165 | let widthIcon = useSpring(widthTransformIcon, { 166 | mass: 0.1, 167 | stiffness: 150, 168 | damping: 12, 169 | }); 170 | let heightIcon = useSpring(heightTransformIcon, { 171 | mass: 0.1, 172 | stiffness: 150, 173 | damping: 12, 174 | }); 175 | 176 | const [hovered, setHovered] = useState(false); 177 | 178 | return ( 179 | 184 | setHovered(true)} 188 | onMouseLeave={() => setHovered(false)} 189 | className="aspect-square rounded-2xl bg-neutral-800 flex items-center justify-center relative" 190 | > 191 | 192 | {hovered && ( 193 | 199 | {title} 200 | 201 | )} 202 | 203 | 207 | {title} 208 | 209 | 210 | 211 | ); 212 | } 213 | 214 | export default DockElement; 215 | -------------------------------------------------------------------------------- /public/svg/complete-site.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /public/svg/tools-postman.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/svg/back-postgresql.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/svg/tools-excalidraw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | --------------------------------------------------------------------------------