├── .env.sample
├── .eslintrc.json
├── .gitignore
├── README.md
├── components.json
├── next.config.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
├── og-image.png
└── portfolioLogo.png
├── src
├── app
│ ├── about
│ │ └── page.tsx
│ ├── contact
│ │ └── page.tsx
│ ├── education
│ │ └── page.tsx
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.tsx
│ ├── loading.tsx
│ ├── more
│ │ └── page.tsx
│ ├── page.tsx
│ ├── projects
│ │ └── page.tsx
│ └── skills
│ │ └── page.tsx
├── components
│ ├── Aboutfooter.tsx
│ ├── ContactForm.tsx
│ ├── DownLoadResumeBtn.tsx
│ ├── Heading.tsx
│ ├── HeroImage.tsx
│ ├── HeroTexts.tsx
│ ├── Navbar.tsx
│ ├── ProjectsCard.tsx
│ ├── SendEmail.ts
│ ├── SkillsFotter.tsx
│ ├── SocialLinks.tsx
│ ├── TextRotator.tsx
│ ├── animation
│ │ ├── DockAnimation.tsx
│ │ ├── FramerWrapper.tsx
│ │ ├── GithubBtn.tsx
│ │ └── HackerBtn.tsx
│ └── ui
│ │ ├── badge.tsx
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ ├── input.tsx
│ │ ├── label.tsx
│ │ └── tooltip.tsx
├── config
│ └── portfolio.config.ts
└── lib
│ └── utils.ts
├── tailwind.config.ts
└── tsconfig.json
/.env.sample:
--------------------------------------------------------------------------------
1 | RESEND_API_KEY= Your Render Api Key
2 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Project Portfolio
2 |
3 | A simple and Beautiful Porfolio made with Nextjs and Shadcn Ui.
4 |
5 | 
6 |
7 | ## Getting Started
8 |
9 | First, run the development server:
10 |
11 | ```bash
12 | npm run dev
13 | # or
14 | yarn dev
15 | # or
16 | pnpm dev
17 | # or
18 | bun dev
19 | ```
20 |
21 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
22 |
23 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
24 |
25 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
26 |
27 | ## Configuration
28 |
29 | This project uses a centralized configuration approach for all personal information. The main configuration file is located at:
30 |
31 | ```
32 | src/config/portfolio.config.ts
33 | ```
34 |
35 | ### Configuration Structure
36 |
37 | The configuration file contains the following sections:
38 |
39 | - **Basic Information**: Name, title, description, location
40 | - **Contact Information**: Email and other contact details
41 | - **Social Media Links**: Links to various social media profiles
42 | - **SEO Information**: Keywords, metadata, and SEO-related settings
43 | - **About Information**: Bio, hobbies, and personal details
44 | - **Skills**: Programming languages, frameworks, tools, and professional roles
45 | - **Education**: Academic background and qualifications
46 | - **Projects**: Portfolio of projects with descriptions and links
47 | - **More Links**: Additional external links and resources
48 |
49 | ### Customizing Your Portfolio
50 |
51 | To personalize the portfolio, simply edit the values in the `portfolio.config.ts` file. All changes will be reflected throughout the site automatically without having to modify multiple files.
52 |
53 | Example usage in a component:
54 |
55 | ```typescript
56 | import { portfolioConfig } from "@/config/portfolio.config";
57 |
58 | // Access configuration values
59 | const { name, title } = portfolioConfig;
60 | ```
61 |
--------------------------------------------------------------------------------
/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "default",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "src/app/globals.css",
9 | "baseColor": "slate",
10 | "cssVariables": true
11 | },
12 | "aliases": {
13 | "components": "@/components",
14 | "utils": "@/lib/utils"
15 | }
16 | }
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | experimental:{
4 | serverComponentsExternalPackages: [
5 | '@react-email/render',
6 | ],
7 | // images:{
8 | // remotePatterns:[
9 | // {
10 | // protocol: 'https',
11 | // hostname: 'cdn.jsdelivr.net',
12 | // }
13 | // ]
14 | // }
15 | }
16 | }
17 |
18 | module.exports = nextConfig
19 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@radix-ui/react-label": "^2.0.2",
13 | "@radix-ui/react-toast": "^1.1.5",
14 | "@radix-ui/react-tooltip": "^1.0.7",
15 | "@vercel/og": "^0.5.20",
16 | "class-variance-authority": "^0.7.0",
17 | "clsx": "^2.0.0",
18 | "framer-motion": "^11.2.13",
19 | "lucide-react": "^0.292.0",
20 | "next": "^15.0.3",
21 | "react": "^18.3.1",
22 | "react-dom": "^18.3.1",
23 | "resend": "^0.16.0",
24 | "tailwind-merge": "^2.0.0",
25 | "tailwindcss-animate": "^1.0.7"
26 | },
27 | "devDependencies": {
28 | "@types/node": "^20",
29 | "@types/react": "^18",
30 | "@types/react-dom": "^18",
31 | "autoprefixer": "^10.0.1",
32 | "eslint": "^8",
33 | "eslint-config-next": "14.0.2",
34 | "postcss": "^8",
35 | "tailwindcss": "^3.3.0",
36 | "typescript": "^5"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/public/og-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/taqui-786/Portfolio/13a1ff256737e5fa2a781b77da6510c856572b4b/public/og-image.png
--------------------------------------------------------------------------------
/public/portfolioLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/taqui-786/Portfolio/13a1ff256737e5fa2a781b77da6510c856572b4b/public/portfolioLogo.png
--------------------------------------------------------------------------------
/src/app/about/page.tsx:
--------------------------------------------------------------------------------
1 | import Aboutfooter from "@/components/Aboutfooter";
2 | import FramerWrapper from "@/components/animation/FramerWrapper";
3 | import Heading from "@/components/Heading";
4 | import { Badge } from "@/components/ui/badge";
5 | import { Circle, Heart, User2 } from "lucide-react";
6 | import { portfolioConfig } from "@/config/portfolio.config";
7 |
8 | const page = () => {
9 | const items = portfolioConfig.about.hobbies.map((hobby) => ({ hobby }));
10 |
11 | return (
12 | // ABOUT PAGE
13 |
14 |
15 |
16 | About me
17 |
18 |
19 |
20 | {portfolioConfig.title} And Web Developer, Based In{" "}
21 | {portfolioConfig.about.personalInfo.nationality}.
22 |
23 |
24 |
25 |
26 | {portfolioConfig.about.bio}
27 |
28 |
29 |
30 |
35 |
36 |
37 |
38 |
39 | {" "}
40 | Hobbies
41 |
42 |
43 | {items.map((val, indx) => {
44 | return (
45 |
49 | {val.hobby}
50 |
51 | );
52 | })}
53 |
54 |
55 |
56 | );
57 | };
58 |
59 | export default page;
60 |
--------------------------------------------------------------------------------
/src/app/contact/page.tsx:
--------------------------------------------------------------------------------
1 | import ContactForm from "@/components/ContactForm";
2 | import FramerWrapper from "@/components/animation/FramerWrapper";
3 | import Heading from "@/components/Heading";
4 | import { Badge } from "@/components/ui/badge";
5 | import { Phone } from "lucide-react";
6 |
7 | const contactPage = () => {
8 | return (
9 | // PROJECT PAGE
10 |
11 |
12 |
13 | Contact Us
14 |
15 |
16 |
Contact Me!
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | );
26 | };
27 |
28 | export default contactPage;
29 |
--------------------------------------------------------------------------------
/src/app/education/page.tsx:
--------------------------------------------------------------------------------
1 | import FramerWrapper from "@/components/animation/FramerWrapper";
2 | import Heading from "@/components/Heading";
3 | import { Badge } from "@/components/ui/badge";
4 | import { Briefcase } from "lucide-react";
5 | import { portfolioConfig } from "@/config/portfolio.config";
6 |
7 | const educationPage = () => {
8 | return (
9 | // ABOUT PAGE
10 |
11 |
12 |
13 | Education
14 |
15 |
16 | My Education
17 |
18 |
19 | {portfolioConfig.education.map((edu, index) => (
20 |
21 |
27 | {edu.period}
28 |
29 |
35 |
36 | {edu.degree}, {edu.institution}
37 |
38 |
39 | {edu.description}
40 |
41 |
42 |
43 | ))}
44 |
45 |
46 | );
47 | };
48 |
49 | export default educationPage;
50 |
--------------------------------------------------------------------------------
/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/taqui-786/Portfolio/13a1ff256737e5fa2a781b77da6510c856572b4b/src/app/favicon.ico
--------------------------------------------------------------------------------
/src/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 |
6 | @layer base {
7 | :root {
8 | --background: 0 0% 100%;
9 | --foreground: 222.2 84% 4.9%;
10 |
11 | --card: 0 0% 100%;
12 | --card-foreground: 222.2 84% 4.9%;
13 |
14 | --popover: 0 0% 100%;
15 | --popover-foreground: 222.2 84% 4.9%;
16 |
17 | --primary: 222.2 47.4% 11.2%;
18 | --primary-foreground: 210 40% 98%;
19 | --primary-sky: 216.24deg 89.95% 57.06%;
20 |
21 | --secondary: 210 40% 96.1%;
22 | --secondary-foreground: 222.2 47.4% 11.2%;
23 |
24 | --muted: 210 40% 96.1%;
25 | --muted-foreground: 215.4 16.3% 46.9%;
26 |
27 | --accent: 210 40% 96.1%;
28 | --accent-foreground: 222.2 47.4% 11.2%;
29 |
30 | --destructive: 0 84.2% 60.2%;
31 | --destructive-foreground: 210 40% 98%;
32 |
33 | --border: 214.3 31.8% 91.4%;
34 | --input: 214.3 31.8% 91.4%;
35 | --ring: 222.2 84% 4.9%;
36 |
37 | --radius: 0.5rem;
38 | }
39 |
40 | .dark {
41 | --background: 222.2 84% 4.9%;
42 | --foreground: 210 40% 98%;
43 |
44 | --card: 222.2 84% 4.9%;
45 | --card-foreground: 210 40% 98%;
46 |
47 | --popover: 222.2 84% 4.9%;
48 | --popover-foreground: 210 40% 98%;
49 |
50 | --primary: 210 40% 98%;
51 | --primary-foreground: 222.2 47.4% 11.2%;
52 |
53 | --secondary: 217.2 32.6% 17.5%;
54 | --secondary-foreground: 210 40% 98%;
55 |
56 | --muted: 217.2 32.6% 17.5%;
57 | --muted-foreground: 215 20.2% 65.1%;
58 |
59 | --accent: 217.2 32.6% 17.5%;
60 | --accent-foreground: 210 40% 98%;
61 |
62 | --destructive: 0 62.8% 30.6%;
63 | --destructive-foreground: 210 40% 98%;
64 |
65 | --border: 217.2 32.6% 17.5%;
66 | --input: 217.2 32.6% 17.5%;
67 | --ring: 212.7 26.8% 83.9%;
68 | }
69 | }
70 |
71 | @layer base {
72 | * {
73 | @apply border-border;
74 | }
75 | body {
76 | @apply bg-background text-foreground;
77 | }
78 | }
79 |
80 | /* CUSTOM CSS */
81 | .name_underline::after{
82 | content: "";
83 | display: block;
84 | width: 6rem;
85 | height: .6rem;
86 | background-color: hsl(var(--primary-sky));
87 | }
88 | .icon_underline::after{
89 | content: "";
90 | position: absolute;
91 | top: 100%;
92 | display: block;
93 | width: 2rem;
94 | height: .3rem;
95 | background-color: hsl(var(--primary-sky));
96 | margin-bottom: 2rem;
97 | }
98 | .education_point::before{
99 | content: "";
100 | display: block;
101 | position: absolute;
102 | top: 46.7%;
103 | left: -7px;
104 | width: 10px;
105 | height: 10px;
106 | border-radius: 50%;
107 | background-color: hsl(var(--primary-sky));
108 | outline: 3px solid hsl(var(--primary));
109 | box-shadow: 0 2px 5px 2px hsl(var(--primary-sky));
110 | }
111 | /* TEXT ROTATOR STYLES */
112 | .animate-text-slide {
113 | animation: text-slide 12.5s cubic-bezier(0.83, 0, 0.17, 1) infinite;
114 | }
115 |
116 | @keyframes text-slide {
117 | 0%,
118 | 16% {
119 | transform: translateY(0%);
120 | }
121 |
122 | 20%,
123 | 36% {
124 | transform: translateY(-16.66%);
125 | }
126 |
127 | 40%,
128 | 56% {
129 | transform: translateY(-33.33%);
130 | }
131 |
132 | 60%,
133 | 76% {
134 | transform: translateY(-50%);
135 | }
136 |
137 | 80%,
138 | 96% {
139 | transform: translateY(-66.66%);
140 | }
141 |
142 | 100% {
143 | transform: translateY(-83.33%);
144 | }
145 | }
--------------------------------------------------------------------------------
/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import { Poppins, Rubik } from "next/font/google";
3 | import "./globals.css";
4 | import { cn } from "@/lib/utils";
5 | import Navbar from "@/components/Navbar";
6 | import { portfolioConfig } from "@/config/portfolio.config";
7 |
8 | const poppins = Poppins({
9 | subsets: ["latin"],
10 | weight: "400",
11 | variable: "--font-poppins",
12 | });
13 | const rubik = Rubik({
14 | subsets: ["latin"],
15 | weight: "600",
16 | variable: "--font-rubik",
17 | });
18 |
19 | export const metadata: Metadata = {
20 | metadataBase: new URL(portfolioConfig.seo.url),
21 | title: {
22 | default: portfolioConfig.name,
23 | template: `%s - ${portfolioConfig.title}`,
24 | },
25 | description: portfolioConfig.description,
26 |
27 | // added new keywords for seo
28 | keywords: portfolioConfig.seo.keywords,
29 | authors: portfolioConfig.seo.authors,
30 | creator: portfolioConfig.name,
31 |
32 | openGraph: {
33 | type: "website",
34 | locale: "en_US",
35 | url: portfolioConfig.seo.url,
36 | title: portfolioConfig.name,
37 | description: portfolioConfig.description,
38 | images: [`${portfolioConfig.seo.url}/og-image.png`],
39 | siteName: portfolioConfig.name,
40 | },
41 | twitter: {
42 | card: "summary_large_image",
43 | title: portfolioConfig.name,
44 | description: portfolioConfig.description,
45 | images: [`${portfolioConfig.seo.url}/og-image.png`],
46 | creator: portfolioConfig.seo.twitterHandle,
47 | },
48 | icons: {
49 | icon: "/favicon.ico",
50 | },
51 | };
52 |
53 | export default function RootLayout({
54 | children,
55 | }: {
56 | children: React.ReactNode;
57 | }) {
58 | return (
59 |
60 |
61 |
67 | {/* NAVBAR -> */}
68 |
69 | {children}
70 |
71 |
72 |
73 | );
74 | }
75 |
--------------------------------------------------------------------------------
/src/app/loading.tsx:
--------------------------------------------------------------------------------
1 | import { Loader } from "lucide-react";
2 |
3 |
4 | export default function Loading() {
5 | return (
6 |
7 |
8 | )
9 | }
--------------------------------------------------------------------------------
/src/app/more/page.tsx:
--------------------------------------------------------------------------------
1 | import Heading from "@/components/Heading";
2 | import { Badge } from "@/components/ui/badge";
3 | import { ExternalLink, PackagePlus } from "lucide-react";
4 | import {
5 | Card,
6 | CardContent,
7 | CardFooter,
8 | CardHeader,
9 | CardTitle,
10 | } from "@/components/ui/card";
11 | import Link from "next/link";
12 | import { cn } from "@/lib/utils";
13 | import { buttonVariants } from "@/components/ui/button";
14 | import FramerWrapper from "@/components/animation/FramerWrapper";
15 | import { portfolioConfig } from "@/config/portfolio.config";
16 |
17 | const morePage = () => {
18 | return (
19 | // ABOUT PAGE
20 |
21 |
22 |
23 | More
24 |
25 |
26 | More
27 |
28 |
29 | {portfolioConfig.moreLinks.map((value, indx) => {
30 | return (
31 |
39 |
40 |
41 | {value.title}
42 |
43 |
44 | {value.description}
45 |
46 |
47 |
55 | {" "}
56 |
57 | Visit here
58 |
59 |
60 |
61 |
62 | );
63 | })}
64 |
65 |
66 | );
67 | };
68 |
69 | export default morePage;
70 |
--------------------------------------------------------------------------------
/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | import SocialLinks from "@/components/SocialLinks";
2 | import HeroTexts from "@/components/HeroTexts";
3 | import HeroImage from "@/components/HeroImage";
4 | import GithubBtn from "@/components/animation/GithubBtn";
5 | import DownLoadResumeBtn from "@/components/DownLoadResumeBtn";
6 | import FramerWrapper from "@/components/animation/FramerWrapper";
7 |
8 |
9 | export default function Home() {
10 | return (
11 | <>
12 | {/* LEFT SIDE */}
13 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | {/* RIGHT SIDE image */}
25 |
30 | {/* IMAGE */}
31 |
32 |
33 |
34 | {/* GITHUB BUTTON */}
35 |
36 | >
37 | );
38 | }
39 |
--------------------------------------------------------------------------------
/src/app/projects/page.tsx:
--------------------------------------------------------------------------------
1 | import FramerWrapper from "@/components/animation/FramerWrapper";
2 | import Heading from "@/components/Heading";
3 | import ProjectCards from "@/components/ProjectsCard";
4 | import { Badge } from "@/components/ui/badge";
5 | import { Layers } from "lucide-react";
6 | import { portfolioConfig } from "@/config/portfolio.config";
7 |
8 | const projectsPage = () => {
9 | return (
10 | // PROJECT PAGE
11 |
12 |
13 |
14 | Projects
15 |
16 |
17 |
My Projects
18 |
19 |
20 | I love to Build Cool Projects. Here, you'll find a curated
21 | collection of my creative endeavors and technical projects. Each
22 | piece represents a journey of innovation, problem-solving, and
23 | continuous learning. Feel free to explore this showcase of my
24 | passion and expertise in action.
25 |
26 |
27 |
28 |
29 |
30 | {portfolioConfig.projects.map((val, indx) => {
31 | return
;
32 | })}
33 |
34 |
35 | );
36 | };
37 |
38 | export default projectsPage;
39 |
--------------------------------------------------------------------------------
/src/app/skills/page.tsx:
--------------------------------------------------------------------------------
1 | import Heading from "@/components/Heading";
2 | import SkillsFooter from "@/components/SkillsFotter";
3 | import { Badge } from "@/components/ui/badge";
4 | import { LightbulbIcon } from "lucide-react";
5 | import FramerWrapper from "@/components/animation/FramerWrapper";
6 | import { portfolioConfig } from "@/config/portfolio.config";
7 |
8 | const skillPage = () => {
9 | return (
10 | // SKILLS PAGE
11 |
12 |
13 |
14 | My Skills
15 |
16 |
17 |
My Technical Experience/Skills.
18 |
19 |
20 | Currently i am a fresher and i have a solid understand of HTML5,
21 | CSS3, JS, TS and React, including responsive design principles. I
22 | specialize in building web applications and sites using Javascript,
23 | Typescript, React, Nextjs & Node.
24 |
25 |
26 |
27 |
28 | Programming Languages
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | Framework/Libraries
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | Tools & Technologies
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | );
53 | };
54 |
55 | export default skillPage;
56 |
--------------------------------------------------------------------------------
/src/components/Aboutfooter.tsx:
--------------------------------------------------------------------------------
1 | import { Circle, Dna, Globe2, Languages } from "lucide-react";
2 | import { portfolioConfig } from "@/config/portfolio.config";
3 |
4 | const Aboutfooter = () => {
5 | const items = [
6 | {
7 | name: "Language",
8 | answer: portfolioConfig.about.personalInfo.language,
9 | icon: ,
10 | },
11 | {
12 | name: "Nationality",
13 | answer: portfolioConfig.about.personalInfo.nationality,
14 | icon: ,
15 | },
16 | {
17 | name: "Gender",
18 | answer: portfolioConfig.about.personalInfo.gender,
19 | icon: ,
20 | },
21 | ];
22 |
23 | return (
24 | <>
25 | {items.map((val, indx) => {
26 | return (
27 |
28 |
29 | {val.icon}
30 | {val.name}
31 |
32 |
33 | {val.answer}
34 |
35 |
36 | );
37 | })}
38 | >
39 | );
40 | };
41 |
42 | export default Aboutfooter;
43 |
--------------------------------------------------------------------------------
/src/components/ContactForm.tsx:
--------------------------------------------------------------------------------
1 | import { Input } from "@/components/ui/input";
2 | import { Label } from "@/components/ui/label";
3 |
4 | import {
5 | Card,
6 | CardContent,
7 | CardDescription,
8 | CardFooter,
9 | CardHeader,
10 | CardTitle,
11 | } from "@/components/ui/card";
12 | import { Button } from "./ui/button";
13 | import { SendEmail } from "./SendEmail";
14 |
15 | const ContactForm = () => {
16 | return (
17 |
18 |
65 |
66 | );
67 | };
68 |
69 | export default ContactForm;
70 |
--------------------------------------------------------------------------------
/src/components/DownLoadResumeBtn.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@/lib/utils'
2 | import { Download } from 'lucide-react'
3 | import Link from 'next/link'
4 | import React from 'react'
5 | import { buttonVariants } from './ui/button'
6 | import HackerBtn from './animation/HackerBtn'
7 |
8 | function DownLoadResumeBtn() {
9 | return (
10 |
11 |
12 |
13 |
14 | )
15 | }
16 |
17 | export default DownLoadResumeBtn
--------------------------------------------------------------------------------
/src/components/Heading.tsx:
--------------------------------------------------------------------------------
1 | import FramerWrapper from "./animation/FramerWrapper";
2 |
3 | const Heading = ({ children }: { children: React.ReactNode }) => {
4 | // CUSTOM HEADING FOR ALL PAGE
5 | return (
6 |
7 |
8 | {children}
9 |
10 |
11 | );
12 | };
13 |
14 | export default Heading;
15 |
--------------------------------------------------------------------------------
/src/components/HeroImage.tsx:
--------------------------------------------------------------------------------
1 | import logo from "../../public/portfolioLogo.png";
2 | import Image from "next/image"
3 |
4 | const HeroImage = () => {
5 |
6 |
7 |
8 | return(
9 | <>
10 |
18 | >
19 | )
20 | }
21 | export default HeroImage
--------------------------------------------------------------------------------
/src/components/HeroTexts.tsx:
--------------------------------------------------------------------------------
1 | import TextRotator from "./TextRotator";
2 | import { portfolioConfig } from "@/config/portfolio.config";
3 |
4 | const HeroTexts = () => {
5 | // Get the name parts
6 | const nameParts = portfolioConfig.name.split(" ");
7 | const firstName = nameParts[0];
8 | const middleName = nameParts.length > 2 ? nameParts[1] : "";
9 | const lastName = nameParts.length > 2 ? nameParts[2] : nameParts[1];
10 |
11 | return (
12 | <>
13 | My Name is
14 |
15 | {firstName} {middleName} {lastName} .
16 |
17 |
18 | >
19 | );
20 | };
21 | export default HeroTexts;
22 |
--------------------------------------------------------------------------------
/src/components/Navbar.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 | import { cn } from "@/lib/utils";
3 |
4 |
5 | import {
6 | Briefcase,
7 | FolderGit2,
8 | GraduationCap,
9 | HomeIcon,
10 | LightbulbIcon,
11 | Mail,
12 | MoreHorizontal,
13 |
14 | User,
15 | } from 'lucide-react';
16 |
17 | import { Dock, DockIcon, DockItem, DockLabel } from '@/components/animation/DockAnimation';
18 |
19 | import Link from "next/link";
20 | import { useEffect, useState } from "react";
21 | import FramerWrapper from "./animation/FramerWrapper";
22 | import { usePathname } from "next/navigation";
23 |
24 | const Navbar = () => {
25 |
26 | const data = [
27 | {
28 | title: 'Home',
29 | icon: (
30 |
31 | ),
32 | href: '/',
33 | },
34 | {
35 | title: 'About',
36 | icon: (
37 |
38 | ),
39 | href: '/about',
40 | },
41 | {
42 | title: 'Skills',
43 | icon: (
44 |
45 | ),
46 | href: '/skills',
47 | },
48 | {
49 | title: 'Education',
50 | icon: (
51 |
52 | ),
53 | href: '/education',
54 | },
55 | {
56 | title: 'Projects',
57 | icon: (
58 |
59 | ),
60 | href: '/projects',
61 | },
62 |
63 | {
64 | title: 'Contact us',
65 | icon: (
66 |
67 | ),
68 | href: '/contact',
69 | },
70 | {
71 | title: 'More',
72 | icon: (
73 |
74 | ),
75 | href: '/more',
76 | },
77 | ];
78 | const [scrolling, setScrolling] = useState(false);
79 | const pathname = usePathname()
80 |
81 | useEffect(() => {
82 | const handleScroll = () => {
83 | if (window.scrollY > 0) {
84 | setScrolling(true);
85 | } else {
86 | setScrolling(false);
87 | }
88 | };
89 |
90 | window.addEventListener('scroll', handleScroll);
91 |
92 | return () => {
93 | window.removeEventListener('scroll', handleScroll);
94 | };
95 | }, []);
96 |
97 |
98 | return (
99 |
100 |
101 |
102 | {data.map((item, idx) => (
103 |
104 |
105 |
108 | {item.title}
109 | {item.icon}
110 |
111 |
112 | ))}
113 |
114 |
115 | );
116 | };
117 |
118 | export default Navbar;
119 |
--------------------------------------------------------------------------------
/src/components/ProjectsCard.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from "@/lib/utils";
2 | import Link from "next/link";
3 | import { buttonVariants } from "./ui/button";
4 | import {
5 | Card,
6 | CardContent,
7 | CardFooter,
8 | CardHeader,
9 | CardTitle,
10 | } from "@/components/ui/card";
11 | import FramerWrapper from "./animation/FramerWrapper";
12 | import { ArrowUpRight } from "lucide-react";
13 |
14 | interface ProjectCardProps {
15 | value: {
16 | title: string;
17 | description: string;
18 | tags: string[];
19 | link: string;
20 | };
21 | num: number;
22 | }
23 |
24 | const ProjectCards: React.FC = ({ value, num }) => {
25 | return (
26 |
33 |
34 |
35 | {value.title}
36 |
37 |
38 |
39 | {value.description}
40 |
41 |
42 | {value.tags.map((tag: string, index: number) => {
43 | const tagStyles = {
44 | 'Nextjs': 'bg-teal-100 text-teal-800',
45 | 'Freelancing': 'bg-yellow-100 text-yellow-800',
46 | 'Shadcn Ui': 'bg-blue-100 text-blue-800',
47 | 'Typescript': 'bg-red-100 text-red-800',
48 | 'MySQL': 'bg-orange-100 text-orange-800',
49 | 'Zustand': 'bg-purple-100 text-purple-800',
50 | 'Supabase': 'bg-emerald-100 text-emerald-800',
51 | 'Npx': 'bg-indigo-100 text-indigo-800',
52 | 'Library': 'bg-pink-100 text-pink-800',
53 | 'Zod': 'bg-cyan-100 text-cyan-800',
54 | 'React Hook Form': 'bg-violet-100 text-violet-800'
55 | }[tag] || 'bg-gray-100 text-gray-800';
56 |
57 | return (
58 |
62 | {tag}
63 |
64 | );
65 | })}
66 |
67 |
68 |
69 |
70 |
82 | Visit Project
83 |
84 |
85 |
86 |
87 |
88 | );
89 | };
90 |
91 | export default ProjectCards;
92 |
--------------------------------------------------------------------------------
/src/components/SendEmail.ts:
--------------------------------------------------------------------------------
1 | import { Resend } from "resend";
2 | import {redirect} from 'next/navigation'
3 |
4 |
5 | // EMAIL SENDGING FUCTIONALITY
6 | // ADD RESEND_API_KEY IN YOUR .ENV FILE
7 | const resend = new Resend(process.env.RESEND_API_KEY);
8 | export const SendEmail = async (formdata: FormData) => {
9 | const message = formdata.get("message");
10 | const name = formdata.get("name");
11 | const SenderEmail = formdata.get("SenderEmail");
12 | if (!message) {
13 | return {
14 | error: "Invalid message",
15 | };
16 | }
17 | await resend.emails.send({
18 | from: "Contact Form ",
19 | to: `mdtaqui.jhar@gmail.com`,
20 | subject: `${name} From Contact Form.`,
21 | reply_to: `${SenderEmail}`,
22 | text: `sender email: ${SenderEmail}
23 | ${message}`,
24 | });
25 |
26 | return redirect('/')
27 |
28 |
29 | };
30 |
--------------------------------------------------------------------------------
/src/components/SkillsFotter.tsx:
--------------------------------------------------------------------------------
1 | import Image from "next/image";
2 | import React from "react";
3 |
4 | interface MyComponentProps {
5 | items: Array<{ alt?: string; img?: any; name?: string; icon?: string }>;
6 | }
7 |
8 | const SkillsFooter: React.FC = ({ items }) => {
9 | return (
10 | <>
11 | {items &&
12 | items.map((item, index) => {
13 | return (
14 |
15 |
19 |
24 |
25 | {item.name}
26 |
27 |
28 | );
29 | })}
30 | >
31 | );
32 | };
33 |
34 | export default SkillsFooter;
35 |
--------------------------------------------------------------------------------
/src/components/SocialLinks.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from "@/lib/utils";
2 | import {
3 | Facebook,
4 | Linkedin,
5 | Twitter,
6 | ExternalLink,
7 | Github,
8 | } from "lucide-react";
9 | import { buttonVariants } from "./ui/button";
10 | import Link from "next/link";
11 | import FramerWrapper from "./animation/FramerWrapper";
12 | import { portfolioConfig } from "@/config/portfolio.config";
13 |
14 | const SocialLinks = () => {
15 | const links = [
16 | {
17 | name: "Facebook",
18 | link: portfolioConfig.socialLinks.facebook,
19 | icon: ,
20 | },
21 | {
22 | name: "Twitter",
23 | link: portfolioConfig.socialLinks.twitter,
24 | icon: ,
25 | },
26 | {
27 | name: "Linkedin",
28 | link: portfolioConfig.socialLinks.linkedin,
29 | icon: ,
30 | },
31 | {
32 | name: "External",
33 | link: portfolioConfig.socialLinks.external,
34 | icon: ,
35 | },
36 | {
37 | name: "Github",
38 | link: portfolioConfig.socialLinks.github,
39 | icon: ,
40 | },
41 | ];
42 | return (
43 | <>
44 | {links.map((itm, indx) => {
45 | const timing = 0.55 + indx * 0.125;
46 |
47 | return (
48 |
49 |
56 | {itm.icon}
57 |
58 |
59 | );
60 | })}
61 | >
62 | );
63 | };
64 |
65 | export default SocialLinks;
66 |
--------------------------------------------------------------------------------
/src/components/TextRotator.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { portfolioConfig } from "@/config/portfolio.config";
3 |
4 | function TextRotator() {
5 | return (
6 |
7 |
8 | I am a {portfolioConfig.title} &
9 |
10 |
11 | {portfolioConfig.skills.roles.map((role, index) => (
12 |
13 | {role}
14 |
15 | ))}
16 |
17 |
18 |
19 |
20 | );
21 | }
22 |
23 | export default TextRotator;
24 |
--------------------------------------------------------------------------------
/src/components/animation/DockAnimation.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import {
4 | motion,
5 | MotionValue,
6 | useMotionValue,
7 | useSpring,
8 | useTransform,
9 | type SpringOptions,
10 | AnimatePresence,
11 | } from 'framer-motion';
12 | import {
13 | Children,
14 | cloneElement,
15 | createContext,
16 | useContext,
17 | useEffect,
18 | useMemo,
19 | useRef,
20 | useState,
21 | } from 'react';
22 | import { cn } from '@/lib/utils';
23 |
24 | const DOCK_HEIGHT = 128;
25 | const DEFAULT_MAGNIFICATION = 80;
26 | const DEFAULT_DISTANCE = 150;
27 | const DEFAULT_PANEL_HEIGHT = 64;
28 |
29 | type DockProps = {
30 | children: React.ReactNode;
31 | className?: string;
32 | distance?: number;
33 | panelHeight?: number;
34 | magnification?: number;
35 | spring?: SpringOptions;
36 | };
37 | type DockItemProps = {
38 | className?: string;
39 | children: React.ReactNode;
40 | };
41 | type DockLabelProps = {
42 | className?: string;
43 | children: React.ReactNode;
44 | };
45 | type DockIconProps = {
46 | className?: string;
47 | children: React.ReactNode;
48 | };
49 |
50 | type DocContextType = {
51 | mouseX: MotionValue;
52 | spring: SpringOptions;
53 | magnification: number;
54 | distance: number;
55 | };
56 | type DockProviderProps = {
57 | children: React.ReactNode;
58 | value: DocContextType;
59 | };
60 |
61 | const DockContext = createContext(undefined);
62 |
63 | function DockProvider({ children, value }: DockProviderProps) {
64 | return {children} ;
65 | }
66 |
67 | function useDock() {
68 | const context = useContext(DockContext);
69 | if (!context) {
70 | throw new Error('useDock must be used within an DockProvider');
71 | }
72 | return context;
73 | }
74 |
75 | function Dock({
76 | children,
77 | className,
78 | spring = { mass: 0.1, stiffness: 150, damping: 12 },
79 | magnification = DEFAULT_MAGNIFICATION,
80 | distance = DEFAULT_DISTANCE,
81 | panelHeight = DEFAULT_PANEL_HEIGHT,
82 | }: DockProps) {
83 | const mouseX = useMotionValue(Infinity);
84 | const isHovered = useMotionValue(0);
85 |
86 | const maxHeight = useMemo(() => {
87 | return Math.max(DOCK_HEIGHT, magnification + magnification / 2 + 4);
88 | }, [magnification]);
89 |
90 | const heightRow = useTransform(isHovered, [0, 1], [panelHeight, maxHeight]);
91 | const height = useSpring(heightRow, spring);
92 |
93 | return (
94 |
101 | {
103 | isHovered.set(1);
104 | mouseX.set(pageX);
105 | }}
106 | onMouseLeave={() => {
107 | isHovered.set(0);
108 | mouseX.set(Infinity);
109 | }}
110 | className={cn(
111 | 'mx-auto flex w-fit gap-1.5 sm:gap-4 rounded-2xl bg-gray-50 px-4 dark:bg-neutral-900',
112 | className
113 | )}
114 | style={{ height: panelHeight }}
115 | role='toolbar'
116 | aria-label='Application dock'
117 | >
118 |
119 | {children}
120 |
121 |
122 |
123 | );
124 | }
125 |
126 | function DockItem({ children, className }: DockItemProps) {
127 | const ref = useRef(null);
128 |
129 | const { distance, magnification, mouseX, spring } = useDock();
130 |
131 | const isHovered = useMotionValue(0);
132 |
133 | const mouseDistance = useTransform(mouseX, (val) => {
134 | const domRect = ref.current?.getBoundingClientRect() ?? { x: 0, width: 0 };
135 | return val - domRect.x - domRect.width / 2;
136 | });
137 |
138 | const widthTransform = useTransform(
139 | mouseDistance,
140 | [-distance, 0, distance],
141 | [40, magnification, 40]
142 | );
143 |
144 | const width = useSpring(widthTransform, spring);
145 |
146 | return (
147 | isHovered.set(1)}
151 | onHoverEnd={() => isHovered.set(0)}
152 | onFocus={() => isHovered.set(1)}
153 | onBlur={() => isHovered.set(0)}
154 | className={cn(
155 | 'relative inline-flex items-center justify-center',
156 | className
157 | )}
158 | tabIndex={0}
159 | role='button'
160 | aria-haspopup='true'
161 | >
162 | {Children.map(children, (child) =>
163 | cloneElement(child as React.ReactElement, { width, isHovered })
164 | )}
165 |
166 | );
167 | }
168 |
169 | function DockLabel({ children, className, ...rest }: DockLabelProps) {
170 | const restProps = rest as Record;
171 | const isHovered = restProps['isHovered'] as MotionValue;
172 | const [isVisible, setIsVisible] = useState(false);
173 |
174 | useEffect(() => {
175 | const unsubscribe = isHovered.on('change', (latest) => {
176 | setIsVisible(latest === 1);
177 | });
178 |
179 | return () => unsubscribe();
180 | }, [isHovered]);
181 |
182 | return (
183 |
184 | {isVisible && (
185 |
197 | {children}
198 |
199 | )}
200 |
201 | );
202 | }
203 |
204 | function DockIcon({ children, className, ...rest }: DockIconProps) {
205 | const restProps = rest as Record;
206 | const width = restProps['width'] as MotionValue;
207 |
208 | const widthTransform = useTransform(width, (val) => val / 2);
209 |
210 | return (
211 |
215 | {children}
216 |
217 | );
218 | }
219 |
220 | export { Dock, DockIcon, DockItem, DockLabel };
221 |
--------------------------------------------------------------------------------
/src/components/animation/FramerWrapper.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import React, { useState } from "react";
3 | import { motion, AnimatePresence } from "framer-motion";
4 | type FramerMotionProps = {
5 | children: React.ReactNode,
6 | className?:any,
7 | y?:number
8 | x?:number
9 | delay?:number
10 | duration?: number
11 | scale?:number
12 | }
13 | function FramerWrapper({children,delay = 0.25 ,y = 15, x = 0,duration = 0.20,scale = 0, className}:FramerMotionProps) {
14 | const [animateConfig, setAnimateConfig] = useState({
15 | opacity:1, y:0, x:0
16 | })
17 | return (
18 |
19 | {children}
26 |
27 | );
28 | }
29 |
30 | export default FramerWrapper;
--------------------------------------------------------------------------------
/src/components/animation/GithubBtn.tsx:
--------------------------------------------------------------------------------
1 | import { Github } from "lucide-react";
2 | import Link from "next/link";
3 |
4 | const GithubBtn = () => {
5 | return (
6 |
7 |
8 | Github
9 |
10 | );
11 | };
12 |
13 | export default GithubBtn;
14 |
--------------------------------------------------------------------------------
/src/components/animation/HackerBtn.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 | import { useState, useEffect } from 'react';
3 | import { Download } from 'lucide-react';
4 | import { Button } from '../ui/button';
5 |
6 | const HackerBtn = ({ label }: { label: string }) => {
7 | const [displayText, setDisplayText] = useState(label);
8 | const charset = "abcdefghijklmnopqrstuvwxyz";
9 |
10 | const randomChars = (length: number) => {
11 | return Array.from(
12 | { length },
13 | () => charset[Math.floor(Math.random() * charset.length)]
14 | ).join("");
15 | };
16 |
17 | const scramble = async (input: string) => {
18 | let prefix = "";
19 | for (let index = 0; index < input.length; index++) {
20 | await new Promise((resolve) => setTimeout(resolve, 50));
21 | prefix += input.charAt(index);
22 | setDisplayText(prefix + randomChars(input.length - prefix.length));
23 | }
24 | };
25 |
26 | const startScrambling = () => {
27 | scramble(label);
28 | setTimeout(() => console.log("Submitted"), label.length * 50);
29 | };
30 |
31 | useEffect(() => {
32 | setDisplayText(label);
33 | }, [label]);
34 |
35 | return (
36 |
38 | {displayText}
39 |
40 | );
41 | };
42 |
43 | export default HackerBtn;
44 |
--------------------------------------------------------------------------------
/src/components/ui/badge.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { cva, type VariantProps } from "class-variance-authority"
3 |
4 | import { cn } from "@/lib/utils"
5 | import FramerWrapper from "../animation/FramerWrapper"
6 |
7 | const badgeVariants = cva(
8 | "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
9 | {
10 | variants: {
11 | variant: {
12 | default:
13 | "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
14 | secondary:
15 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
16 | destructive:
17 | "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
18 | outline: "text-foreground",
19 | },
20 | },
21 | defaultVariants: {
22 | variant: "default",
23 | },
24 | }
25 | )
26 |
27 | export interface BadgeProps
28 | extends React.HTMLAttributes,
29 | VariantProps {}
30 |
31 | function Badge({ className, variant, ...props }: BadgeProps) {
32 | return (
33 |
34 |
35 |
36 |
37 | )
38 | }
39 |
40 | export { Badge, badgeVariants }
41 |
--------------------------------------------------------------------------------
/src/components/ui/button.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@/lib/utils'
2 | import { cva, VariantProps } from 'class-variance-authority'
3 | import { Loader2 } from 'lucide-react'
4 | import * as React from 'react'
5 |
6 | const buttonVariants = cva(
7 | 'active:scale-95 inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 disabled:opacity-50 dark:focus:ring-slate-400 disabled:pointer-events-none dark:focus:ring-offset-slate-900',
8 | {
9 | variants: {
10 | variant: {
11 | default: "bg-primary text-primary-foreground hover:bg-primary/90",
12 | destructive:
13 | "bg-destructive text-destructive-foreground hover:bg-destructive/90",
14 | outline:
15 | 'border border-[#000] bg-transparent hover:bg-accent hover:text-accent-foreground',
16 | custom:
17 | ' bg-[#020817] text-white hover:bg-[#020817d6] hover:shadow-lg',
18 | subtle:
19 | 'border border-input bg-background hover:bg-[#6aa2e6] hover:text-white',
20 | ghost:
21 | 'bg-transparent hover:bg-zinc-100 text-zinc-800 data-[state=open]:bg-transparent data-[state=open]:bg-transparent',
22 | link: 'bg-transparent dark:bg-transparent underline-offset-4 hover:underline text-slate-900 dark:text-slate-100 hover:bg-transparent dark:hover:bg-transparent',
23 | },
24 | size: {
25 | default: 'h-10 py-2 px-4',
26 | sm: 'h-9 px-2 rounded-md',
27 | xs: 'h-8 px-1.5 rounded-sm',
28 | lg: 'h-11 px-8 rounded-md',
29 | icon: "h-10 w-10",
30 | notch:"text-2xl px-2"
31 | },
32 | },
33 | defaultVariants: {
34 | variant: 'default',
35 | size: 'default',
36 | },
37 | }
38 | )
39 |
40 | export interface ButtonProps
41 | extends React.ButtonHTMLAttributes,
42 | VariantProps {
43 | isLoading?: boolean
44 | }
45 |
46 | const Button = React.forwardRef(
47 | ({ className, children, variant, isLoading, size, ...props }, ref) => {
48 | return (
49 |
54 | {isLoading ? : null}
55 | {children}
56 |
57 | )
58 | }
59 | )
60 | Button.displayName = 'Button'
61 |
62 | export { Button, buttonVariants }
--------------------------------------------------------------------------------
/src/components/ui/card.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 |
3 | import { cn } from "@/lib/utils"
4 |
5 | const Card = React.forwardRef<
6 | HTMLDivElement,
7 | React.HTMLAttributes
8 | >(({ className, ...props }, ref) => (
9 |
17 | ))
18 | Card.displayName = "Card"
19 |
20 | const CardHeader = React.forwardRef<
21 | HTMLDivElement,
22 | React.HTMLAttributes
23 | >(({ className, ...props }, ref) => (
24 |
29 | ))
30 | CardHeader.displayName = "CardHeader"
31 |
32 | const CardTitle = React.forwardRef<
33 | HTMLParagraphElement,
34 | React.HTMLAttributes
35 | >(({ className, ...props }, ref) => (
36 |
44 | ))
45 | CardTitle.displayName = "CardTitle"
46 |
47 | const CardDescription = React.forwardRef<
48 | HTMLParagraphElement,
49 | React.HTMLAttributes
50 | >(({ className, ...props }, ref) => (
51 |
56 | ))
57 | CardDescription.displayName = "CardDescription"
58 |
59 | const CardContent = React.forwardRef<
60 | HTMLDivElement,
61 | React.HTMLAttributes
62 | >(({ className, ...props }, ref) => (
63 |
64 | ))
65 | CardContent.displayName = "CardContent"
66 |
67 | const CardFooter = React.forwardRef<
68 | HTMLDivElement,
69 | React.HTMLAttributes
70 | >(({ className, ...props }, ref) => (
71 |
76 | ))
77 | CardFooter.displayName = "CardFooter"
78 |
79 | export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
80 |
--------------------------------------------------------------------------------
/src/components/ui/input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 |
3 | import { cn } from "@/lib/utils"
4 |
5 | export interface InputProps
6 | extends React.InputHTMLAttributes {}
7 |
8 | const Input = React.forwardRef(
9 | ({ className, type, ...props }, ref) => {
10 | return (
11 |
20 | )
21 | }
22 | )
23 | Input.displayName = "Input"
24 |
25 | export { Input }
26 |
--------------------------------------------------------------------------------
/src/components/ui/label.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as LabelPrimitive from "@radix-ui/react-label"
5 | import { cva, type VariantProps } from "class-variance-authority"
6 |
7 | import { cn } from "@/lib/utils"
8 |
9 | const labelVariants = cva(
10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
11 | )
12 |
13 | const Label = React.forwardRef<
14 | React.ElementRef,
15 | React.ComponentPropsWithoutRef &
16 | VariantProps
17 | >(({ className, ...props }, ref) => (
18 |
23 | ))
24 | Label.displayName = LabelPrimitive.Root.displayName
25 |
26 | export { Label }
27 |
--------------------------------------------------------------------------------
/src/components/ui/tooltip.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as TooltipPrimitive from "@radix-ui/react-tooltip"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const TooltipProvider = TooltipPrimitive.Provider
9 |
10 | const Tooltip = TooltipPrimitive.Root
11 |
12 | const TooltipTrigger = TooltipPrimitive.Trigger
13 |
14 | const TooltipContent = React.forwardRef<
15 | React.ElementRef,
16 | React.ComponentPropsWithoutRef
17 | >(({ className, sideOffset = 4, ...props }, ref) => (
18 |
27 | ))
28 | TooltipContent.displayName = TooltipPrimitive.Content.displayName
29 |
30 | export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
31 |
--------------------------------------------------------------------------------
/src/config/portfolio.config.ts:
--------------------------------------------------------------------------------
1 | export const portfolioConfig = {
2 | // Basic Information
3 | name: "Md Taqui Imam",
4 | title: "Software Engineer",
5 | description: "I am a Passionate Software Developer",
6 | location: "Ramgarh cantt, Jharkhand, India",
7 |
8 | // Contact Information
9 | email: "taquiimam@example.com", // Replace with actual email if available
10 |
11 | // Social Media Links
12 | socialLinks: {
13 | facebook: "https://www.facebook.com/shahina.khatun.1044",
14 | twitter: "https://twitter.com/Taquiimam14",
15 | linkedin: "https://www.linkedin.com/in/taqui-imam",
16 | external: "https://tinyurl.com/MdTaquiImam",
17 | github: "https://github.com/taqui-786", // Assuming this is the GitHub link
18 | },
19 |
20 | // SEO Information
21 | seo: {
22 | ogImage: "https://mdtaquiimam.vercel.app/og-image.png",
23 | url: "https://mdtaquiimam.vercel.app",
24 | twitterHandle: "@Taquiimam14",
25 | keywords: [
26 | "md",
27 | "taqui",
28 | "imam",
29 | "Md",
30 | "MD",
31 | "TAQUI",
32 | "Taqui",
33 | "Imam",
34 | "Imam",
35 | "Md Taqui Imam",
36 | "md taqui imam",
37 | "mdtaqui",
38 | "mdtaquiimam",
39 | "taqui imam",
40 | "Taqui Imam",
41 | "Taquiimam",
42 | "portfolio",
43 | "web developer",
44 | "web",
45 | "web dev",
46 | "developer",
47 | "PROGRAMMER ",
48 | "programmer ",
49 | "MD TAQUI IMAM ",
50 | "website",
51 | "@Taquiimam",
52 | "Taquiimam",
53 | "taqui developer",
54 | ],
55 | authors: [
56 | {
57 | name: "Taqui Imam",
58 | url: "https://github.com/taqui-786",
59 | },
60 | ],
61 | },
62 |
63 | // About Information
64 | about: {
65 | bio: "I am a Full Stack Web Developer from Ramgarh cantt, Jharkhand, India. I'm passionate about crafting web projects and contributing to open-source communities. I specialize in modern JavaScript frameworks and responsive CSS design, focusing on creating pixel-perfect, user-friendly interfaces. With strong attention to detail and efficient delivery, I build seamless web experiences that combine functionality with elegant design.",
66 | hobbies: [
67 | "Coding",
68 | "Playing Games",
69 | "Watching Anime",
70 | "Tech Blog Writing",
71 | "Creating Cool Projects",
72 | ],
73 | personalInfo: {
74 | language: "English UK",
75 | nationality: "India",
76 | gender: "Male",
77 | },
78 | },
79 |
80 | // Skills and Roles
81 | skills: {
82 | roles: [
83 | "Freelancer",
84 | "Blogger",
85 | "Gamer",
86 | "Creator",
87 | "Student",
88 | "Contributer",
89 | ],
90 | // Technical Skills
91 | programmingLanguages: [
92 | {
93 | name: "HTML5",
94 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/html5/html5-original.svg",
95 | },
96 | {
97 | name: "CSS3",
98 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/css3/css3-original.svg",
99 | },
100 | {
101 | name: "JavaScript",
102 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/javascript/javascript-original.svg",
103 | },
104 | {
105 | name: "TypeScript",
106 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/typescript/typescript-original.svg",
107 | },
108 | {
109 | name: "C++",
110 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/cplusplus/cplusplus-original.svg",
111 | },
112 | {
113 | name: "Python",
114 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/python/python-original.svg",
115 | },
116 | {
117 | name: "Java",
118 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/java/java-original.svg",
119 | },
120 | ],
121 | frameworks: [
122 | {
123 | name: "React",
124 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/react/react-original.svg",
125 | },
126 | {
127 | name: "Next.js",
128 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/nextjs/nextjs-original.svg",
129 | },
130 | {
131 | name: "Vue.js",
132 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/vuejs/vuejs-original.svg",
133 | },
134 | {
135 | name: "Svelte",
136 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/svelte/svelte-original.svg",
137 | },
138 | {
139 | name: "Tailwind CSS",
140 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/tailwindcss/tailwindcss-original.svg",
141 | },
142 | {
143 | name: "Bootstrap",
144 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/bootstrap/bootstrap-original.svg",
145 | },
146 | {
147 | name: "Material UI",
148 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/materialui/materialui-original.svg",
149 | },
150 | ],
151 | tools: [
152 | {
153 | name: "Git",
154 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/git/git-original.svg",
155 | },
156 | {
157 | name: "GitHub",
158 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/github/github-original.svg",
159 | },
160 | {
161 | name: "VS Code",
162 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/vscode/vscode-original.svg",
163 | },
164 | {
165 | name: "Docker",
166 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/docker/docker-original.svg",
167 | },
168 | {
169 | name: "Firebase",
170 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/firebase/firebase-plain.svg",
171 | },
172 | {
173 | name: "MongoDB",
174 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/mongodb/mongodb-original.svg",
175 | },
176 | {
177 | name: "PostgreSQL",
178 | icon: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/postgresql/postgresql-original.svg",
179 | },
180 | ],
181 | },
182 |
183 | // Education Information
184 | education: [
185 | {
186 | degree: "Bachelor of Computer Application",
187 | institution: "Ranchi University Jharkhand",
188 | location: "Doranda College Ranchi",
189 | period: "July 2023 - 2026",
190 | description:
191 | "I am currently Studying Bachelor of Computer Application form Doranda College Ranchi a Goverment College of Ranchi. The program has provided me with a well-rounded education, covering both theoretical foundations and practical applications of computer science.",
192 | },
193 | ],
194 |
195 | // Projects Information
196 | projects: [
197 | {
198 | title: "WePost- A modern, minimalistic social platform.",
199 | description:
200 | "WePost is a modern, minimalistic social platform for sharing posts, like, follow, and engaging in comments etc.",
201 | tags: ["Tanstack-Query", "PostgreSQL", "Shadcn Ui", "Nextjs"],
202 | link: "https://we-post-dev.vercel.app",
203 | },
204 | {
205 | title: "Devzone- A community chat app for devs",
206 | description:
207 | "DevZone is the ultimate chat platform for developers to connect, collaborate, and code together. Join the conversation and level up your coding journey.",
208 | tags: ["Zustand", "Supabase", "Shadcn Ui", "Nextjs"],
209 | link: "https://devzone-ti.vercel.app/",
210 | },
211 | {
212 | title: "itZmyLink- One Page many Links",
213 | description:
214 | "itZmyLink is a simple platform where user can create a personalized page to showcase all your social media profiles in one place. ",
215 | tags: ["Nextjs", "Typescript", "Shadcn Ui"],
216 | link: "https://github.com/taqui-786/itZmyLink",
217 | },
218 | {
219 | title: "GitEstimate- Github estimate worth generator",
220 | description:
221 | "GitEstimate is a simple fun tool where user can generate their github estimate worth card just by entering their github username. ",
222 | tags: ["Nextjs", "Typescript", "Shadcn Ui"],
223 | link: "https://github.com/taqui-786/GitEstimate",
224 | },
225 | {
226 | title: "Mixcn-ui- Reusable components for Nextjs",
227 | description:
228 | "This is Nextjs app with a Collection of Nextjs Components - (Currently under Devlelopment) ",
229 | tags: ["Nextjs", "Shadcnui", "Npx", "Library"],
230 | link: "https://mixcn-ui.vercel.app",
231 | },
232 | {
233 | title: "Rupeespot- All deals Product in one place",
234 | description:
235 | "This is a free tool to check price history charts for millions of products for popular Indian stores such as Amazon and Flipkart. ",
236 | tags: ["Nextjs", "Freelancing", "MySQL"],
237 | link: "https://rupeespot.com/",
238 | },
239 | {
240 | title: "Formcraft- Build Type-Safe Forms with Zero Effort",
241 | description:
242 | "Create production-ready forms with Zod validation, React Hook Form, and TypeScript. Design, customize, and deploy in minutes.",
243 | tags: ["Nextjs", "Shadcnui", "Zod", "React Hook Form "],
244 | link: "https://formcraft-ti.vercel.app/",
245 | },
246 | {
247 | title: "KryptoKapital- Investing in Cryptocurreny",
248 | description:
249 | "This is a platform for learning about cryptocurrency with many tools and festures. It is very big project. ",
250 | tags: ["Nextjs", "Freelancing", "Supabase"],
251 | link: "https://pro.kryptokapital.info/",
252 | },
253 | {
254 | title: "FriendZ - A social media Platform",
255 | description:
256 | "FriendZ is a social media app made with modern tech stacks such as redis, Authjs etc. A user can Create, delete, like, comment Post. ",
257 | tags: ["Redis", "Authjs", "Typescript", "Nextjs"],
258 | link: "https://github.com/taqui-786/project-friendz",
259 | },
260 | {
261 | title: "ChatApp- Simple instagram clone",
262 | description:
263 | "ChatApp is similar to instagram, you can create, edit, delete, like,comment, post and Follow, unfollow users",
264 | tags: ["Reactjs", "Javascript"],
265 | link: "https://github.com/taqui-786/chatapp-api",
266 | },
267 | {
268 | title: "Devletter - A Newsletter for devs",
269 | description:
270 | "Devletter ia a newsletter subscribing single page app made with Nextjs and Tailwindcss.",
271 | tags: ["Nextjs", "Tailwindcss"],
272 | link: "https://github.com/taqui-786/Devletter",
273 | },
274 | {
275 | title: "CrouMaker - A Crousal Maker App",
276 | description:
277 | "Crousal Maker is a tool with in-built crousals templates edit and download it in any format.",
278 | tags: ["Nextjs", "jsPDF", "html2canvas", "Shadcn Ui"],
279 | link: "https://github.com/taqui-786/crousal-maker",
280 | },
281 | ],
282 |
283 | // More Links Information
284 | moreLinks: [
285 | {
286 | title: "Dev.to",
287 | description:
288 | "I write blogs on web development, trending tech stacks or javascript guide or tips in Dev.to ",
289 | link: "https://dev.to/random_ti",
290 | },
291 | {
292 | title: "Hashnode",
293 | description:
294 | "I write blogs on web development, trending tech stacks or javascript guide or tips in Hashnode",
295 | link: "https://mdtaquiimam.hashnode.dev/",
296 | },
297 | {
298 | title: "Medium",
299 | description:
300 | "I write blogs on web development, trending tech stacks or javascript guide or tips in Medium",
301 | link: "https://medium.com/@mdtaqui.jhar",
302 | },
303 | {
304 | title: "Daily.Dev",
305 | description:
306 | "I am also the member of Daily Dev squads and i also upload post on some squads.",
307 | link: "https://app.daily.dev/taqui_786",
308 | },
309 | {
310 | title: "Gumroad",
311 | description:
312 | "I also sell digital products on gumroad like Notion Templates and web projects etc.",
313 | link: "https://mdtaquijhar.gumroad.com/",
314 | },
315 | {
316 | title: "Buy Me a coffee",
317 | description:
318 | "Supports my content quality, new topics, and project creation.",
319 | link: "https://www.buymeacoffee.com/taquidevloper",
320 | },
321 | ],
322 |
323 | // API Keys (should be in .env but referenced here)
324 | apiKeys: {
325 | resendApiKey: "YOUR_RESEND_API_KEY", // This should be loaded from environment variables in a real app
326 | },
327 | };
328 |
--------------------------------------------------------------------------------
/src/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { type ClassValue, clsx } from "clsx"
2 | import { twMerge } from "tailwind-merge"
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs))
6 | }
7 |
--------------------------------------------------------------------------------
/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | darkMode: ["class"],
4 | content: [
5 | './pages/**/*.{ts,tsx}',
6 | './components/**/*.{ts,tsx}',
7 | './app/**/*.{ts,tsx}',
8 | './src/**/*.{ts,tsx}',
9 | ],
10 | theme: {
11 | screens: {
12 | sm: '480px',
13 | md: '720px',
14 | lg: '976px',
15 | xl: '1440px',
16 | },
17 | container: {
18 | center: true,
19 | padding: "2rem",
20 | screens: {
21 | "2xl": "1400px",
22 | },
23 |
24 | },
25 | extend: {
26 | fontFamily:{
27 | poppins: ['var(--font-poppins)'],
28 | rubik: ['var(--font-rubik)']
29 | },
30 | colors: {
31 | border: "hsl(var(--border))",
32 | input: "hsl(var(--input))",
33 | ring: "hsl(var(--ring))",
34 | background: "hsl(var(--background))",
35 | foreground: "hsl(var(--foreground))",
36 | primary: {
37 | DEFAULT: "hsl(var(--primary))",
38 | foreground: "hsl(var(--primary-foreground))",
39 | sky: "hsl(var(--primary-sky))",
40 | },
41 | secondary: {
42 | DEFAULT: "hsl(var(--secondary))",
43 | foreground: "hsl(var(--secondary-foreground))",
44 | },
45 | destructive: {
46 | DEFAULT: "hsl(var(--destructive))",
47 | foreground: "hsl(var(--destructive-foreground))",
48 | },
49 | muted: {
50 | DEFAULT: "hsl(var(--muted))",
51 | foreground: "hsl(var(--muted-foreground))",
52 | },
53 | accent: {
54 | DEFAULT: "hsl(var(--accent))",
55 | foreground: "hsl(var(--accent-foreground))",
56 | },
57 | popover: {
58 | DEFAULT: "hsl(var(--popover))",
59 | foreground: "hsl(var(--popover-foreground))",
60 | },
61 | card: {
62 | DEFAULT: "hsl(var(--card))",
63 | foreground: "hsl(var(--card-foreground))",
64 | },
65 | },
66 | borderRadius: {
67 | lg: "var(--radius)",
68 | md: "calc(var(--radius) - 2px)",
69 | sm: "calc(var(--radius) - 4px)",
70 | },
71 | keyframes: {
72 | "accordion-down": {
73 | from: { height: 0 },
74 | to: { height: "var(--radix-accordion-content-height)" },
75 | },
76 | "accordion-up": {
77 | from: { height: "var(--radix-accordion-content-height)" },
78 | to: { height: 0 },
79 | },
80 | },
81 | animation: {
82 | "accordion-down": "accordion-down 0.2s ease-out",
83 | "accordion-up": "accordion-up 0.2s ease-out",
84 | },
85 | },
86 | },
87 | plugins: [require("tailwindcss-animate")],
88 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./src/*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------