├── public
├── favicon.ico
├── logo192.png
├── logo512.png
├── robots.txt
├── manifest.json
└── index.html
├── src
├── assets
│ ├── img
│ │ ├── 666.jpg
│ │ ├── 12345.jpg
│ │ ├── odina.png
│ │ ├── odina2.png
│ │ ├── project1.jpg
│ │ ├── project6.jpg
│ │ ├── banner-bg.png
│ │ ├── color-sharp.png
│ │ ├── fifth work.jpg
│ │ ├── first work.jpg
│ │ ├── footer-bg.png
│ │ ├── second work.jpg
│ │ ├── color-sharp2.png
│ │ ├── forth project.jpg
│ │ ├── project-img1.png
│ │ ├── project-img2.png
│ │ ├── project-img3.png
│ │ ├── nav-icon2.svg
│ │ ├── arrow1.svg
│ │ ├── arrow2.svg
│ │ ├── nav-icon1.svg
│ │ ├── logo.svg
│ │ ├── nav-icon3.svg
│ │ ├── meter3.svg
│ │ ├── meter1.svg
│ │ ├── meter2.svg
│ │ └── contact-img.svg
│ └── font
│ │ ├── CentraNo2-Bold.ttf
│ │ ├── CentraNo2-Book.ttf
│ │ └── CentraNo2-Medium.ttf
├── setupTests.js
├── App.test.js
├── index.css
├── reportWebVitals.js
├── components
│ ├── ProjectCard.js
│ ├── MailchimpForm.js
│ ├── Footer.js
│ ├── Newsletter.js
│ ├── Skills.js
│ ├── NavBar.js
│ ├── Banner.js
│ ├── Projects.js
│ └── Contact.js
├── index.js
├── App.js
├── logo.svg
└── App.css
├── .gitignore
├── README.md
├── package.json
└── server.js
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/public/logo512.png
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/src/assets/img/666.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/666.jpg
--------------------------------------------------------------------------------
/src/assets/img/12345.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/12345.jpg
--------------------------------------------------------------------------------
/src/assets/img/odina.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/odina.png
--------------------------------------------------------------------------------
/src/assets/img/odina2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/odina2.png
--------------------------------------------------------------------------------
/src/assets/img/project1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/project1.jpg
--------------------------------------------------------------------------------
/src/assets/img/project6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/project6.jpg
--------------------------------------------------------------------------------
/src/assets/img/banner-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/banner-bg.png
--------------------------------------------------------------------------------
/src/assets/img/color-sharp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/color-sharp.png
--------------------------------------------------------------------------------
/src/assets/img/fifth work.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/fifth work.jpg
--------------------------------------------------------------------------------
/src/assets/img/first work.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/first work.jpg
--------------------------------------------------------------------------------
/src/assets/img/footer-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/footer-bg.png
--------------------------------------------------------------------------------
/src/assets/img/second work.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/second work.jpg
--------------------------------------------------------------------------------
/src/assets/img/color-sharp2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/color-sharp2.png
--------------------------------------------------------------------------------
/src/assets/img/forth project.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/forth project.jpg
--------------------------------------------------------------------------------
/src/assets/img/project-img1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/project-img1.png
--------------------------------------------------------------------------------
/src/assets/img/project-img2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/project-img2.png
--------------------------------------------------------------------------------
/src/assets/img/project-img3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/img/project-img3.png
--------------------------------------------------------------------------------
/src/assets/font/CentraNo2-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/font/CentraNo2-Bold.ttf
--------------------------------------------------------------------------------
/src/assets/font/CentraNo2-Book.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/font/CentraNo2-Book.ttf
--------------------------------------------------------------------------------
/src/assets/font/CentraNo2-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/od1na/personal-website/HEAD/src/assets/font/CentraNo2-Medium.ttf
--------------------------------------------------------------------------------
/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render( );
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/src/assets/img/nav-icon2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/src/components/ProjectCard.js:
--------------------------------------------------------------------------------
1 | import { Col } from "react-bootstrap";
2 |
3 | export const ProjectCard = ({ title, description, imgUrl }) => {
4 | return (
5 |
6 |
7 |
8 |
9 |
{title}
10 | {description}
11 |
12 |
13 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/.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 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
25 | # environment variables
26 | .env
27 |
--------------------------------------------------------------------------------
/src/assets/img/arrow1.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/assets/img/arrow2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | const root = ReactDOM.createRoot(document.getElementById('root'));
8 | root.render(
9 |
10 |
11 |
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import logo from './logo.svg';
2 | import './App.css';
3 | import 'bootstrap/dist/css/bootstrap.min.css';
4 | import { NavBar } from "./components/NavBar";
5 | import { Banner } from "./components/Banner";
6 | import { Skills } from "./components/Skills";
7 | import { Projects } from "./components/Projects";
8 | import { Contact } from "./components/Contact";
9 | import { Footer } from "./components/Footer";
10 |
11 | function App() {
12 | return (
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | );
22 | }
23 |
24 | export default App;
25 |
--------------------------------------------------------------------------------
/src/assets/img/nav-icon1.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/components/MailchimpForm.js:
--------------------------------------------------------------------------------
1 | import MailchimpSubscribe from "react-mailchimp-subscribe";
2 | import { Newsletter } from "./Newsletter";
3 |
4 | export const MailchimpForm = () => {
5 | const postUrl = `${process.env.REACT_APP_MAILCHIMP_URL}?u=${process.env.REACT_APP_MAILCHIMP_U}&id=${process.env.REACT_APP_MAILCHIMP_ID}`;
6 |
7 | return (
8 | <>
9 | (
12 | subscribe(formData)}
16 | />
17 | )}
18 | />
19 | >
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/Footer.js:
--------------------------------------------------------------------------------
1 | import { Container, Row, Col } from "react-bootstrap";
2 | import { MailchimpForm } from "./MailchimpForm";
3 | import logo from "../assets/img/odina2.png";
4 | import navIcon1 from "../assets/img/nav-icon1.svg";
5 | import navIcon2 from "../assets/img/nav-icon2.svg";
6 | import navIcon3 from "../assets/img/nav-icon3.svg";
7 |
8 | export const Footer = () => {
9 | return (
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
23 | Thank you for attention
24 |
25 |
26 |
27 |
28 | )
29 | }
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Personal Portfolio Website in React
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 |
6 | Built using:
7 |
8 | - Front-end library: React
9 | - CSS framework: React-bootstrap
10 | - CSS animations library: Animate.css
11 |
12 | In the /personal-portfolio, you can run:
13 |
14 | ### `npm start`
15 |
16 | Runs the app in the development mode.\
17 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
18 |
19 | The page will reload when you make changes.\
20 | You may also see any lint errors in the console.
21 |
22 | ### `npm test`
23 |
24 | Launches the test runner in the interactive watch mode.\
25 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
26 |
27 | ### `npm run build`
28 |
29 | Builds the app for production to the `build` folder.\
30 | It correctly bundles React in production mode and optimizes the build for the best performance.
31 |
32 | The build is minified and the filenames include the hashes.\
33 | Your app is ready to be deployed!
34 |
35 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
36 |
--------------------------------------------------------------------------------
/src/assets/img/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "personal-portfolio",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.4",
7 | "@testing-library/react": "^13.3.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "animate.css": "^4.1.1",
10 | "bootstrap": "^5.1.3",
11 | "cors": "^2.8.5",
12 | "express": "^4.18.1",
13 | "nodemailer": "^6.7.5",
14 | "react": "^18.1.0",
15 | "react-bootstrap": "^2.4.0",
16 | "react-bootstrap-icons": "^1.8.2",
17 | "react-dom": "^18.1.0",
18 | "react-mailchimp-subscribe": "^2.1.3",
19 | "react-multi-carousel": "^2.8.1",
20 | "react-on-screen": "^2.1.1",
21 | "react-responsive-carousel": "^3.2.23",
22 | "react-router-dom": "^6.3.0",
23 | "react-router-hash-link": "^2.4.3",
24 | "react-scripts": "5.0.1",
25 | "web-vitals": "^2.1.4"
26 | },
27 | "scripts": {
28 | "start": "react-scripts start",
29 | "build": "react-scripts build",
30 | "test": "react-scripts test",
31 | "eject": "react-scripts eject"
32 | },
33 | "eslintConfig": {
34 | "extends": [
35 | "react-app",
36 | "react-app/jest"
37 | ]
38 | },
39 | "browserslist": {
40 | "production": [
41 | ">0.2%",
42 | "not dead",
43 | "not op_mini all"
44 | ],
45 | "development": [
46 | "last 1 chrome version",
47 | "last 1 firefox version",
48 | "last 1 safari version"
49 | ]
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const router = express.Router();
3 | const cors = require("cors");
4 | const nodemailer = require("nodemailer");
5 |
6 | // server used to send send emails
7 | const app = express();
8 | app.use(cors());
9 | app.use(express.json());
10 | app.use("/", router);
11 | app.listen(5000, () => console.log("Server Running"));
12 | console.log(process.env.EMAIL_USER);
13 | console.log(process.env.EMAIL_PASS);
14 |
15 | const contactEmail = nodemailer.createTransport({
16 | service: 'gmail',
17 | auth: {
18 | user: "********@gmail.com",
19 | pass: ""
20 | },
21 | });
22 |
23 | contactEmail.verify((error) => {
24 | if (error) {
25 | console.log(error);
26 | } else {
27 | console.log("Ready to Send");
28 | }
29 | });
30 |
31 | router.post("/contact", (req, res) => {
32 | const name = req.body.firstName + req.body.lastName;
33 | const email = req.body.email;
34 | const message = req.body.message;
35 | const phone = req.body.phone;
36 | const mail = {
37 | from: name,
38 | to: "********@gmail.com",
39 | subject: "Contact Form Submission - Portfolio",
40 | html: `Name: ${name}
41 | Email: ${email}
42 | Phone: ${phone}
43 | Message: ${message}
`,
44 | };
45 | contactEmail.sendMail(mail, (error) => {
46 | if (error) {
47 | res.json(error);
48 | } else {
49 | res.json({ code: 200, status: "Message Sent" });
50 | }
51 | });
52 | });
53 |
--------------------------------------------------------------------------------
/src/components/Newsletter.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 | import { Col, Row, Alert } from "react-bootstrap";
3 |
4 | export const Newsletter = ({ status, message, onValidated }) => {
5 | const [email, setEmail] = useState('');
6 |
7 | useEffect(() => {
8 | if (status === 'success') clearFields();
9 | }, [status])
10 |
11 | const handleSubmit = (e) => {
12 | e.preventDefault();
13 | email &&
14 | email.indexOf("@") > -1 &&
15 | onValidated({
16 | EMAIL: email
17 | })
18 | }
19 |
20 | const clearFields = () => {
21 | setEmail('');
22 | }
23 |
24 | return (
25 |
26 |
27 |
28 |
29 | Subscribe to our Newsletter & Never miss latest updates
30 | {status === 'sending' && Sending... }
31 | {status === 'error' && {message} }
32 | {status === 'success' && {message} }
33 |
34 |
35 |
41 |
42 |
43 |
44 |
45 | )
46 | }
47 |
--------------------------------------------------------------------------------
/src/assets/img/nav-icon3.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 | You need to enable JavaScript to run this app.
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/Skills.js:
--------------------------------------------------------------------------------
1 | import meter1 from "../assets/img/meter1.svg";
2 | import meter2 from "../assets/img/meter2.svg";
3 | import meter3 from "../assets/img/meter3.svg";
4 | import Carousel from 'react-multi-carousel';
5 | import 'react-multi-carousel/lib/styles.css';
6 | import arrow1 from "../assets/img/arrow1.svg";
7 | import arrow2 from "../assets/img/arrow2.svg";
8 | import colorSharp from "../assets/img/color-sharp.png"
9 |
10 | export const Skills = () => {
11 | const responsive = {
12 | superLargeDesktop: {
13 | // the naming can be any, depends on you.
14 | breakpoint: { max: 4000, min: 3000 },
15 | items: 5
16 | },
17 | desktop: {
18 | breakpoint: { max: 3000, min: 1024 },
19 | items: 3
20 | },
21 | tablet: {
22 | breakpoint: { max: 1024, min: 464 },
23 | items: 2
24 | },
25 | mobile: {
26 | breakpoint: { max: 464, min: 0 },
27 | items: 1
28 | }
29 | };
30 |
31 | return (
32 |
33 |
34 |
35 |
36 |
37 |
About Skills
38 |
I have learned different programming languages so far and as far as my skills are concerned
39 |
40 |
41 |
42 |
Web Development
43 |
44 |
45 |
46 |
English
47 |
48 |
49 |
50 |
Logo Design
51 |
52 |
53 |
54 |
Web Development
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | )
64 | }
65 |
--------------------------------------------------------------------------------
/src/components/NavBar.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 | import { Navbar, Nav, Container } from "react-bootstrap";
3 | import logo from '../assets/img/odina2.png';
4 | import navIcon1 from '../assets/img/nav-icon1.svg';
5 | import navIcon2 from '../assets/img/nav-icon2.svg';
6 | import navIcon3 from '../assets/img/nav-icon3.svg';
7 | import { HashLink } from 'react-router-hash-link';
8 | import {
9 | BrowserRouter as Router
10 | } from "react-router-dom";
11 |
12 | export const NavBar = () => {
13 |
14 | const [activeLink, setActiveLink] = useState('home');
15 | const [scrolled, setScrolled] = useState(false);
16 |
17 | useEffect(() => {
18 | const onScroll = () => {
19 | if (window.scrollY > 50) {
20 | setScrolled(true);
21 | } else {
22 | setScrolled(false);
23 | }
24 | }
25 |
26 | window.addEventListener("scroll", onScroll);
27 |
28 | return () => window.removeEventListener("scroll", onScroll);
29 | }, [])
30 |
31 | const onUpdateActiveLink = (value) => {
32 | setActiveLink(value);
33 | }
34 |
35 | return (
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | onUpdateActiveLink('home')}>Home
48 | onUpdateActiveLink('skills')}>Skills
49 | onUpdateActiveLink('projects')}>Projects
50 |
51 |
52 |
57 |
58 | Let’s Connect
59 |
60 |
61 |
62 |
63 |
64 |
65 | )
66 | }
67 |
--------------------------------------------------------------------------------
/src/assets/img/meter3.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/assets/img/meter1.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/assets/img/meter2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/components/Banner.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 | import { Container, Row, Col } from "react-bootstrap";
3 | import headerImg from "../assets/img/header-img.svg";
4 | import { ArrowRightCircle } from 'react-bootstrap-icons';
5 | import 'animate.css';
6 | import TrackVisibility from 'react-on-screen';
7 |
8 | export const Banner = () => {
9 | const [loopNum, setLoopNum] = useState(0);
10 | const [isDeleting, setIsDeleting] = useState(false);
11 | const [text, setText] = useState('');
12 | const [delta, setDelta] = useState(300 - Math.random() * 100);
13 | const [index, setIndex] = useState(1);
14 | const toRotate = [ "Web Developer", "Web Designer", "Team Leader" ];
15 | const period = 2000;
16 |
17 | useEffect(() => {
18 | let ticker = setInterval(() => {
19 | tick();
20 | }, delta);
21 |
22 | return () => { clearInterval(ticker) };
23 | }, [text])
24 |
25 | const tick = () => {
26 | let i = loopNum % toRotate.length;
27 | let fullText = toRotate[i];
28 | let updatedText = isDeleting ? fullText.substring(0, text.length - 1) : fullText.substring(0, text.length + 1);
29 |
30 | setText(updatedText);
31 |
32 | if (isDeleting) {
33 | setDelta(prevDelta => prevDelta / 2);
34 | }
35 |
36 | if (!isDeleting && updatedText === fullText) {
37 | setIsDeleting(true);
38 | setIndex(prevIndex => prevIndex - 1);
39 | setDelta(period);
40 | } else if (isDeleting && updatedText === '') {
41 | setIsDeleting(false);
42 | setLoopNum(loopNum + 1);
43 | setIndex(1);
44 | setDelta(500);
45 | } else {
46 | setIndex(prevIndex => prevIndex + 1);
47 | }
48 | }
49 |
50 | return (
51 |
52 |
53 |
54 |
55 |
56 | {({ isVisible }) =>
57 |
58 |
Welcome to my Portfolio
59 |
{`Hi! I'm Odina`} {text}
60 |
My fullname is Saidnazarova Odinanabonu. I'm 15 years old. I study 249-school in 10th grade.I am a front-end web developer. I can make the website more, more interactive with web animation
61 | I study at Web Brain Academy group G5. When I first came to web brain, I had no knowledge of programming.
62 | But now with the help of strong aspirations and teachers, my level of knowledge has greatly increased and I can freely create web site views that are used in our daily lives
63 |
64 |
console.log('connect')}>Let’s Connect
65 |
}
66 |
67 |
68 |
69 |
70 | {({ isVisible }) =>
71 |
72 |
73 |
}
74 |
75 |
76 |
77 |
78 |
79 | )
80 | }
81 |
--------------------------------------------------------------------------------
/src/components/Projects.js:
--------------------------------------------------------------------------------
1 | import { Container, Row, Col, Tab, Nav } from "react-bootstrap";
2 | import { ProjectCard } from "./ProjectCard";
3 | import projImg1 from "../assets/img/forth project.jpg";
4 | import projImg2 from "../assets/img/second work.jpg";
5 | import projImg3 from "../assets/img/project1.jpg";
6 | import projImg4 from "../assets/img/first work.jpg";
7 | import projImg5 from "../assets/img/fifth work.jpg";
8 | import projImg6 from "../assets/img/12345.jpg";
9 | import colorSharp2 from "../assets/img/color-sharp2.png";
10 | import 'animate.css';
11 | import TrackVisibility from 'react-on-screen';
12 |
13 | export const Projects = () => {
14 |
15 | const projects = [
16 | {
17 |
18 | description: "Design & Development",
19 | imgUrl: projImg1,
20 | },
21 | {
22 | description: "Design & Development",
23 | imgUrl: projImg2,
24 | },
25 | {
26 | description: "Design & Development",
27 | imgUrl: projImg3,
28 | },
29 | {
30 | description: "Design & Development",
31 | imgUrl: projImg4,
32 | },
33 | {
34 | description: "Design & Development",
35 | imgUrl: projImg5,
36 | },
37 | {
38 | description: "Design & Development",
39 | imgUrl: projImg6,
40 | },
41 | ];
42 |
43 | return (
44 |
45 |
46 |
47 |
48 |
49 | {({ isVisible }) =>
50 |
51 |
Projects
52 |
I show you to all the big and small websites I have done so far
53 |
54 |
55 |
56 | Tab 1
57 |
58 | {/*
59 | Tab 2
60 |
61 |
62 | Tab 3
63 | */}
64 |
65 |
66 |
67 |
68 | {
69 | projects.map((project, index) => {
70 | return (
71 |
75 | )
76 | })
77 | }
78 |
79 |
80 |
81 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque quam, quod neque provident velit, rem explicabo excepturi id illo molestiae blanditiis, eligendi dicta officiis asperiores delectus quasi inventore debitis quo.
82 |
83 |
84 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Cumque quam, quod neque provident velit, rem explicabo excepturi id illo molestiae blanditiis, eligendi dicta officiis asperiores delectus quasi inventore debitis quo.
85 |
86 |
87 |
88 |
}
89 |
90 |
91 |
92 |
93 |
94 |
95 | )
96 | }
97 |
--------------------------------------------------------------------------------
/src/components/Contact.js:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import { Container, Row, Col } from "react-bootstrap";
3 | import contactImg from "../assets/img/contact-img.svg";
4 | import 'animate.css';
5 | import TrackVisibility from 'react-on-screen';
6 |
7 | export const Contact = () => {
8 | const formInitialDetails = {
9 | firstName: '',
10 | lastName: '',
11 | email: '',
12 | phone: '',
13 | message: ''
14 | }
15 | const [formDetails, setFormDetails] = useState(formInitialDetails);
16 | const [buttonText, setButtonText] = useState('Send');
17 | const [status, setStatus] = useState({});
18 |
19 | const onFormUpdate = (category, value) => {
20 | setFormDetails({
21 | ...formDetails,
22 | [category]: value
23 | })
24 | }
25 |
26 | const handleSubmit = async (e) => {
27 | e.preventDefault();
28 | setButtonText("Sending...");
29 | let response = await fetch("http://localhost:5000/contact", {
30 | method: "POST",
31 | headers: {
32 | "Content-Type": "application/json;charset=utf-8",
33 | },
34 | body: JSON.stringify(formDetails),
35 | });
36 | setButtonText("Send");
37 | let result = await response.json();
38 | setFormDetails(formInitialDetails);
39 | if (result.code == 200) {
40 | setStatus({ succes: true, message: 'Message sent successfully'});
41 | } else {
42 | setStatus({ succes: false, message: 'Something went wrong, please try again later.'});
43 | }
44 | };
45 |
46 | return (
47 |
48 |
49 |
50 |
51 |
52 | {({ isVisible }) =>
53 |
54 | }
55 |
56 |
57 |
58 |
59 | {({ isVisible }) =>
60 |
61 |
Get In Touch
62 |
88 |
}
89 |
90 |
91 |
92 |
93 |
94 | )
95 | }
96 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | /************ Custom Font ************/
2 | @font-face {
3 | font-family: Centra;
4 | src: url('./assets/font/CentraNo2-Bold.ttf');
5 | font-weight: 700;
6 | }
7 | @font-face {
8 | font-family: Centra;
9 | src: url('./assets/font/CentraNo2-Medium.ttf');
10 | font-weight: 500;
11 | }
12 | @font-face {
13 | font-family: Centra;
14 | src: url('./assets/font/CentraNo2-Book.ttf');
15 | font-weight: 400;
16 | }
17 |
18 | /************ Default Css ************/
19 | * {
20 | margin: 0;
21 | padding: 0;
22 | box-sizing: border-box;
23 | }
24 |
25 | html {
26 | scroll-behavior: smooth;
27 | scroll-padding-top: 75px;
28 | }
29 |
30 | body {
31 | font-weight: 400;
32 | overflow-x: hidden;
33 | position: relative;
34 | background-color: #121212 !important;
35 | color: #fff !important;
36 | font-family: 'Centra', sans-serif !important;
37 | }
38 |
39 | h1, h2, h3, h4, h5, h6 {
40 | margin: 0;
41 | padding: 0;
42 | line-height: normal;
43 | }
44 |
45 | p, a, li, button, ul {
46 | margin: 0;
47 | padding: 0;
48 | line-height: normal;
49 | text-decoration: none;
50 | }
51 |
52 | a:hover {
53 | text-decoration: none;
54 | }
55 |
56 | img {
57 | width: 100%;
58 | height: auto;
59 | }
60 |
61 | button {
62 | border: 0;
63 | background-color: transparent;
64 | }
65 |
66 | input:focus, textarea:focus, select:focus {
67 | outline: none;
68 | }
69 |
70 | @media (min-width:1700px) {
71 | main .container {
72 | max-width: 100%;
73 | padding: 0 150px;
74 | }
75 | }
76 |
77 | p.success {
78 | color: green;
79 | }
80 |
81 | p.danger {
82 | color: red;
83 | }
84 | /************ Navbar Css ************/
85 | nav.navbar {
86 | padding: 18px 0;
87 | position: fixed;
88 | width: 100%;
89 | top: 0;
90 | z-index: 9999;
91 | transition: 0.32s ease-in-out;
92 | }
93 | nav.navbar.scrolled {
94 | padding: 0px 0;
95 | background-color: #121212;
96 | }
97 | nav.navbar a.navbar-brand {
98 | width: 9%;
99 | }
100 | nav.navbar .navbar-nav .nav-link.navbar-link {
101 | font-weight: 400;
102 | color: #fff !important;
103 | letter-spacing: 0.8px;
104 | padding: 0 25px;
105 | font-size: 18px;
106 | opacity: 0.75;
107 | }
108 | nav.navbar .navbar-nav a.nav-link.navbar-link:hover,
109 | nav.navbar .navbar-nav a.nav-link.navbar-link.active {
110 | opacity: 1;
111 | }
112 | span.navbar-text {
113 | display: flex;
114 | align-items: center;
115 | }
116 | .social-icon {
117 | display: inline-block;
118 | margin-left: 14px;
119 | }
120 | .social-icon a {
121 | width: 42px;
122 | height: 42px;
123 | background: rgba(217, 217, 217, 0.1);
124 | display: inline-flex;
125 | border-radius: 50%;
126 | margin-right: 6px;
127 | align-items: center;
128 | justify-content: center;
129 | line-height: 1;
130 | border: 1px solid rgba(255, 255, 255, 0.5);
131 | }
132 | .social-icon a::before {
133 | content: "";
134 | width: 42px;
135 | height: 42px;
136 | position: absolute;
137 | background-color: #ffffff;
138 | border-radius: 50%;
139 | transform: scale(0);
140 | transition: 0.3s ease-in-out;
141 | }
142 | .social-icon a:hover::before {
143 | transform: scale(1);
144 | }
145 | .social-icon a img {
146 | width: 40%;
147 | z-index: 1;
148 | transition: 0.3s ease-in-out;
149 | }
150 | .social-icon a:hover img {
151 | filter: brightness(0) saturate(100%) invert(0%) sepia(7%) saturate(98%) hue-rotate(346deg) brightness(95%) contrast(86%);
152 | }
153 | .navbar-text button {
154 | font-weight: 700;
155 | color: #fff;
156 | border: 1px solid #fff;
157 | padding: 18px 34px;
158 | font-size: 18px;
159 | margin-left: 18px;
160 | position: relative;
161 | background-color: transparent;
162 | transition: 0.3s ease-in-out;
163 | }
164 | .navbar-text button span {
165 | z-index: 1;
166 | }
167 | .navbar-text button::before {
168 | content: "";
169 | width: 0%;
170 | height: 100%;
171 | position: absolute;
172 | background-color: #fff;
173 | left: 0;
174 | top: 0;
175 | z-index: -1;
176 | transition: 0.3s ease-in-out;
177 | }
178 | .navbar-text button:hover {
179 | color: #121212;
180 | }
181 | .navbar-text button:hover::before {
182 | content: "";
183 | width: 100%;
184 | height: 100%;
185 | position: absolute;
186 | }
187 | nav.navbar .navbar-toggler:active,
188 | nav.navbar .navbar-toggler:focus {
189 | outline: none;
190 | box-shadow: none;
191 | }
192 | nav.navbar .navbar-toggler-icon {
193 | width: 24px;
194 | height: 17px;
195 | background-image: none;
196 | position: relative;
197 | border-bottom: 2px solid #fff;
198 | transition: all 300ms linear;
199 | top: -2px;
200 | }
201 | nav.navbar .navbar-toggler-icon:focus {
202 | border-bottom: 2px solid #fff;
203 | }
204 | nav.navbar .navbar-toggler-icon:after,
205 | nav.navbar .navbar-toggler-icon:before {
206 | width: 24px;
207 | position: absolute;
208 | height: 2px;
209 | background-color: #fff;
210 | top: 0;
211 | left: 0;
212 | content: '';
213 | z-index: 2;
214 | transition: all 300ms linear;
215 | }
216 | nav.navbar .navbar-toggler-icon:after {
217 | top: 8px;
218 | }
219 | nav.navbar .navbar-toggler[aria-expanded="true"] .navbar-toggler-icon:after {
220 | transform: rotate(45deg);
221 | background-color: #fff;
222 | height: 2px;
223 | }
224 | nav.navbar .navbar-toggler[aria-expanded="true"] .navbar-toggler-icon:before {
225 | transform: translateY(8px) rotate(-45deg);
226 | background-color: #fff;
227 | height: 2px;
228 | }
229 | nav.navbar .navbar-toggler[aria-expanded="true"] .navbar-toggler-icon {
230 | border-color: transparent;
231 | }
232 |
233 | /************ Banner Css ************/
234 | .banner {
235 | margin-top: 0;
236 | padding: 260px 0 100px 0;
237 | background-image: url('./assets/img/banner-bg.png');
238 | background-position: top center;
239 | background-size: cover;
240 | background-repeat: no-repeat;
241 | }
242 | .banner .tagline {
243 | font-weight: 700;
244 | letter-spacing: 0.8px;
245 | padding: 8px 10px;
246 | background: linear-gradient(90.21deg, rgba(170, 54, 124, 0.5) -5.91%, rgba(74, 47, 189, 0.5) 111.58%);
247 | border: 1px solid rgba(255, 255, 255, 0.5);
248 | font-size: 20px;
249 | margin-bottom: 16px;
250 | display: inline-block;
251 | }
252 | .banner h1 {
253 | font-size: 65px;
254 | font-weight: 700;
255 | letter-spacing: 0.8px;
256 | line-height: 1;
257 | margin-bottom: 20px;
258 | display: block;
259 | }
260 | .banner p {
261 | color: #B8B8B8;
262 | font-size: 18px;
263 | letter-spacing: 0.8px;
264 | line-height: 1.5em;
265 | width: 96%;
266 | }
267 | .banner button {
268 | color: #fff;
269 | font-weight: 700;
270 | font-size: 20px;
271 | margin-top: 60px;
272 | letter-spacing: 0.8px;
273 | display: flex;
274 | align-items: center;
275 | }
276 | .banner button svg {
277 | font-size: 25px;
278 | margin-left: 10px;
279 | transition: 0.3s ease-in-out;
280 | line-height: 1;
281 | }
282 | .banner button:hover svg {
283 | margin-left: 25px;
284 | }
285 | .banner img {
286 | animation: updown 3s linear infinite;
287 | }
288 | @keyframes updown {
289 | 0% {
290 | transform: translateY(-20px);
291 | }
292 | 50% {
293 | transform: translateY(20px);
294 | }
295 | 100% {
296 | transform: translateY(-20px);
297 | }
298 | }
299 | .txt-rotate > .wrap {
300 | border-right: 0.08em solid #666;
301 | }
302 |
303 | /************ Skills Css ************/
304 | .skill {
305 | padding: 0 0 50px 0;
306 | position: relative;
307 | }
308 | .skill-bx {
309 | background: #151515;
310 | border-radius: 64px;
311 | text-align: center;
312 | padding: 60px 50px;
313 | margin-top: -60px;
314 | }
315 | .skill h2 {
316 | font-size: 45px;
317 | font-weight: 700;
318 | }
319 | .skill p {
320 | color: #B8B8B8;
321 | font-size: 18px;
322 | letter-spacing: 0.8px;
323 | line-height: 1.5em;
324 | margin: 14px 0 75px 0;
325 | }
326 | .skill-slider {
327 | width: 80%;
328 | margin: 0 auto;
329 | position: relative;
330 | }
331 | .skill-slider .item img {
332 | width: 50%;
333 | margin: 0 auto 15px auto;
334 | }
335 | .background-image-left {
336 | top: 28%;
337 | position: absolute;
338 | bottom: 0;
339 | width: 40%;
340 | z-index: -4;
341 | }
342 |
343 | /************ Projects Css ************/
344 | .project {
345 | padding: 80px 0;
346 | position: relative;
347 | background-color: black;
348 | }
349 | .project h2 {
350 | font-size: 45px;
351 | font-weight: 700;
352 | text-align: center;
353 | }
354 | .project p {
355 | color: #B8B8B8;
356 | font-size: 18px;
357 | letter-spacing: 0.8px;
358 | line-height: 1.5em;
359 | margin: 14px auto 30px auto;
360 | text-align: center;
361 | width: 56%;
362 | }
363 | .project .nav.nav-pills {
364 | width: 72%;
365 | margin: 0 auto;
366 | border-radius: 50px;
367 | background-color: rgb(255 255 255 / 10%);
368 | overflow: hidden;
369 | }
370 | .project .nav.nav-pills .nav-item {
371 | width: 33.33333%;
372 | }
373 | .project .nav.nav-pills .nav-link {
374 | background-color: transparent;
375 | border-radius: 0;
376 | padding: 17px 0;
377 | color: #fff;
378 | width: 100%;
379 | font-size: 17px;
380 | letter-spacing: 0.8px;
381 | font-weight: 500;
382 | position: relative;
383 | transition: 0.3s ease-in-out;
384 | text-align: center;
385 | z-index: 0;
386 | }
387 | .project .nav.nav-pills .nav-link::before {
388 | content: "";
389 | position: absolute;
390 | width: 0;
391 | height: 100%;
392 | background: linear-gradient(90.21deg, #AA367C -5.91%, #4A2FBD 111.58%);
393 | top: 0;
394 | left: 0;
395 | z-index: -1;
396 | transition: 0.3s ease-in-out;
397 | }
398 | .project .nav.nav-pills .nav-link.active::before {
399 | width: 100% !important;
400 | }
401 | .project .nav.nav-pills .nav-link.active {
402 | border: 1px solid rgba(255, 255, 255, 1);
403 | }
404 | .nav-link#projects-tabs-tab-first {
405 | border: 1px solid rgba(255, 255, 255, 0.5);
406 | border-radius: 55px 0px 0px 55px;
407 | }
408 | .nav-link#projects-tabs-tab-second {
409 | border-top: 1px solid rgba(255, 255, 255, 0.5);
410 | border-bottom: 1px solid rgba(255, 255, 255, 0.5);
411 | }
412 | .nav-link#projects-tabs-tab-third {
413 | border: 1px solid rgba(255, 255, 255, 0.5);
414 | border-radius: 0 55px 55px 0;
415 | }
416 | .proj-imgbx {
417 | position: relative;
418 | border-radius: 30px;
419 | overflow: hidden;
420 | margin-bottom: 24px;
421 | }
422 | .proj-imgbx::before {
423 | content: "";
424 | background: linear-gradient(90.21deg, #AA367C -5.91%, #4A2FBD 111.58%);
425 | opacity: 0.85;
426 | position: absolute;
427 | width: 100%;
428 | height: 0;
429 | transition: 0.4s ease-in-out;
430 | }
431 | .proj-imgbx:hover::before {
432 | height: 100%;
433 | }
434 | .proj-txtx {
435 | position: absolute;
436 | text-align: center;
437 | top: 65%;
438 | left: 50%;
439 | transform: translate(-50%, -50%);
440 | transition: 0.5s ease-in-out;
441 | opacity: 0;
442 | width: 100%;
443 | }
444 | .proj-imgbx:hover .proj-txtx {
445 | top: 50%;
446 | opacity: 1;
447 | }
448 | .proj-txtx h4 {
449 | font-size: 30px;
450 | font-weight: 700;
451 | letter-spacing: 0.8px;
452 | line-height: 1.1em;
453 | }
454 | .proj-txtx span {
455 | font-style: italic;
456 | font-weight: 400;
457 | font-size: 15px;
458 | letter-spacing: 0.8px;
459 | }
460 | .background-image-right {
461 | top: 20%;
462 | position: absolute;
463 | bottom: 0;
464 | width: 35%;
465 | right: 0;
466 | z-index: -4;
467 | }
468 |
469 | /************ Projects Css ************/
470 | .contact {
471 | background: linear-gradient(90.21deg, #AA367C -5.91%, #4A2FBD 111.58%);
472 | padding: 60px 0 200px 0;
473 | }
474 | .contact img {
475 | width: 92%;
476 | }
477 | .contact h2 {
478 | font-size: 45px;
479 | font-weight: 700;
480 | margin-bottom: 30px;
481 | }
482 | .contact form input, .contact form textarea {
483 | width: 100%;
484 | background: rgba(255, 255, 255, 0.1);
485 | border: 1px solid rgba(255, 255, 255, 0.5);
486 | border-radius: 20px;
487 | color: #fff;
488 | margin: 0 0 8px 0;
489 | padding: 18px 26px;
490 | font-weight: 500;
491 | font-size: 18px;
492 | letter-spacing: 0.8px;
493 | transition: 0.3s ease-in-out;
494 | }
495 | .contact form input:focus, .contact form textarea:focus {
496 | background: rgba(255, 255, 255, 1);
497 | color: #121212;
498 | }
499 | .contact form input::placeholder, .contact form textarea::placeholder {
500 | font-size: 16px;
501 | font-weight: 400;
502 | color: #fff;
503 | }
504 | .contact form input:focus::placeholder, .contact form textarea:focus::placeholder {
505 | color: #121212;
506 | opacity: 0.8;
507 | }
508 | .contact form button {
509 | font-weight: 700;
510 | color: #000;
511 | background-color: #fff;
512 | padding: 14px 48px;
513 | font-size: 18px;
514 | margin-top: 25px;
515 | border-radius: 0;
516 | position: relative;
517 | transition: 0.3s ease-in-out;
518 | }
519 | .contact form button span {
520 | z-index: 1;
521 | position: relative;
522 | }
523 | .contact form button:hover {
524 | color: #fff;
525 | }
526 | .contact form button::before {
527 | content: "";
528 | background: #121212;
529 | width: 0;
530 | height: 100%;
531 | position: absolute;
532 | top: 0;
533 | left: 0;
534 | z-index: 0;
535 | transition: 0.3s ease-in-out;
536 | }
537 | .contact form button:hover::before {
538 | width: 100%;
539 | }
540 |
541 | /************ Footer Css ************/
542 | .footer {
543 | padding: 0 0 50px 0;
544 | background-image: url('./assets/img/footer-bg.png');
545 | background-position: center center;
546 | background-size: cover;
547 | background-repeat: no-repeat;
548 | }
549 | .newsletter-bx {
550 | background: #FFFFFF;
551 | border-radius: 55px;
552 | color: #121212;
553 | padding: 85px 125px;
554 | margin-bottom: 80px;
555 | margin-top: -122px;
556 | }
557 | .newsletter-bx h3 {
558 | font-weight: 700;
559 | letter-spacing: 0.5px;
560 | line-height: 1.2em;
561 | }
562 | .new-email-bx {
563 | background: #fff;
564 | padding: 5px;
565 | border-radius: 20px;
566 | position: relative;
567 | z-index: 0;
568 | display: flex;
569 | align-items: center;
570 | }
571 | .new-email-bx::before {
572 | content: "";
573 | background: linear-gradient(90.21deg, #AA367C -5.91%, #4A2FBD 111.58%);
574 | border-radius: 20px;
575 | position: absolute;
576 | z-index: -1;
577 | top: -1px;
578 | left: -1px;
579 | bottom: -1px;
580 | right: -1px;
581 | }
582 | .new-email-bx::after {
583 | content: "";
584 | background: #fff;
585 | border-radius: 20px;
586 | position: absolute;
587 | z-index: -1;
588 | top: 0;
589 | left: 0;
590 | bottom: 0;
591 | right: 0;
592 | }
593 | .new-email-bx input {
594 | width: 100%;
595 | color: #121212;
596 | font-weight: 500;
597 | background: transparent;
598 | border: 0;
599 | padding: 0 15px;
600 | }
601 | .new-email-bx button {
602 | background: linear-gradient(90.21deg, #AA367C -5.91%, #4A2FBD 111.58%);
603 | padding: 20px 65px;
604 | color: #fff;
605 | font-weight: 500;
606 | letter-spacing: 0.5px;
607 | border-radius: 18px;
608 | }
609 | .footer img {
610 | width: 26%;
611 | }
612 | .footer p {
613 | font-weight: 400;
614 | font-size: 14px;
615 | color: #B8B8B8;
616 | letter-spacing: 0.5px;
617 | margin-top: 20px;
618 | }
619 |
--------------------------------------------------------------------------------
/src/assets/img/contact-img.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 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
--------------------------------------------------------------------------------