├── .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 |
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 |
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 |
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 |
19 | {copied ? (
20 |
26 |
27 |
32 |
33 | {" "}
34 | {" "}
41 | {" "}
48 | {" "}
55 |
56 |
57 | ) : (
58 |
64 |
65 |
70 |
71 | {" "}
72 | {" "}
79 | {" "}
86 |
87 |
88 | )}
89 |
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 |
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 |
34 |
35 |
36 | {items[0].title}
37 |
38 |
39 |
40 |
41 |
47 |
48 |
49 | {items[1].title}
50 |
51 |
52 |
53 |
54 |
55 |
56 |
62 |
63 |
64 | {items[2].title}
65 |
66 |
67 |
68 |
69 |
75 |
76 |
77 | {items[3].title}
78 |
79 |
80 |
81 |
82 |
88 |
89 |
90 | {items[4].title}
91 |
92 |
93 |
94 |
95 |
96 |
97 |
103 |
104 |
105 | {items[5].title}
106 |
107 |
108 |
109 |
110 |
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 |
82 |
83 |
84 |
85 | ))}
86 |
87 | )}
88 |
89 |
setOpen(!open)}
91 | className="h-10 w-10 rounded-full bg-neutral-800 flex items-center justify-center"
92 | >
93 |
94 |
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 |
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 |
--------------------------------------------------------------------------------