├── .env.example
├── .gitignore
├── LICENSE
├── README.md
├── eslint.config.js
├── index.html
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
├── arrow-up.png
├── conestoga_logo.png
├── fonts
│ ├── Inter-VariableFont_opsz,wght.ttf
│ └── Roboto-VariableFont_wdth,wght.ttf
├── icons
│ ├── c-sharp.svg
│ ├── css-3.svg
│ ├── eslint.svg
│ ├── github-icon.svg
│ ├── html-5.svg
│ ├── javascript.svg
│ ├── markdown.svg
│ ├── nextjs.svg
│ ├── prettier.svg
│ ├── python.svg
│ ├── react.svg
│ ├── redux.svg
│ ├── tailwindcss-icon.svg
│ ├── threejs.svg
│ ├── typescript-icon.svg
│ ├── unity.svg
│ ├── vercel.svg
│ └── vite.svg
├── logo.png
├── logo.svg
├── projects
│ ├── KarateGalaxy_Main.png
│ ├── Portfolio_Main.png
│ ├── ThreeRun_Main_Screen.png
│ └── skif.png
├── resume_anzhelika_kostyuk.pdf
└── varlab_logo.png
├── src
├── App.css
├── App.jsx
├── components
│ ├── CursorGlow.jsx
│ ├── Footer.jsx
│ ├── Loader.jsx
│ ├── MouseScroll.jsx
│ ├── Navbar.jsx
│ ├── ProjectCard.jsx
│ ├── SkillsSphere.jsx
│ └── StarField.jsx
├── constants
│ └── data.ts
├── main.jsx
└── sections
│ ├── Contact.jsx
│ ├── Experience.jsx
│ ├── Hero.jsx
│ ├── Projects.jsx
│ └── Skills.jsx
├── tailwind.config.js
└── vite.config.js
/.env.example:
--------------------------------------------------------------------------------
1 | VITE_EMAILJS_SERVICE_ID=your_service_id
2 | VITE_EMAILJS_TEMPLATE_ID=your_template_id
3 | VITE_EMAILJS_PUBLIC_KEY=your_public_key
4 | VITE_EMAILJS_TO_NAME=YourName
5 | VITE_EMAILJS_TO_EMAIL=you@example.com
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 | .env
15 |
16 | # Editor directories and files
17 | .vscode/*
18 | !.vscode/extensions.json
19 | .idea
20 | .DS_Store
21 | *.suo
22 | *.ntvs*
23 | *.njsproj
24 | *.sln
25 | *.sw?
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Anzhelika Kostyuk
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
👋 Welcome to My Portfolio Website
3 |
4 |
5 |
6 |
7 |
8 |
9 | A showcase of my skills, projects, and expertise as a Software Developer.
10 | This website is built using modern web technologies and includes interactive 3D elements to create an engaging experience.
11 |
12 |
13 | 🔗 Live Demo:
14 |
15 | Anzhelika Kostyuk
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | ### 🎯 **About This Project**
25 | A professional portfolio and personal branding site that brings my developer journey to life with interactive 3D elements and smooth animations. It features clean UI/UX and highlights my work and skills through modern web tech.
26 |
27 | ### 🔥 **Key Highlights**
28 | ✅ **3D Interactivity** – Built with **React Three Fiber & Three.js** for immersive 3D experiences.
29 | ✅ **Performance Optimized** – Fast load times with optimized assets and lazy loading.
30 | ✅ **Fully Responsive** – Works across desktops, tablets, and mobile devices.
31 | ✅ **Modern UI/UX** – Styled with **Tailwind CSS** for a clean and professional look.
32 | ✅ **Easy Navigation** – Smooth scrolling and intuitive layout for better user experience.
33 | ✅ **Hosted on GitHub Pages** – Easily accessible with continuous deployment.
34 |
35 | ---
36 |
37 | ### 🛠️ **Tech Stack & Tools**
38 |
39 | **Frontend:**
40 | 
41 | 
42 | 
43 | 
44 | **3D Graphics:**
45 | 
46 | 
47 | 
48 | **Styling:**
49 | 
50 | 
51 | **Build Tool:**
52 | 
53 | **Code quality and Formatting:**
54 | 
55 | 
56 | **Version Control:**
57 | 
58 | 
59 | **Hosting:**
60 | 
61 |
62 | ---
63 |
64 | ### 🚀 Getting Started
65 | To run this project locally, follow these steps:
66 |
67 | ### Prerequisites
68 | - [Node.js](https://nodejs.org/) installed
69 | - Git installed
70 |
71 | ### Installation
72 | 1. **Clone the repository**
73 | ```sh
74 | git clone https://github.com/A-coderr/three_portfolio.git
75 | cd three_portfolio
76 | ```
77 | 2. **Install dependencies**
78 | ```sh
79 | npm install
80 | ```
81 | 3. **Run the development server**
82 | ```sh
83 | npm run dev
84 | ```
85 | ---
86 |
87 | ### 📜 License
88 | This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
89 |
90 |
91 |
92 |
93 |
📩 Connect with Me ⬇️
94 |
I’m actively looking for new opportunities! If you're a recruiter or hiring manager, feel free to reach out.
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js'
2 | import globals from 'globals'
3 | import react from 'eslint-plugin-react'
4 | import reactHooks from 'eslint-plugin-react-hooks'
5 | import reactRefresh from 'eslint-plugin-react-refresh'
6 |
7 | export default [
8 | { ignores: ['dist'] },
9 | {
10 | files: ['**/*.{js,jsx}'],
11 | languageOptions: {
12 | ecmaVersion: 2020,
13 | globals: globals.browser,
14 | parserOptions: {
15 | ecmaVersion: 'latest',
16 | ecmaFeatures: { jsx: true },
17 | sourceType: 'module',
18 | },
19 | },
20 | settings: { react: { version: '18.3' } },
21 | plugins: {
22 | react,
23 | 'react-hooks': reactHooks,
24 | 'react-refresh': reactRefresh,
25 | },
26 | rules: {
27 | ...js.configs.recommended.rules,
28 | ...react.configs.recommended.rules,
29 | ...react.configs['jsx-runtime'].rules,
30 | ...reactHooks.configs.recommended.rules,
31 | 'react/jsx-no-target-blank': 'off',
32 | 'react/no-unknown-property' : 'off',
33 | 'react-refresh/only-export-components': [
34 | 'warn',
35 | { allowConstantExport: true },
36 | ],
37 | },
38 | },
39 | ]
40 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Anzhelika Kostyuk
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "three_portfolio",
3 | "private": true,
4 | "version": "1.2.3",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint .",
10 | "preview": "vite preview",
11 | "deploy": "gh-pages -d ./dist"
12 | },
13 | "dependencies": {
14 | "@emailjs/browser": "^4.4.1",
15 | "@emotion/react": "^11.13.3",
16 | "@emotion/styled": "^11.13.0",
17 | "@fortawesome/fontawesome-svg-core": "^6.6.0",
18 | "@fortawesome/free-brands-svg-icons": "^6.6.0",
19 | "@fortawesome/free-regular-svg-icons": "^6.6.0",
20 | "@fortawesome/free-solid-svg-icons": "^6.6.0",
21 | "@fortawesome/react-fontawesome": "^0.2.2",
22 | "@mui/icons-material": "^6.1.0",
23 | "@mui/material": "^6.1.0",
24 | "@react-three/drei": "^9.114.0",
25 | "@react-three/fiber": "^8.17.9",
26 | "emailjs": "^4.0.3",
27 | "framer-motion": "^12.5.0",
28 | "hugeicons-react": "^0.3.0",
29 | "leva": "^0.9.35",
30 | "react": "^18.3.1",
31 | "react-dom": "^18.3.1",
32 | "react-icons": "^5.3.0",
33 | "react-motion": "^0.5.2",
34 | "react-responsive": "^10.0.0",
35 | "react-social-icons": "^6.22.0",
36 | "react-spring-3d-carousel": "^1.3.4",
37 | "react-text-gradients": "^1.0.2",
38 | "react-vertical-timeline-component": "^3.5.3",
39 | "three": "^0.168.0",
40 | "uuid": "^11.1.0"
41 | },
42 | "devDependencies": {
43 | "@eslint/js": "^9.9.0",
44 | "@types/react": "^18.3.3",
45 | "@types/react-dom": "^18.3.0",
46 | "@vitejs/plugin-react": "^4.3.1",
47 | "autoprefixer": "^10.4.20",
48 | "eslint": "^9.9.0",
49 | "eslint-plugin-react": "^7.35.0",
50 | "eslint-plugin-react-hooks": "^5.1.0-rc.0",
51 | "eslint-plugin-react-refresh": "^0.4.9",
52 | "gh-pages": "^6.3.0",
53 | "globals": "^15.9.0",
54 | "postcss": "^8.4.45",
55 | "tailwindcss": "^3.4.11",
56 | "vite": "^5.4.1"
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/public/arrow-up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3ss127/threejs-portfolio-sample/dc70a8acb5346350b049086d61f6e402fa2fc09d/public/arrow-up.png
--------------------------------------------------------------------------------
/public/conestoga_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3ss127/threejs-portfolio-sample/dc70a8acb5346350b049086d61f6e402fa2fc09d/public/conestoga_logo.png
--------------------------------------------------------------------------------
/public/fonts/Inter-VariableFont_opsz,wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3ss127/threejs-portfolio-sample/dc70a8acb5346350b049086d61f6e402fa2fc09d/public/fonts/Inter-VariableFont_opsz,wght.ttf
--------------------------------------------------------------------------------
/public/fonts/Roboto-VariableFont_wdth,wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3ss127/threejs-portfolio-sample/dc70a8acb5346350b049086d61f6e402fa2fc09d/public/fonts/Roboto-VariableFont_wdth,wght.ttf
--------------------------------------------------------------------------------
/public/icons/c-sharp.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 | C#
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/public/icons/css-3.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/public/icons/eslint.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/public/icons/github-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/public/icons/html-5.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/public/icons/javascript.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/public/icons/markdown.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/public/icons/nextjs.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 | Next.js
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/public/icons/prettier.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 |
--------------------------------------------------------------------------------
/public/icons/python.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/public/icons/react.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/public/icons/redux.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/public/icons/tailwindcss-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/public/icons/threejs.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 | threejs
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/public/icons/typescript-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 | TypeScript
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/public/icons/unity.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/public/icons/vercel.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/public/icons/vite.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3ss127/threejs-portfolio-sample/dc70a8acb5346350b049086d61f6e402fa2fc09d/public/logo.png
--------------------------------------------------------------------------------
/public/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/public/projects/KarateGalaxy_Main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3ss127/threejs-portfolio-sample/dc70a8acb5346350b049086d61f6e402fa2fc09d/public/projects/KarateGalaxy_Main.png
--------------------------------------------------------------------------------
/public/projects/Portfolio_Main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3ss127/threejs-portfolio-sample/dc70a8acb5346350b049086d61f6e402fa2fc09d/public/projects/Portfolio_Main.png
--------------------------------------------------------------------------------
/public/projects/ThreeRun_Main_Screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3ss127/threejs-portfolio-sample/dc70a8acb5346350b049086d61f6e402fa2fc09d/public/projects/ThreeRun_Main_Screen.png
--------------------------------------------------------------------------------
/public/projects/skif.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3ss127/threejs-portfolio-sample/dc70a8acb5346350b049086d61f6e402fa2fc09d/public/projects/skif.png
--------------------------------------------------------------------------------
/public/resume_anzhelika_kostyuk.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3ss127/threejs-portfolio-sample/dc70a8acb5346350b049086d61f6e402fa2fc09d/public/resume_anzhelika_kostyuk.pdf
--------------------------------------------------------------------------------
/public/varlab_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3ss127/threejs-portfolio-sample/dc70a8acb5346350b049086d61f6e402fa2fc09d/public/varlab_logo.png
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | @font-face {
6 | font-family: 'Inter-VariableFont_opsz,wght';
7 | font-weight: normal;
8 | font-style: normal;
9 | src: url('/fonts/Inter-VariableFont_opsz,wght.ttf') format('truetype');
10 | }
11 |
12 | @font-face {
13 | font-family: 'Roboto-VariableFont_wdth,wght';
14 | font-weight: normal;
15 | font-style: normal;
16 | src: url('/fonts/Roboto-VariableFont_wdth,wght.ttf') format('truetype');
17 | }
18 |
19 | body {
20 | font-family: 'Roboto-VariableFont_wdth,wght', sans-serif;
21 | background-color: #1a191e;
22 | margin: 0;
23 | padding: 0;
24 | }
25 |
26 | h1, h2, h3, h4, h5, h6 {
27 | font-family: 'Inter-VariableFont_opsz,wght';
28 | }
29 |
30 | * {
31 | scroll-behavior: smooth;
32 | }
33 |
34 | @keyframes scroll {
35 | 0% { opacity: 0; }
36 | 10% { transform: translateY(0); opacity: 1; }
37 | 100% { transform: translateY(15px); opacity: 0; }
38 | }
39 | .animate-scroll {
40 | animation: scroll 2.2s cubic-bezier(.15,.41,.69,.94) infinite;
41 | }
--------------------------------------------------------------------------------
/src/App.jsx:
--------------------------------------------------------------------------------
1 | import "./App.css";
2 | import Navbar from "./components/Navbar";
3 | import Hero from "./sections/Hero";
4 | import Experience from "./sections/Experience";
5 | import Skills from "./sections/Skills";
6 | import Projects from "./sections/Projects";
7 | import Contact from "./sections/Contact";
8 | import StarCanvas from "./components/StarField";
9 | import Footer from "./components/Footer";
10 | import CursorGlow from "./components/CursorGlow";
11 |
12 | export default function App() {
13 | return (
14 | <>
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | >
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/src/components/CursorGlow.jsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 |
3 | const CursorGlow = () => {
4 | const [position, setPosition] = useState({ x: 0, y: 0 });
5 |
6 | useEffect(() => {
7 | const handleMouseMove = (e) => {
8 | setPosition({ x: e.clientX, y: e.clientY });
9 | };
10 |
11 | window.addEventListener("mousemove", handleMouseMove);
12 | return () => window.removeEventListener("mousemove", handleMouseMove);
13 | }, []);
14 |
15 | return (
16 |
24 | );
25 | };
26 |
27 | export default CursorGlow;
28 |
--------------------------------------------------------------------------------
/src/components/Footer.jsx:
--------------------------------------------------------------------------------
1 | import { motion } from "framer-motion";
2 | import { SocialIcon } from "react-social-icons";
3 |
4 | const Footer = () => {
5 | return (
6 |
13 |
14 | {/* Separator Line */}
15 |
21 |
22 |
23 | {/* Left Section - Branding & Resume Button */}
24 |
29 |
36 | Download Resume
37 |
38 |
39 |
40 | {/* Right Section - Social Icons */}
41 |
42 | {[
43 | "https://github.com/A-coderr",
44 | "http://www.linkedin.com/in/anzhelika-kostyuk-a2b388194",
45 | "https://www.instagram.com/a_akcio/?hl=en",
46 | "https://www.facebook.com/profile.php?id=100011369881132",
47 | ].map((url, index) => (
48 |
53 |
59 |
60 | ))}
61 |
62 |
63 |
64 | {/* Copyright */}
65 |
66 | © {new Date().getFullYear()} Anzhelika Kostyuk. All rights reserved.
67 |
68 |
69 |
70 | );
71 | };
72 |
73 | export default Footer;
74 |
--------------------------------------------------------------------------------
/src/components/Loader.jsx:
--------------------------------------------------------------------------------
1 | import { Html, useProgress } from "@react-three/drei";
2 |
3 | const Loader = () => {
4 | const { progress } = useProgress(); // Get loading progress
5 | console.log("Loading Progress:", progress); // Log progress to see if it's working
6 |
7 | return (
8 |
9 |
10 |
Loading {Math.round(progress)}%
11 |
17 |
18 |
19 | );
20 | };
21 |
22 | export default Loader;
23 |
--------------------------------------------------------------------------------
/src/components/MouseScroll.jsx:
--------------------------------------------------------------------------------
1 | const MouseScroll = () => {
2 | return (
3 |
8 | );
9 | };
10 |
11 | export default MouseScroll;
12 |
--------------------------------------------------------------------------------
/src/components/Navbar.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 | import { FaAlignRight } from "react-icons/fa";
3 | import { FaTimes } from "react-icons/fa";
4 | import { navLinks } from "../constants/data";
5 | import { motion } from "framer-motion";
6 |
7 | const NavItems = () => {
8 | return (
9 | <>
10 |
11 | {navLinks.map(({ id, href, name }) => (
12 |
18 |
24 | {name}
25 |
26 |
27 | ))}
28 |
29 | >
30 | );
31 | };
32 |
33 | const Navbar = () => {
34 | const [isOpen, setIsOpen] = useState(false);
35 | const [isScrolled, setIsScrolled] = useState(false);
36 |
37 | useEffect(() => {
38 | const handleScroll = () => {
39 | if (window.scrollY > 50) {
40 | setIsScrolled(true);
41 | } else {
42 | setIsScrolled(false);
43 | }
44 |
45 | //Close mobile menu on scroll.
46 | if (isOpen) {
47 | setIsOpen(false);
48 | }
49 | };
50 |
51 | window.addEventListener("scroll", handleScroll);
52 | return () => window.removeEventListener("scroll", handleScroll);
53 | }, [isOpen]);
54 |
55 | const toggleMenu = () => {
56 | setIsOpen((prevIsOpen) => !prevIsOpen);
57 | };
58 | return (
59 | <>
60 |
67 |
68 |
69 |
70 |
75 |
76 |
77 |
82 | {isOpen ? (
83 |
84 | ) : (
85 |
86 | )}
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
100 |
101 |
102 |
103 |
104 |
105 | >
106 | );
107 | };
108 |
109 | export default Navbar;
110 |
--------------------------------------------------------------------------------
/src/components/ProjectCard.jsx:
--------------------------------------------------------------------------------
1 | import { motion } from "framer-motion";
2 | import { SocialIcon } from "react-social-icons";
3 | import PropTypes from "prop-types";
4 |
5 | const ProjectCard = ({ project }) => {
6 | return (
7 |
8 |
12 |
17 | {/* Social Icon in the top-right corner of the image */}
18 |
23 |
24 |
25 | {/* Project Details */}
26 |
27 |
28 | {project.title}
29 |
30 |
31 | {project.desc}
32 |
33 |
34 | {project.subdesc}
35 |
36 |
37 |
38 | {/* Tags & Demo Link */}
39 |
40 |
41 | {project.tags.map((tag, index) => (
42 |
46 |
47 |
48 | ))}
49 |
50 |
58 | Demo
59 |
60 |
61 |
62 |
63 | );
64 | };
65 |
66 | export default ProjectCard;
67 |
68 | ProjectCard.propTypes = {
69 | project: PropTypes.shape({
70 | logo: PropTypes.string.isRequired,
71 | logoStyle: PropTypes.object.isRequired,
72 | source: PropTypes.string.isRequired,
73 | title: PropTypes.string.isRequired,
74 | desc: PropTypes.string.isRequired,
75 | subdesc: PropTypes.string.isRequired,
76 | href: PropTypes.string.isRequired,
77 | tags: PropTypes.arrayOf(
78 | PropTypes.shape({
79 | name: PropTypes.string.isRequired,
80 | path: PropTypes.string.isRequired,
81 | })
82 | ).isRequired,
83 | }).isRequired,
84 | };
85 |
--------------------------------------------------------------------------------
/src/components/SkillsSphere.jsx:
--------------------------------------------------------------------------------
1 | import { useState, useRef, useEffect, Suspense } from "react";
2 | import { Canvas, useFrame } from "@react-three/fiber";
3 | import { OrbitControls, Text } from "@react-three/drei";
4 | import { useSpring, animated } from "@react-spring/three";
5 | import * as THREE from "three";
6 | import PropTypes from "prop-types";
7 | import { skills } from "../constants/data";
8 | import Loader from "./Loader";
9 |
10 | const AnimatedText = animated(Text);
11 |
12 | const Word = ({ children, position }) => {
13 | const [hovered, setHovered] = useState(false);
14 | const textRef = useRef();
15 |
16 | useFrame(({ camera }) => {
17 | if (textRef.current) {
18 | textRef.current.quaternion.copy(camera.quaternion);
19 | }
20 | });
21 |
22 | const { color, scale } = useSpring({
23 | color: hovered ? "#fc0865" : "white",
24 | scale: hovered ? 1.1 : 1,
25 | config: { tension: 200, friction: 20 },
26 | });
27 |
28 | return (
29 | setHovered(true)}
37 | onPointerOut={() => setHovered(false)}
38 | >
39 | {children}
40 |
41 | );
42 | };
43 |
44 | Word.propTypes = {
45 | children: PropTypes.node.isRequired,
46 | position: PropTypes.object.isRequired,
47 | };
48 |
49 | const WordSphere = () => {
50 | const radius = 5;
51 | const wordPositions = skills.map((skill, i) => {
52 | const phi = Math.acos(-1 + (2 * i) / skills.length);
53 | const theta = Math.sqrt(skills.length * Math.PI) * phi;
54 | const position = new THREE.Vector3(
55 | radius * Math.sin(phi) * Math.cos(theta),
56 | radius * Math.sin(phi) * Math.sin(theta),
57 | radius * Math.cos(phi)
58 | );
59 | return { position, skill };
60 | });
61 |
62 | return (
63 |
64 | {wordPositions.map(({ skill, position }, index) => (
65 |
66 | {skill}
67 |
68 | ))}
69 |
70 | );
71 | };
72 |
73 | const SkillsSphere = () => {
74 | const [size, setSize] = useState(window.innerWidth);
75 |
76 | useEffect(() => {
77 | const handleResize = () => setSize(window.innerWidth);
78 | window.addEventListener("resize", handleResize);
79 | return () => window.removeEventListener("resize", handleResize);
80 | }, []);
81 |
82 | const isMobile = size < 768; // Adjust sphere size for mobile screens
83 | return (
84 |
91 | }>
92 |
93 |
94 |
95 |
96 |
97 | );
98 | };
99 |
100 | export default SkillsSphere;
101 |
--------------------------------------------------------------------------------
/src/components/StarField.jsx:
--------------------------------------------------------------------------------
1 | import { useRef, Suspense } from "react";
2 | import { Canvas, useFrame } from "@react-three/fiber";
3 | import { Points, PointMaterial, Preload } from "@react-three/drei";
4 | import * as random from "maath/random/dist/maath-random.esm";
5 | import Loader from "./Loader";
6 |
7 | const StarField = (props) => {
8 | const ref = useRef();
9 | const sphere = random.inSphere(new Float32Array(5000), { radius: 1.2 });
10 | useFrame((state, delta) => {
11 | ref.current.rotation.x -= delta / 15;
12 | ref.current.rotation.y -= delta / 20;
13 | });
14 |
15 | return (
16 |
17 |
18 |
25 |
26 |
27 | );
28 | };
29 |
30 | const StarCanvas = () => {
31 | return (
32 |
33 |
34 | }>
35 |
36 |
37 |
38 |
39 |
40 | );
41 | };
42 |
43 | export default StarCanvas;
44 |
--------------------------------------------------------------------------------
/src/constants/data.ts:
--------------------------------------------------------------------------------
1 | export const navLinks = [
2 | {
3 | id: 1,
4 | name: "Home",
5 | href: "#home",
6 | },
7 | {
8 | id: 2,
9 | name: "Skills",
10 | href: "#skills",
11 | },
12 | {
13 | id: 3,
14 | name: "Experience",
15 | href: "#experience",
16 | },
17 | {
18 | id: 4,
19 | name: "Projects",
20 | href: "#projects",
21 | },
22 | {
23 | id: 5,
24 | name: "Contact",
25 | href: "#contact",
26 | },
27 | ];
28 |
29 | export const myProjects = [
30 | {
31 | title: "ThreeRun - 3D Obstacle Course Game",
32 | desc: "A 3D obstacle course game built with React Three Fiber, featuring a third-person character controller with movement and animations.",
33 | subdesc:
34 | "Currently in early development, with plans for level completion, multiplayer, and collectibles.",
35 | href: "https://github.com/A-coderr/3d_obstacle_course",
36 | source: "https://a-coderr.github.io/3d_obstacle_course/",
37 | logo: "projects/ThreeRun_Main_Screen.png",
38 | logoStyle: {
39 | backgroundColor: "#b18eff",
40 | background:
41 | "linear-gradient(0deg, #B18EFF50, #B18EFF50), linear-gradient(180deg, rgba(255, 255, 255, 0.9) 0%, rgba(208, 213, 221, 0.8) 100%)",
42 | border: "0.2px solid rgba(177, 142, 255, 1)",
43 | boxShadow: "0px 0px 60px 0px rgba(177, 142, 255, 0.3)",
44 | },
45 | tags: [
46 | {
47 | id: 1,
48 | name: "React.js",
49 | path: "icons/react.svg",
50 | },
51 | {
52 | id: 2,
53 | name: "TailwindCSS",
54 | path: "icons/tailwindcss-icon.svg",
55 | },
56 | {
57 | id: 3,
58 | name: "TypeScript",
59 | path: "icons/typescript-icon.svg",
60 | },
61 | {
62 | id: 4,
63 | name: "Java Script",
64 | path: "icons/javascript.svg",
65 | },
66 | {
67 | id: 5,
68 | name: "Three.js",
69 | path: "icons/threejs.svg",
70 | },
71 | {
72 | id: 6,
73 | name: "HTML",
74 | path: "icons/html-5.svg",
75 | },
76 | {
77 | id: 7,
78 | name: "Redux",
79 | path: "icons/redux.svg",
80 | },
81 | {
82 | id: 8,
83 | name: "Prettier",
84 | path: "icons/prettier.svg",
85 | },
86 | {
87 | id: 9,
88 | name: "ESLint",
89 | path: "icons/eslint.svg",
90 | },
91 | {
92 | id: 10,
93 | name: "Vite",
94 | path: "icons/vite.svg",
95 | },
96 | ],
97 | },
98 | {
99 | title: "Anzhelika Kostyuk - Portfolio Website",
100 | desc: "My Portfolio Website, a showcase of my skills, projects, and experience as a software developer.",
101 | subdesc:
102 | "Built with modern web technologies, this portfolio highlights interactive 3D elements, smooth animations, and a responsive design for an engaging user experience.",
103 | href: "https://github.com/A-coderr/portfolio-website",
104 | source: "https://a-coderr.github.io/portfolio-website/",
105 | logo: "projects/Portfolio_Main.png",
106 | logoStyle: {
107 | backgroundColor: "#4FC3F7",
108 | background:
109 | "linear-gradient(0deg, #4FC3F750, #4FC3F750), linear-gradient(180deg, rgba(255, 255, 255, 0.9) 0%, rgba(208, 213, 221, 0.8) 100%)",
110 | border: "0.2px solid rgba(79, 195, 247, 1)",
111 | boxShadow: "0px 0px 60px 0px rgba(79, 195, 247, 0.3)",
112 | },
113 | tags: [
114 | {
115 | id: 1,
116 | name: "React.js",
117 | path: "icons/react.svg",
118 | },
119 | {
120 | id: 2,
121 | name: "TailwindCSS",
122 | path: "icons/tailwindcss-icon.svg",
123 | },
124 | {
125 | id: 3,
126 | name: "TypeScript",
127 | path: "icons/typescript-icon.svg",
128 | },
129 | {
130 | id: 4,
131 | name: "Java Script",
132 | path: "icons/javascript.svg",
133 | },
134 | {
135 | id: 5,
136 | name: "Three.js",
137 | path: "icons/threejs.svg",
138 | },
139 | {
140 | id: 6,
141 | name: "HTML",
142 | path: "icons/html-5.svg",
143 | },
144 | {
145 | id: 7,
146 | name: "CSS",
147 | path: "icons/css-3.svg",
148 | },
149 | {
150 | id: 8,
151 | name: "Prettier",
152 | path: "icons/prettier.svg",
153 | },
154 | {
155 | id: 9,
156 | name: "ESLint",
157 | path: "icons/eslint.svg",
158 | },
159 | {
160 | id: 10,
161 | name: "Vite",
162 | path: "icons/vite.svg",
163 | },
164 | ],
165 | },
166 | {
167 | title: "Karate Galaxy - Karate Website",
168 | desc: "My first ever web project, built as part of a college assignment and the starting point of my journey as a software developer.",
169 | subdesc:
170 | "Built using only HTML and CSS, it is a foundational project that reflects my early passion for web development.",
171 | href: "https://a-coderr.github.io/karate-galaxy/",
172 | source: "https://github.com/A-coderr/Karate_HTML_CSS",
173 | logo: "projects/KarateGalaxy_Main.png",
174 | logoStyle: {
175 | backgroundColor: "#A0F0BC",
176 | background:
177 | "linear-gradient(0deg, #A0F0BC50, #A0F0BC50), linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(208, 213, 221, 0.85) 100%)",
178 | border: "0.2px solid rgba(160, 240, 188, 1)",
179 | boxShadow: "0px 0px 60px 0px rgba(135, 234, 174, 0.4)",
180 | },
181 | tags: [
182 | {
183 | id: 1,
184 | name: "HTML",
185 | path: "icons/html-5.svg",
186 | },
187 | {
188 | id: 2,
189 | name: "CSS",
190 | path: "icons/css-3.svg",
191 | },
192 | ],
193 | },
194 | {
195 | title: "SKIF Karate Canada Website",
196 | desc: "A modern, responsive website built with Next.js to represent the SKIF Karate Canada.",
197 | subdesc:
198 | "This project showcases a blend of modern web development and traditional martial arts values.",
199 | href: "https://skif-website.vercel.app/",
200 | source: "https://github.com/A-coderr/skif-website",
201 | logo: "projects/skif.png",
202 | logoStyle: {
203 | backgroundColor: "#FF4C4C",
204 | background:
205 | "linear-gradient(0deg, #FF4C4C50, #FF4C4C50), linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 200, 200, 0.85) 100%)",
206 | border: "0.2px solid rgba(255, 76, 76, 1)",
207 | boxShadow: "0px 0px 60px 0px rgba(183, 28, 28, 0.4)",
208 | },
209 | tags: [
210 | {
211 | id: 1,
212 | name: "React.js",
213 | path: "icons/react.svg",
214 | },
215 | {
216 | id: 2,
217 | name: "Nextjs",
218 | path: "icons/nextjs.svg",
219 | },
220 | {
221 | id: 3,
222 | name: "TailwindCSS",
223 | path: "icons/tailwindcss-icon.svg",
224 | },
225 | {
226 | id: 4,
227 | name: "TypeScript",
228 | path: "icons/typescript-icon.svg",
229 | },
230 | {
231 | id: 5,
232 | name: "Java Script",
233 | path: "icons/javascript.svg",
234 | },
235 | {
236 | id: 6,
237 | name: "HTML",
238 | path: "icons/html-5.svg",
239 | },
240 | {
241 | id: 7,
242 | name: "CSS",
243 | path: "icons/css-3.svg",
244 | },
245 | {
246 | id: 8,
247 | name: "Prettier",
248 | path: "icons/prettier.svg",
249 | },
250 | {
251 | id: 9,
252 | name: "ESLint",
253 | path: "icons/eslint.svg",
254 | },
255 | {
256 | id: 10,
257 | name: "Markdown",
258 | path: "icons/markdown.svg",
259 | },
260 | {
261 | id: 11,
262 | name: "Vite",
263 | path: "icons/vite.svg",
264 | },
265 | {
266 | id: 12,
267 | name: "Vercel",
268 | path: "icons/vercel.svg",
269 | },
270 | ],
271 | },
272 | ];
273 |
274 | export const workExperiences = [
275 | {
276 | id: 1,
277 | company: "Centre for Virtual Reality Innovation - VARLab",
278 | position: "DLS Software Developer",
279 | duration: "August 2022 - current",
280 | icon: "varlab_logo.png",
281 | duties: [
282 | "Engineered performant and scalable web apps using ReactJS, JavaScript, TypeScript, and Node.js, implementing reusable components and modular architecture.",
283 | "Developed flat screen and VR learning experiences using Unity and C#, applying object-oriented principles and optimizing performance.",
284 | "Built interactive 3D web applications with Three.js and React Three Fiber, creating immersive educational content and visualizations.",
285 | "Integrated APIs and developed RESTful services using Express.js and MongoDB to support backend functionality and data persistence for interactive applications.",
286 | "Led the development of onboarding projects, standardizing workflows and improving ramp-up time for new developers by 45%.",
287 | "Partnered closely with UX/UI designers, 3D artists, and instructional designers to refine user interaction flows, leading to a 23% boost in usability test performance.",
288 | "Conducted code reviews, enforcing SOLID principles, clean code standards, and test-driven development (TDD).",
289 | "Applied responsive design principles to ensure accessibility and usability across devices.",
290 | "Mentored 20+ co-op developers, fostering agile best practices and effective use of Git and version control workflows.",
291 | ],
292 | },
293 | {
294 | id: 2,
295 | company: "Centre for Virtual Reality Innovation - VARLab",
296 | position: "AR/VR Software Developer (Co-op & Part-Time)",
297 | duration: "January 2021 - December 2021",
298 | icon: "varlab_logo.png",
299 | duties: [
300 | "Developed immersive 2D and 3D digital learning simulations in Unity and C#, applying Object-Oriented Programming (OOP) principles to build scalable, maintainable systems.",
301 | "Engineered modular, reusable components and optimized data structures, streamlining asset management and eliminating code redundancy.",
302 | "Collaborated cross-functionally with design, content, and QA teams to align interactive features with learning objectives and user needs, improving overall experience quality.",
303 | "Conducted unit and integration testing, identifying edge cases and minimizing production issues.",
304 | "Utilized advanced data structures (graphs, trees, hash maps) to optimize scene management and interaction logic in Unity environments.",
305 | "Integrated editor tools, scriptable objects, and custom inspectors to enhance team productivity and streamline content creation.",
306 | ],
307 | },
308 | {
309 | id: 3,
310 | company: "Conestoga College",
311 | position: "Mobile Application Developer (Co-op)",
312 | duration: "June 2020 - December 2020",
313 | icon: "conestoga_logo.png",
314 | duties: [
315 | "Developed cross-platform mobile applications with integrated Augmented Reality (AR) features, enhancing user engagement and interactivity.",
316 | "Utilized Python and machine learning techniques to predict optimal mask fit for users by analyzing facial scan data.",
317 | "Optimized application performance, resulting in a 17% increase in speed and a 21% improvement in user engagement metrics.",
318 | "Collaborated in design and architecture reviews, contributing to system scalability, modularity, and long-term maintainability.",
319 | "Authored and maintained comprehensive technical documentation to support onboarding, scalability, and knowledge transfer.",
320 | "Gained hands-on experience with Agile methodologies, participating in daily stand-ups, sprint planning, and retrospectives.",
321 | ],
322 | },
323 | ];
324 |
325 | export const socialLinks = [
326 | { url: "https://www.instagram.com/a_akcio/?hl=en" },
327 | { url: "https://github.com/A-coderr" },
328 | { url: "https://www.facebook.com/profile.php?id=100011369881132" },
329 | { url: "http://www.linkedin.com/in/anzhelika-kostyuk-a2b388194" },
330 | ];
331 |
332 | export const skills = [
333 | "ReactJS",
334 | "Three.js",
335 | "Test-Driven Development",
336 | "JavaScript",
337 | "TypeScript",
338 | "C#",
339 | "Unity",
340 | "Python",
341 | "Object-Oriented Programming",
342 | "HTML5",
343 | "CSS3",
344 | "Node.js",
345 | "Express.js",
346 | "Git",
347 | "MongoDB",
348 | "React Three Fiber",
349 | "Azure",
350 | "Atlassian suite",
351 | "MySQL",
352 | "Scrum",
353 | "Agile",
354 | "3D",
355 | "GitHub",
356 | "Web Development",
357 | "Redux",
358 | "TailwindCSS",
359 | "Responsive Design",
360 | "Data Structures",
361 | "Algorithms",
362 | "User Experience",
363 | "Version Control",
364 | ];
365 |
--------------------------------------------------------------------------------
/src/main.jsx:
--------------------------------------------------------------------------------
1 | import { StrictMode } from "react";
2 | import { createRoot } from "react-dom/client";
3 | import App from "./App.jsx";
4 |
5 | createRoot(document.getElementById("root")).render(
6 |
7 |
8 |
9 | );
10 |
--------------------------------------------------------------------------------
/src/sections/Contact.jsx:
--------------------------------------------------------------------------------
1 | import { useRef, useState } from "react";
2 | import { LinearGradient } from "react-text-gradients";
3 | import emailjs from "@emailjs/browser";
4 | import { motion } from "framer-motion";
5 |
6 | const SERVICE_ID = import.meta.env.VITE_EMAILJS_SERVICE_ID;
7 | const TEMPLATE_ID = import.meta.env.VITE_EMAILJS_TEMPLATE_ID;
8 | const PUBLIC_KEY = import.meta.env.VITE_EMAILJS_PUBLIC_KEY;
9 | const TO_NAME = import.meta.env.VITE_EMAILJS_TO_NAME;
10 | const TO_EMAIL = import.meta.env.VITE_EMAILJS_TO_EMAIL;
11 |
12 | /**
13 | * The Contact section of the website allows users to
14 | * submit a message to the website owner. The component renders a form with
15 | * name, email and message fields. When the form is submitted, the component
16 | * sends an email using EmailJS and displays a success or error message based
17 | * on the outcome of the email sending process.
18 | */
19 | const Contact = () => {
20 | const formRef = useRef();
21 | const [loading, setLoading] = useState(false);
22 | const [form, setForm] = useState({ name: "", email: "", message: "" });
23 |
24 | /**
25 | * Handles the change of the form fields, updates the
26 | * component state with the new values.
27 | * @param {React.ChangeEvent} e - The change event.
28 | */
29 | const handleChange = (e) => {
30 | const { name, value } = e.target;
31 | setForm({ ...form, [name]: value });
32 | };
33 |
34 | /**
35 | * Handles the form submission, sends an email using EmailJS
36 | * and displays a success or error message based on the
37 | * outcome of the email sending process.
38 | * @param {React.FormEvent} e - The form submission event.
39 | */
40 | const handleSubmit = (e) => {
41 | e.preventDefault();
42 | setLoading(true);
43 | emailjs
44 | .send(
45 | SERVICE_ID,
46 | TEMPLATE_ID,
47 | {
48 | from_name: form.name,
49 | to_name: TO_NAME,
50 | from_email: form.email,
51 | to_email: TO_EMAIL,
52 | message: form.message,
53 | },
54 | PUBLIC_KEY
55 | )
56 | .then(
57 | () => {
58 | setLoading(false);
59 | alert("Thank you. I will get back to you as soon as possible");
60 | setForm({
61 | name: "",
62 | email: "",
63 | message: "",
64 | });
65 | },
66 | (error) => {
67 | setLoading(false);
68 | console.log(error);
69 | alert("Something went wrong!");
70 | }
71 | );
72 | };
73 |
74 | return (
75 |
154 | );
155 | };
156 |
157 | export default Contact;
158 |
--------------------------------------------------------------------------------
/src/sections/Experience.jsx:
--------------------------------------------------------------------------------
1 | import { LinearGradient } from "react-text-gradients";
2 | import {
3 | VerticalTimeline,
4 | VerticalTimelineElement,
5 | } from "react-vertical-timeline-component";
6 | import "react-vertical-timeline-component/style.min.css";
7 | import { workExperiences } from "../constants/data";
8 | import { motion } from "framer-motion";
9 | import PropTypes from "prop-types";
10 |
11 | const ExperienceCard = ({ experience }) => {
12 | return (
13 |
21 |
26 |
27 | }
28 | >
29 |
30 |
31 | {experience.position}
32 |
33 |
34 | {experience.company}
35 |
36 |
37 |
38 | {experience.duties.map((duty, index) => (
39 |
43 | {duty}
44 |
45 | ))}
46 |
47 |
48 | );
49 | };
50 | const Experience = () => {
51 | return (
52 | <>
53 |
57 |
58 |
59 |
66 |
67 | Work Experience
68 |
69 |
70 |
71 |
72 |
73 | {workExperiences.map((experience, index) => (
74 |
78 | ))}
79 |
80 |
81 |
82 | >
83 | );
84 | };
85 |
86 | export default Experience;
87 |
88 | ExperienceCard.propTypes = {
89 | experience: PropTypes.shape({
90 | company: PropTypes.string.isRequired,
91 | position: PropTypes.string.isRequired,
92 | duration: PropTypes.string.isRequired,
93 | icon: PropTypes.string.isRequired,
94 | duties: PropTypes.arrayOf(PropTypes.string).isRequired,
95 | }).isRequired,
96 | };
97 |
--------------------------------------------------------------------------------
/src/sections/Hero.jsx:
--------------------------------------------------------------------------------
1 | import { LinearGradient } from "react-text-gradients";
2 | import { SocialIcon } from "react-social-icons/component";
3 | import "react-social-icons/instagram";
4 | import "react-social-icons/github";
5 | import "react-social-icons/linkedin";
6 | import "react-social-icons/facebook";
7 | import MouseScroll from "../components/MouseScroll";
8 | import { socialLinks } from "../constants/data";
9 | import { motion } from "framer-motion";
10 | import { useEffect, useState } from "react";
11 |
12 | const Hero = () => {
13 | const [waveTrigger, setWaveTrigger] = useState(false);
14 |
15 | useEffect(() => {
16 | const interval = setInterval(() => {
17 | setWaveTrigger(true);
18 | setTimeout(() => setWaveTrigger(false), 1000);
19 | }, 4000); //Wave every 4 seconds.
20 |
21 | return () => clearInterval(interval);
22 | }, []);
23 |
24 | return (
25 | <>
26 |
30 |
31 |
32 | Hi, I am{" "}
33 |
34 | Anzhelika
35 |
36 |
37 |
42 | Software Developer
43 |
44 |
45 |
46 | I'm a passionate software developer with expertise in web and
47 | game development using JavaScript, TypeScript, C#, and Unity. I
48 | build interactive experiences and web applications, leveraging both
49 | front-end and back-end technologies. With a strong focus on clean
50 | code, collaboration, and continuous learning, I strive to create
51 | innovative solutions that enhance user experiences.
52 |
53 |
54 |
60 | {socialLinks.map((link, index) => (
61 |
78 |
79 |
80 | ))}
81 |
82 |
83 |
84 |
85 |
86 | >
87 | );
88 | };
89 |
90 | export default Hero;
91 |
--------------------------------------------------------------------------------
/src/sections/Projects.jsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 | import Carousel from "react-spring-3d-carousel";
3 | import { config } from "react-spring";
4 | import { v4 as uuidv4 } from "uuid";
5 | import { LinearGradient } from "react-text-gradients";
6 | import { myProjects } from "../constants/data";
7 | import ProjectCard from "../components/ProjectCard";
8 | import { motion } from "framer-motion";
9 |
10 | const Projects = () => {
11 | const [slideIndex, setSlideIndex] = useState(0);
12 | const [slides, setSlides] = useState([]);
13 |
14 | useEffect(() => {
15 | const carouselSlides = myProjects.map((project, index) => ({
16 | key: uuidv4(),
17 | content: ,
18 | onClick: () => setSlideIndex(index),
19 | }));
20 | setSlides(carouselSlides);
21 | }, []);
22 |
23 | return (
24 |
25 |
26 |
27 |
34 |
35 | Projects
36 |
37 |
38 |
39 |
40 |
{
44 | const swipe = info.offset.x;
45 |
46 | if (swipe > 50) {
47 | setSlideIndex(
48 | (prev) => (prev - 1 + myProjects.length) % myProjects.length
49 | );
50 | } else if (swipe < -50) {
51 | setSlideIndex((prev) => (prev + 1) % myProjects.length);
52 | }
53 | }}
54 | className="w-full mt-24 mb-12 md:mt-32 md:mb-20 lg:mt-40 h-[400px] md:h-[500px] flex items-center justify-center cursor-grab active:cursor-grabbing"
55 | >
56 | {slides.length > 0 && (
57 |
64 | )}
65 |
66 |
67 |
68 | );
69 | };
70 |
71 | export default Projects;
72 |
--------------------------------------------------------------------------------
/src/sections/Skills.jsx:
--------------------------------------------------------------------------------
1 | import { LinearGradient } from "react-text-gradients";
2 | import SkillsSphere from "../components/SkillsSphere";
3 | import { motion } from "framer-motion";
4 |
5 | const Skills = () => {
6 | return (
7 | <>
8 |
9 |
10 |
11 |
18 |
19 | Skills
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | >
29 | );
30 | };
31 |
32 | export default Skills;
33 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
4 | theme: {
5 | extend: {
6 | animation: {
7 | typewriter: "typewriter 1s steps(13) forwards",
8 | caret:
9 | "typewriter 1s steps(13) forwards, blink 1s steps(13) infinite 2s",
10 | },
11 | keyframes: {
12 | typewriter: {
13 | to: {
14 | left: "100%",
15 | },
16 | },
17 | blink: {
18 | "0%": {
19 | opacity: "0",
20 | },
21 | "0.1%": {
22 | opacity: "1",
23 | },
24 | "50%": {
25 | opacity: "1",
26 | },
27 | "50.1%": {
28 | opacity: "0",
29 | },
30 | "100%": {
31 | opacity: "0",
32 | },
33 | },
34 | },
35 | },
36 | },
37 | plugins: [],
38 | };
39 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import react from "@vitejs/plugin-react";
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | base: "./",
8 | });
9 |
--------------------------------------------------------------------------------