├── src
├── App.css
├── assets
│ ├── app.png
│ ├── hero.jpg
│ ├── login.png
│ ├── logo.png
│ ├── tripy.png
│ ├── profile.jpg
│ ├── slider.png
│ ├── travel.png
│ ├── Zain-logo (3).png
│ ├── zain.svg
│ ├── Zain-logo (1).svg
│ └── Zain-logo (3).svg
├── main.jsx
├── components
│ ├── Mywork
│ │ ├── workData.js
│ │ └── Mywork.jsx
│ ├── Services
│ │ ├── ServicesData.js
│ │ └── Services.jsx
│ ├── Hero
│ │ └── Hero.jsx
│ ├── Footer
│ │ └── Footer.jsx
│ ├── About
│ │ └── About.jsx
│ ├── Navbar
│ │ └── Navbar.jsx
│ └── Contact
│ │ └── Conatct.jsx
├── App.jsx
└── index.css
├── README.md
├── postcss.config.js
├── vite.config.js
├── tailwind.config.js
├── .gitignore
├── .eslintrc.cjs
├── index.html
├── package.json
└── public
└── vite.svg
/src/App.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # npm i react-anchor-link-smooth-scroll
2 |
3 | #
4 |
--------------------------------------------------------------------------------
/src/assets/app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/code-with-zain-hunzai/Portfolio/HEAD/src/assets/app.png
--------------------------------------------------------------------------------
/src/assets/hero.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/code-with-zain-hunzai/Portfolio/HEAD/src/assets/hero.jpg
--------------------------------------------------------------------------------
/src/assets/login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/code-with-zain-hunzai/Portfolio/HEAD/src/assets/login.png
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/code-with-zain-hunzai/Portfolio/HEAD/src/assets/logo.png
--------------------------------------------------------------------------------
/src/assets/tripy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/code-with-zain-hunzai/Portfolio/HEAD/src/assets/tripy.png
--------------------------------------------------------------------------------
/src/assets/profile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/code-with-zain-hunzai/Portfolio/HEAD/src/assets/profile.jpg
--------------------------------------------------------------------------------
/src/assets/slider.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/code-with-zain-hunzai/Portfolio/HEAD/src/assets/slider.png
--------------------------------------------------------------------------------
/src/assets/travel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/code-with-zain-hunzai/Portfolio/HEAD/src/assets/travel.png
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/src/assets/Zain-logo (3).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/code-with-zain-hunzai/Portfolio/HEAD/src/assets/Zain-logo (3).png
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: [
4 | "./index.html",
5 | "./src/**/*.{js,ts,jsx,tsx}",
6 | ],
7 | theme: {
8 | extend: {},
9 | },
10 | plugins: [],
11 | }
--------------------------------------------------------------------------------
/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App.jsx'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root')).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true },
4 | extends: [
5 | 'eslint:recommended',
6 | 'plugin:react/recommended',
7 | 'plugin:react/jsx-runtime',
8 | 'plugin:react-hooks/recommended',
9 | ],
10 | ignorePatterns: ['dist', '.eslintrc.cjs'],
11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
12 | settings: { react: { version: '18.2' } },
13 | plugins: ['react-refresh'],
14 | rules: {
15 | 'react/jsx-no-target-blank': 'off',
16 | 'react-refresh/only-export-components': [
17 | 'warn',
18 | { allowConstantExport: true },
19 | ],
20 | },
21 | }
22 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Portfolio
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/components/Mywork/workData.js:
--------------------------------------------------------------------------------
1 | import tripy from '../../assets/tripy.png';
2 | import app from '../../assets/app.png'
3 | import slider from '../../assets/slider.png'
4 | import login from '../../assets/login.png'
5 | import travel from '../../assets/travel.png'
6 |
7 | export const workData = [
8 | {
9 | w_no: 1,
10 | w_Name: "web-design",
11 | w_img: tripy
12 | },
13 | {
14 | w_no: 2,
15 | w_Name: "web-design",
16 | w_img: app
17 | },
18 | {
19 | w_no: 3,
20 | w_Name: "web-design",
21 | w_img: slider
22 | },
23 | {
24 | w_no: 4,
25 | w_Name: "web-design",
26 | w_img: login
27 | },
28 | {
29 | w_no: 5,
30 | w_Name: "web-design",
31 | w_img: travel
32 | }
33 | ];
34 |
--------------------------------------------------------------------------------
/src/components/Services/ServicesData.js:
--------------------------------------------------------------------------------
1 | export const ServicesData = [
2 | {
3 | serviceNo: "01",
4 | serviceName: "Web Design",
5 | serviceDesc: "Web development is a process of building, programming..."
6 | },
7 | {
8 | serviceNo: "02",
9 | serviceName: "Graphics Design",
10 | serviceDesc: "Graphics design involves creating visual content..."
11 | },
12 | {
13 | serviceNo: "03",
14 | serviceName: "Social Media",
15 | serviceDesc: "Social media management is the process of creating..."
16 | },
17 | {
18 | serviceNo: "04",
19 | serviceName: "App Design",
20 | serviceDesc: "App design is the process of designing mobile applications..."
21 | },
22 | {
23 | serviceNo: "05",
24 | serviceName: "App Development",
25 | serviceDesc: "App development is the process of building mobile applications..."
26 | },
27 | ];
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "portfolio-react",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "aos": "^2.3.4",
14 | "react": "^18.3.1",
15 | "react-anchor-link-smooth-scroll": "^1.0.12",
16 | "react-dom": "^18.3.1",
17 | "react-toastify": "^10.0.5"
18 | },
19 | "devDependencies": {
20 | "@types/react": "^18.3.3",
21 | "@types/react-dom": "^18.3.0",
22 | "@vitejs/plugin-react": "^4.3.1",
23 | "autoprefixer": "^10.4.19",
24 | "eslint": "^8.57.0",
25 | "eslint-plugin-react": "^7.34.2",
26 | "eslint-plugin-react-hooks": "^4.6.2",
27 | "eslint-plugin-react-refresh": "^0.4.7",
28 | "postcss": "^8.4.39",
29 | "tailwindcss": "^3.4.4",
30 | "vite": "^5.3.1"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/App.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { useState } from 'react';
3 | import Navbar from './components/Navbar/Navbar';
4 | import Hero from './components/Hero/Hero';
5 | import About from './components/About/About';
6 | import Services from './components/Services/Services';
7 | import Mywork from './components/Mywork/Mywork';
8 | import Conatct from './components/Contact/Conatct';
9 | import Footer from './components/Footer/Footer';
10 |
11 | const App = () => {
12 | const [darkMode, setdarkMode] = useState(false)
13 |
14 | const toggleDarkMode = () => {
15 | setdarkMode(!darkMode)
16 | }
17 | return (
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | )
32 | }
33 |
34 | export default App
35 |
--------------------------------------------------------------------------------
/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/Services/Services.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {ServicesData} from './ServicesData';
3 | import { FaArrowRightLong } from "react-icons/fa6";
4 |
5 | const Services = () => {
6 | return (
7 |
8 |
9 |
My Services
10 |
11 |
12 | {ServicesData.map((service, index) => (
13 |
14 |
{service.serviceNo}
15 |
{service.serviceName}
16 |
{service.serviceDesc}
17 |
21 |
22 | ))}
23 |
24 |
25 | );
26 | }
27 |
28 | export default Services;
--------------------------------------------------------------------------------
/src/components/Mywork/Mywork.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { workData } from './workData';
3 | import { FaArrowRightLong } from "react-icons/fa6";
4 |
5 | const Mywork = () => {
6 | const [hoveredIndex, setHoveredIndex] = useState(null);
7 |
8 | return (
9 |
10 |
11 |
My latest work
12 |
13 |
14 | {workData.map((work, index) => {
15 | return (
16 |
setHoveredIndex(index)}
20 | onMouseLeave={() => setHoveredIndex(null)}
21 | >
22 |

23 |
24 | )
25 | })}
26 |
27 |
31 |
32 | )
33 | }
34 |
35 | export default Mywork;
36 |
--------------------------------------------------------------------------------
/src/components/Hero/Hero.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { useEffect } from 'react';
3 | import AOS from 'aos';
4 | import hero from '../../assets/hero.jpg';
5 | import AnchorLink from 'react-anchor-link-smooth-scroll';
6 | import 'aos/dist/aos.css';
7 | const Hero = () => {
8 |
9 | useEffect(() => {
10 | AOS.init({ duration: 2000 });
11 | }, []);
12 |
13 | return (
14 |
15 |

16 |
17 |
18 |
27 | I'm Zain,
28 |
29 | FrontEnd Developer base on pakistan
30 |
31 |
I am a FrontEnd Developer from hunza with the 3-4 years of experience.
32 |
33 |
35 |
36 | Connect with me
37 |
My resume
38 |
39 |
40 | )
41 | }
42 |
43 | export default Hero
44 |
--------------------------------------------------------------------------------
/src/components/Footer/Footer.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import zain from '../../assets/zain.svg'
3 |
4 | const Footer = () => {
5 | return (
6 |
7 |
8 |
9 |

10 |
11 | I'm Zain,
12 | FrontEnd Developer base on pakistan,I am a FrontEnd Developer from hunza with the 3-4 years of experience.
13 |
14 |
15 |
16 |
20 |
21 |
22 |
23 |
Subscribe
24 |
25 |
26 |
27 |
28 |
© 2024 zain.hunzai All rights reserved
29 |
30 |
Term of Services
31 |
Privacy policy
32 |
Connect with me
33 |
34 |
35 |
36 | )
37 | }
38 |
39 | export default Footer
40 |
--------------------------------------------------------------------------------
/src/assets/zain.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/assets/Zain-logo (1).svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/assets/Zain-logo (3).svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/components/About/About.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import profile from '../../assets/profile.jpg'
3 |
4 | const About = () => {
5 | return (
6 |
7 |
8 |
About me
9 |
10 |
11 |
12 |

13 |
14 |
15 |
16 |
A front-end developer designs interactive, visually engaging web interfaces using HTML, CSS, and JavaScript, enhancing user experience.
17 |
A front-end developer creates dynamic web pages, focusing on user experience through the use of HTML, CSS, and JavaScript, React & Next.js
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
3+
31 |
YEARS OF EXPERIENCE
32 |
33 |
34 |
35 |
20+
36 |
PROJECTS COMPLETED
37 |
38 |
39 |
40 |
15+
41 |
HAPPY CLIENTS
42 |
43 |
44 |
45 | )
46 | }
47 | export default About
48 |
--------------------------------------------------------------------------------
/src/components/Navbar/Navbar.jsx:
--------------------------------------------------------------------------------
1 | import React, { useRef, useState } from 'react';
2 | import zain from '../../assets/zain.svg';
3 | import AnchorLink from 'react-anchor-link-smooth-scroll';
4 | import { MdOutlineLightMode } from "react-icons/md";
5 | import { FaMoon } from "react-icons/fa";
6 |
7 | const Navbar = ({ darkMode, toggleDarkMode }) => {
8 | const [menu, setMenu] = useState("home");
9 | const [isMenuOpen, setIsMenuOpen] = useState(false);
10 | const menuRef = useRef();
11 |
12 | const openMenu = () => {
13 | setIsMenuOpen(true);
14 | menuRef.current.style.right = '0';
15 | };
16 |
17 | const closeMenu = () => {
18 | setIsMenuOpen(false);
19 | menuRef.current.style.right = '-350px';
20 | };
21 |
22 | return (
23 |
24 |
25 |

26 |
27 |
31 |
32 |
33 |
34 |
35 |
39 |
40 |
41 | -
42 |
43 |
setMenu("home")}>Home
44 |
45 | {menu === "home" &&
}
46 |
47 | -
48 |
49 |
setMenu("about me")}>About me
50 |
51 | {menu === "about me" &&
}
52 |
53 | -
54 |
55 |
setMenu("services")}>Services
56 |
57 | {menu === "services" &&
}
58 |
59 | -
60 |
61 |
setMenu("portfolio")}>Portfolio
62 |
63 | {menu === "portfolio" &&
}
64 |
65 | -
66 |
67 |
setMenu("contact")}>Contact
68 |
69 | {menu === "contact" &&
}
70 |
71 |
72 |
73 |
75 |
76 | Connect with me
77 |
78 |
79 |
80 |
86 |
87 |
88 |
89 |
90 | );
91 | };
92 |
93 | export default Navbar;
94 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | * {
6 | margin: 0;
7 | padding: 0;
8 | box-sizing: border-box;
9 | }
10 |
11 | body {
12 | height: 100vh;
13 | color: white;
14 | font-family: outfit;
15 | }
16 |
17 | @layer components {
18 | .about-skill:hover {
19 | transform: scale(1.05);
20 | transition: 0.3s;
21 | }
22 |
23 | .about-skill hr {
24 | outline: none;
25 | border: none;
26 | width: 50%;
27 | height: 8PX;
28 | border-radius: 50px;
29 | background: linear-gradient(264deg, #DF8908 -5.09%, #b415b4 106.28%);
30 | }
31 |
32 | .about-achievements {
33 | width: 100%;
34 | justify-content: space-around;
35 | align-items: center;
36 | margin-bottom: 80px;
37 | margin-top: 70px;
38 | }
39 |
40 | .about-achievement:hover {
41 | transform: scale(1.12);
42 | transition: 0.3s;
43 | }
44 |
45 | .about-achievements .vertical-hr {
46 | width: 1px;
47 | height: 100px;
48 | background-color: #fff;
49 | transform: rotate(180deg);
50 | }
51 |
52 | .about-achievement {
53 | display: flex;
54 | flex-direction: column;
55 | align-items: center;
56 | gap: 10px;
57 | transition: 0.5s;
58 | }
59 |
60 | .about-achievement h1 {
61 | font-size: 60px;
62 | font-weight: 700;
63 | margin-bottom: 10px;
64 | background: linear-gradient(270deg, #DF8908 50.41%, #b415b4B4 90.25%);
65 | background-clip: text;
66 | -webkit-background-clip: text;
67 | -webkit-text-fill-color: transparent;
68 | }
69 | .services-format h2 {
70 | background: linear-gradient(270deg, #DF8908 50.41%, #b415b4B4 90.25%);
71 | background-clip: text;
72 | -webkit-background-clip: text;
73 | -webkit-text-fill-color: transparent;
74 | }
75 |
76 | .services-format:hover {
77 | border: 2px solid #ff00ff;
78 | background: linear-gradient(45deg, #3f0028, #583300);
79 | transform: scale(1.05);
80 | transition: 0.5s;
81 | }
82 |
83 | .mywork-container {
84 | display: grid;
85 | gap: 40px;
86 | }
87 |
88 | .mywork-container img {
89 | box-sizing: border-box;
90 | width: 100%;
91 | height: auto;
92 | object-fit: cover;
93 | border-radius: 10px;
94 | transition: 0.3s;
95 | cursor: pointer;
96 | }
97 |
98 | .mywork-container img:hover {
99 | transform: scale(1.10);
100 | border: 2px solid fuchsia;
101 | transition: 0.3s;
102 | }
103 |
104 | .loaction:hover {
105 | transform: scale(1.10);
106 | }
107 |
108 | .contact-left h1 {
109 | font-size: 80px;
110 | font-family: 800px;
111 | background: linear-gradient(270deg, #DF8908 50.41%, #b415b4B4 90.25%);
112 | background-clip: text;
113 | -webkit-background-clip: text;
114 | -webkit-text-fill-color: transparent;
115 | }
116 |
117 | .contact-details {
118 | gap: 30px
119 | }
120 |
121 | .contact-detail {
122 | display: flex;
123 | align-items: center;
124 | gap: 20px;
125 | margin-bottom: 15px;
126 | font-size: 22px;
127 | }
128 |
129 | .contact-detail p {
130 | cursor: pointer;
131 | }
132 |
133 | .conatct-right label {
134 | color: #d8d8d8;
135 | font-size: 22px;
136 | font-weight: 500;
137 | }
138 |
139 | .contact-right input {
140 | border: none;
141 | width: 700px;
142 | height: 40px;
143 | padding-left: 20px;
144 | border-radius: 4px;
145 | background-color: #32323c;
146 | color: #a0a0a0;
147 | font-family: outfit;
148 | font-size: 16px;
149 | outline: none;
150 | }
151 |
152 | .text-area {
153 | border: none;
154 | width: 650px;
155 | height: 250px;
156 | padding-left: 20px;
157 | padding: 10px;
158 | border-radius: 4px;
159 | background-color: #32323c;
160 | color: #a0a0a0;
161 | font-family: outfit;
162 | font-size: 16px;
163 | outline: none;
164 | }
165 |
166 | .contact-submit {
167 | border: none;
168 | color: white;
169 | border-radius: 50px;
170 | background: linear-gradient(270deg, #DF8908 50.41%, #b415b4B4 90.25%);
171 | font-size: 22px;
172 | font-weight: 600;
173 | padding: 16px 40px;
174 | margin-bottom: 50px;
175 | cursor: pointer;
176 | transition: 0.3s;
177 | }
178 |
179 | .contact-submit:hover {
180 | transform: scale(1.1);
181 | transition: 0.3s;
182 | }
183 |
184 | .footer hr {
185 | width: 100%;
186 | background-color: #fff;
187 | }
188 |
189 | .footer-subscribe {
190 | font-size: 20px;
191 | padding: 16px 40px;
192 | border-radius: 50px;
193 | background: linear-gradient(270deg, #DF8908 50.41%, #b415b4B4 90.25%);
194 | cursor: pointer;
195 | transition: 0.3s;
196 | }
197 |
198 | .footer-subscribe:hover {
199 | transform: scale(1.1);
200 | transition: 0.3s;
201 | }
202 |
203 | .nav-line {
204 | outline: none;
205 | border: none;
206 | height: 4PX;
207 | border-radius: 40px;
208 | background: linear-gradient(264deg, #DF8908 -5.09%, #b415b4 106.28%);
209 | }
210 |
211 | .nav-mob-open {
212 | display: none;
213 | }
214 |
215 | .nav-mob-close {
216 | display: none;
217 | }
218 |
219 | @media(max-width: 1024px) {
220 | .nav-mob-open {
221 | display: block;
222 | position: fixed;
223 | right: 30px;
224 | z-index: 3;
225 | }
226 |
227 | .nav-mob-close {
228 | display: block;
229 | position: fixed;
230 | top: 15px;
231 | right: 30px;
232 | width: 30px;
233 | z-index: 3;
234 | }
235 |
236 | .nav-menu {
237 | position: fixed;
238 | flex-direction: column;
239 | align-items: center;
240 | top: 0;
241 | gap: 30px;
242 | background-color: #1f0016;
243 | width: 350px;
244 | height: 75%;
245 | z-index: 2;
246 | transition: right 0.5s;
247 | right: -350px;
248 | }
249 |
250 | .nav-menu li {
251 | padding-top: 50px;
252 | font-size: 20px;
253 | flex-direction: column;
254 | }
255 | }
256 |
257 | @media(max-width:768px) {
258 | .contact-right input {
259 | width: 400px;
260 | height: 40px;
261 | }
262 |
263 | .text-area {
264 | width: 350px;
265 | height: 250px;
266 | }
267 | }
268 |
269 | }
--------------------------------------------------------------------------------
/src/components/Contact/Conatct.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { IoLocationSharp } from "react-icons/io5";
3 | import { ToastContainer, toast } from 'react-toastify';
4 | import 'react-toastify/dist/ReactToastify.css';
5 |
6 | const Contact = () => {
7 | const [result, setResult] = useState("");
8 | const [nameError, setNameError] = useState("");
9 | const [emailError, setEmailError] = useState("");
10 | const [messageError, setMessageError] = useState("");
11 |
12 | const validateEmail = (email) => {
13 | const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
14 | return re.test(String(email).toLowerCase());
15 | };
16 |
17 | const handleNameChange = (event) => {
18 | const name = event.target.value;
19 | if (name.length >= 3) {
20 | setNameError('');
21 | }
22 | };
23 |
24 | const handleEmailChange = (event) => {
25 | const email = event.target.value;
26 | if (validateEmail(email)) {
27 | setEmailError('');
28 | }
29 | };
30 |
31 | const handleMessageChange = (event) => {
32 | const message = event.target.value;
33 | if (message.length >= 11) {
34 | setMessageError('');
35 | }
36 | };
37 |
38 | const onSubmit = async (event) => {
39 | event.preventDefault();
40 | setResult("Sending....");
41 |
42 | const formData = new FormData(event.target);
43 | const name = formData.get('name');
44 | const email = formData.get('email');
45 | const message = formData.get('message');
46 |
47 | let valid = true;
48 |
49 | if (name.length < 3) {
50 | setNameError('Name must be at least 3 characters long.');
51 | valid = false;
52 | }
53 |
54 | if (!validateEmail(email)) {
55 | setEmailError('Invalid email format.');
56 | valid = false;
57 | }
58 |
59 | if (message.length < 11) {
60 | setMessageError('Message must be at least 11 characters long.');
61 | valid = false;
62 | }
63 |
64 | if (!valid) {
65 | setResult("");
66 | return;
67 | }
68 |
69 | formData.append("access_key", "3e55aee4-5c14-4cb8-b945-dfa81252a6e0");
70 |
71 | try {
72 | const response = await fetch("https://api.web3forms.com/submit", {
73 | method: "POST",
74 | body: formData
75 | });
76 |
77 | const data = await response.json();
78 |
79 | if (data.success) {
80 | setResult("Form Submitted Successfully");
81 | event.target.reset();
82 | toast.success('Form submitted successfully!');
83 | } else {
84 | console.log("Error", data);
85 | setResult(data.message);
86 | toast.error('Form submission failed.');
87 | }
88 | } catch (error) {
89 | console.error("Error submitting the form:", error);
90 | setResult("Error submitting the form");
91 | toast.error('Form submission failed.');
92 | }
93 | };
94 |
95 | return (
96 | <>
97 |
109 |
160 | >
161 | )
162 | }
163 |
164 | export default Contact;
165 |
--------------------------------------------------------------------------------