├── 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 | Logo 16 | 17 | 18 |
19 | Icon 20 | Icon 21 | Icon 22 |
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 |
36 |
37 | setEmail(e.target.value)} placeholder="Email Address" /> 38 | 39 |
40 |
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 | 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 | Image 42 |
Web Development
43 |
44 |
45 | Image 46 |
English
47 |
48 |
49 | Image 50 |
Logo Design
51 |
52 |
53 | Image 54 |
Web Development
55 |
56 |
57 |
58 |
59 |
60 |
61 | Image 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 | Logo 41 | 42 | 43 | 44 | 45 | 46 | 51 | 52 |
53 | 54 | 55 | 56 |
57 | 58 | 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 | 65 |
} 66 |
67 | 68 | 69 | 70 | {({ isVisible }) => 71 |
72 | Header Img 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 | 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 | Contact Us 54 | } 55 | 56 | 57 | 58 | 59 | {({ isVisible }) => 60 |
61 |

Get In Touch

62 |
63 | 64 | 65 | onFormUpdate('firstName', e.target.value)} /> 66 | 67 | 68 | onFormUpdate('lastName', e.target.value)}/> 69 | 70 | 71 | onFormUpdate('email', e.target.value)} /> 72 | 73 | 74 | onFormUpdate('phone', e.target.value)}/> 75 | 76 | 77 | 78 | 79 | 80 | { 81 | status.message && 82 | 83 |

{status.message}

84 | 85 | } 86 |
87 |
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 | --------------------------------------------------------------------------------