├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public ├── HeroImage.png ├── index.html └── planet │ ├── license.txt │ ├── scene.bin │ ├── scene.gltf │ └── textures │ ├── Clouds_baseColor.png │ └── Planet_baseColor.png └── src ├── App.js ├── components ├── Dialog │ └── ProjectDetails.jsx ├── HeroBgAnimation │ ├── HeroBgAnimationStyle.js │ └── index.js ├── Navbar.jsx ├── canvas │ ├── Earth.jsx │ └── Stars.jsx ├── cards │ ├── EducationCard.jsx │ ├── ExperienceCard.jsx │ └── ProjectCard.jsx └── sections │ ├── Contact.jsx │ ├── Education.jsx │ ├── Experience.jsx │ ├── Footer.jsx │ ├── Hero.jsx │ ├── Projects.jsx │ └── Skills.jsx ├── data └── constants.js ├── images ├── HeroImage.png ├── copic.png ├── djangopic.png ├── expresspic.png ├── flutterpic.png ├── icons8-angularjs-48.png ├── jetpackpic.png ├── keraspic.png ├── school.png ├── vuepic.png └── xdpic.png ├── index.css ├── index.js └── utils ├── Themes.js └── motion.js /.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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # My Portfolio 2 | Welcome to my portfolio! This project showcases my skills, projects, and experiences as a web developer. 3 | 4 | 5 | ## Table of Contents 6 | - [Introduction](#introduction) 7 | - [Features](#features) 8 | - [Technologies Used](#technologies-used) 9 | - [Installation](#installation) 10 | - [Usage](#usage) 11 | - [Contributing](#contributing) 12 | - [License](#license) 13 | 14 | ## Introduction 15 | My Portfolio is a React.js application that serves as an online portfolio to showcase my work, skills, and achievements. It provides an overview of my background, displays my projects, and offers a way to contact me. 16 | 17 | ## Features 18 | - About Me: An overview of my background, skills, and experiences. 19 | - Projects: A collection of my notable projects with descriptions, screenshots, and links. 20 | - Skills: A list of my technical skills and proficiencies. 21 | - Resume: A link to download my resume. 22 | - Contact: A form to send me messages or inquiries. 23 | 24 | ## Technologies Used 25 | - React.js: A JavaScript library for building user interfaces. 26 | - HTML5 & CSS3: Markup and styling languages for building web pages. 27 | - JavaScript: A programming language for adding interactivity to web applications. 28 | - Style-Components: A CSS framework for creating responsive and mobile-first designs. 29 | - Git: A version control system for tracking changes and collaborating on projects. 30 | - GitHub Pages: A platform for hosting and deploying web applications. 31 | 32 | ## Usage 33 | After installing and running the project locally, you can navigate through the different sections of the portfolio using the navigation menu. Explore the About Me section to learn more about my background and skills. Visit the Projects section to see detailed information about my projects, including descriptions and screenshots. Use the Contact section to send me a message or inquiry. 34 | 35 | ## Contributing 36 | Contributions are welcome! If you'd like to contribute to My Portfolio, please follow these steps: 37 | 38 | 1. Fork the repository. 39 | 2. Create a new branch for your feature or bug fix: `git checkout -b my-feature` 40 | 3. Commit your changes: `git commit -m 'Add some feature'` 41 | 4. Push to the branch: `git push origin my-feature` 42 | 5. Open a pull request. 43 | 44 | ## License 45 | This project is licensed under the [MIT License](LICENSE). 46 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "3d-portfolio-website", 3 | "version": "0.1.1", 4 | "homepage": "https://rishavchanda.github.io", 5 | "private": true, 6 | "dependencies": { 7 | "@emailjs/browser": "^4.1.0", 8 | "@emotion/react": "^11.11.3", 9 | "@emotion/styled": "^11.11.0", 10 | "@mui/icons-material": "^5.15.10", 11 | "@mui/lab": "^5.0.0-alpha.165", 12 | "@mui/material": "^5.15.10", 13 | "@react-three/drei": "^9.99.0", 14 | "@react-three/fiber": "^8.15.16", 15 | "@testing-library/jest-dom": "^5.17.0", 16 | "@testing-library/react": "^13.4.0", 17 | "@testing-library/user-event": "^13.5.0", 18 | "emailjs": "^4.0.3", 19 | "framer-motion": "^11.0.5", 20 | "maath": "^0.10.7", 21 | "react": "^18.2.0", 22 | "react-dom": "^18.2.0", 23 | "react-icons": "^5.0.1", 24 | "react-router-dom": "^6.22.1", 25 | "react-scripts": "5.0.1", 26 | "react-scroll": "^1.9.0", 27 | "react-tilt": "^1.0.2", 28 | "react-vertical-timeline-component": "^3.6.0", 29 | "styled-components": "^6.1.8", 30 | "three": "^0.161.0", 31 | "typewriter-effect": "^2.21.0", 32 | "web-vitals": "^2.1.4", 33 | "gh-pages": "^3.2.3" 34 | }, 35 | "scripts": { 36 | "start": "react-scripts start", 37 | "build": "react-scripts build", 38 | "test": "react-scripts test", 39 | "eject": "react-scripts eject", 40 | "predeploy": "npm run build", 41 | "deploy": "gh-pages -d build" 42 | }, 43 | "eslintConfig": { 44 | "extends": [ 45 | "react-app", 46 | "react-app/jest" 47 | ] 48 | }, 49 | "browserslist": { 50 | "production": [ 51 | ">0.2%", 52 | "not dead", 53 | "not op_mini all" 54 | ], 55 | "development": [ 56 | "last 1 chrome version", 57 | "last 1 firefox version", 58 | "last 1 safari version" 59 | ] 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /public/HeroImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-knight0227/reactproject/7ecc205f6cb5738843b6b6816284e7f708893710/public/HeroImage.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | Anh Quan Khuat 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/planet/license.txt: -------------------------------------------------------------------------------- 1 | Model Information: 2 | * title: Stylized planet 3 | * source: https://sketchfab.com/3d-models/stylized-planet-789725db86f547fc9163b00f302c3e70 4 | * author: cmzw (https://sketchfab.com/cmzw) 5 | 6 | Model License: 7 | * license type: CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/) 8 | * requirements: Author must be credited. Commercial use is allowed. 9 | 10 | If you use this 3D model in your project be sure to copy paste this credit wherever you share it: 11 | This work is based on "Stylized planet" (https://sketchfab.com/3d-models/stylized-planet-789725db86f547fc9163b00f302c3e70) by cmzw (https://sketchfab.com/cmzw) licensed under CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/) -------------------------------------------------------------------------------- /public/planet/scene.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-knight0227/reactproject/7ecc205f6cb5738843b6b6816284e7f708893710/public/planet/scene.bin -------------------------------------------------------------------------------- /public/planet/scene.gltf: -------------------------------------------------------------------------------- 1 | { 2 | "accessors": [ 3 | { 4 | "bufferView": 2, 5 | "componentType": 5126, 6 | "count": 26495, 7 | "max": [ 8 | 0.8758764863014221, 9 | 0.8545469045639038, 10 | 0.8728971481323242 11 | ], 12 | "min": [ 13 | -0.8763356804847717, 14 | -0.8634992837905884, 15 | -0.8758782148361206 16 | ], 17 | "type": "VEC3" 18 | }, 19 | { 20 | "bufferView": 2, 21 | "byteOffset": 317940, 22 | "componentType": 5126, 23 | "count": 26495, 24 | "max": [ 25 | 1.0, 26 | 0.9999911785125732, 27 | 0.9991646409034729 28 | ], 29 | "min": [ 30 | -1.0, 31 | -0.9999968409538269, 32 | -0.9999611377716064 33 | ], 34 | "type": "VEC3" 35 | }, 36 | { 37 | "bufferView": 1, 38 | "componentType": 5126, 39 | "count": 26495, 40 | "max": [ 41 | 1.0, 42 | 1.0 43 | ], 44 | "min": [ 45 | 0.0, 46 | 0.0 47 | ], 48 | "type": "VEC2" 49 | }, 50 | { 51 | "bufferView": 0, 52 | "componentType": 5125, 53 | "count": 103014, 54 | "type": "SCALAR" 55 | }, 56 | { 57 | "bufferView": 2, 58 | "byteOffset": 635880, 59 | "componentType": 5126, 60 | "count": 6596, 61 | "max": [ 62 | 0.6551179885864258, 63 | 0.6613333821296692, 64 | 0.6618664860725403 65 | ], 66 | "min": [ 67 | -0.6606217622756958, 68 | -0.6490849852561951, 69 | -0.6526646018028259 70 | ], 71 | "type": "VEC3" 72 | }, 73 | { 74 | "bufferView": 2, 75 | "byteOffset": 715032, 76 | "componentType": 5126, 77 | "count": 6596, 78 | "max": [ 79 | 0.999987006187439, 80 | 0.9998384118080139, 81 | 0.9999796748161316 82 | ], 83 | "min": [ 84 | -0.9995425939559937, 85 | -0.999676525592804, 86 | -0.9994800686836243 87 | ], 88 | "type": "VEC3" 89 | }, 90 | { 91 | "bufferView": 1, 92 | "byteOffset": 211960, 93 | "componentType": 5126, 94 | "count": 6596, 95 | "max": [ 96 | 1.0, 97 | 1.0 98 | ], 99 | "min": [ 100 | 0.0, 101 | 0.0 102 | ], 103 | "type": "VEC2" 104 | }, 105 | { 106 | "bufferView": 0, 107 | "byteOffset": 412056, 108 | "componentType": 5125, 109 | "count": 39042, 110 | "type": "SCALAR" 111 | }, 112 | { 113 | "bufferView": 3, 114 | "componentType": 5126, 115 | "count": 451, 116 | "max": [ 117 | 15.0 118 | ], 119 | "min": [ 120 | 0.0 121 | ], 122 | "type": "SCALAR" 123 | }, 124 | { 125 | "bufferView": 5, 126 | "componentType": 5126, 127 | "count": 451, 128 | "max": [ 129 | 0.20017318427562714, 130 | 0.979751706123352, 131 | 0.2001722753047943, 132 | 0.9797602891921997 133 | ], 134 | "min": [ 135 | -0.018710684031248093, 136 | -0.9797568917274475, 137 | -0.1991616040468216, 138 | 0.0026621678844094276 139 | ], 140 | "type": "VEC4" 141 | }, 142 | { 143 | "bufferView": 3, 144 | "byteOffset": 1804, 145 | "componentType": 5126, 146 | "count": 125, 147 | "max": [ 148 | 15.0 149 | ], 150 | "min": [ 151 | 0.0 152 | ], 153 | "type": "SCALAR" 154 | }, 155 | { 156 | "bufferView": 4, 157 | "componentType": 5126, 158 | "count": 125, 159 | "max": [ 160 | 1.0000001192092896, 161 | 1.0, 162 | 1.0000001192092896 163 | ], 164 | "min": [ 165 | 0.9999998807907104, 166 | 1.0, 167 | 0.9999998807907104 168 | ], 169 | "type": "VEC3" 170 | }, 171 | { 172 | "bufferView": 3, 173 | "byteOffset": 2304, 174 | "componentType": 5126, 175 | "count": 451, 176 | "max": [ 177 | 15.0 178 | ], 179 | "min": [ 180 | 0.0 181 | ], 182 | "type": "SCALAR" 183 | }, 184 | { 185 | "bufferView": 5, 186 | "byteOffset": 7216, 187 | "componentType": 5126, 188 | "count": 451, 189 | "max": [ 190 | 0.20017318427562714, 191 | 0.979751706123352, 192 | 0.2001722753047943, 193 | 0.9797602891921997 194 | ], 195 | "min": [ 196 | -0.018710684031248093, 197 | -0.9797568917274475, 198 | -0.1991616040468216, 199 | 0.0026621678844094276 200 | ], 201 | "type": "VEC4" 202 | }, 203 | { 204 | "bufferView": 3, 205 | "byteOffset": 4108, 206 | "componentType": 5126, 207 | "count": 125, 208 | "max": [ 209 | 15.0 210 | ], 211 | "min": [ 212 | 0.0 213 | ], 214 | "type": "SCALAR" 215 | }, 216 | { 217 | "bufferView": 4, 218 | "byteOffset": 1500, 219 | "componentType": 5126, 220 | "count": 125, 221 | "max": [ 222 | 1.0000001192092896, 223 | 1.0, 224 | 1.0000001192092896 225 | ], 226 | "min": [ 227 | 0.9999998807907104, 228 | 1.0, 229 | 0.9999998807907104 230 | ], 231 | "type": "VEC3" 232 | } 233 | ], 234 | "animations": [ 235 | { 236 | "channels": [ 237 | { 238 | "sampler": 0, 239 | "target": { 240 | "node": 3, 241 | "path": "rotation" 242 | } 243 | }, 244 | { 245 | "sampler": 1, 246 | "target": { 247 | "node": 3, 248 | "path": "scale" 249 | } 250 | }, 251 | { 252 | "sampler": 2, 253 | "target": { 254 | "node": 5, 255 | "path": "rotation" 256 | } 257 | }, 258 | { 259 | "sampler": 3, 260 | "target": { 261 | "node": 5, 262 | "path": "scale" 263 | } 264 | } 265 | ], 266 | "name": "Animation", 267 | "samplers": [ 268 | { 269 | "input": 8, 270 | "interpolation": "LINEAR", 271 | "output": 9 272 | }, 273 | { 274 | "input": 10, 275 | "interpolation": "LINEAR", 276 | "output": 11 277 | }, 278 | { 279 | "input": 12, 280 | "interpolation": "LINEAR", 281 | "output": 13 282 | }, 283 | { 284 | "input": 14, 285 | "interpolation": "LINEAR", 286 | "output": 15 287 | } 288 | ] 289 | } 290 | ], 291 | "asset": { 292 | "extras": { 293 | "author": "cmzw (https://sketchfab.com/cmzw)", 294 | "license": "CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)", 295 | "source": "https://sketchfab.com/3d-models/stylized-planet-789725db86f547fc9163b00f302c3e70", 296 | "title": "Stylized planet" 297 | }, 298 | "generator": "Sketchfab-14.10.0", 299 | "version": "2.0" 300 | }, 301 | "bufferViews": [ 302 | { 303 | "buffer": 0, 304 | "byteLength": 568224, 305 | "name": "floatBufferViews", 306 | "target": 34963 307 | }, 308 | { 309 | "buffer": 0, 310 | "byteLength": 264728, 311 | "byteOffset": 568224, 312 | "byteStride": 8, 313 | "name": "floatBufferViews", 314 | "target": 34962 315 | }, 316 | { 317 | "buffer": 0, 318 | "byteLength": 794184, 319 | "byteOffset": 832952, 320 | "byteStride": 12, 321 | "name": "floatBufferViews", 322 | "target": 34962 323 | }, 324 | { 325 | "buffer": 0, 326 | "byteLength": 4608, 327 | "byteOffset": 1627136, 328 | "name": "floatBufferViews" 329 | }, 330 | { 331 | "buffer": 0, 332 | "byteLength": 3000, 333 | "byteOffset": 1631744, 334 | "byteStride": 12, 335 | "name": "floatBufferViews" 336 | }, 337 | { 338 | "buffer": 0, 339 | "byteLength": 14432, 340 | "byteOffset": 1634744, 341 | "byteStride": 16, 342 | "name": "floatBufferViews" 343 | } 344 | ], 345 | "buffers": [ 346 | { 347 | "byteLength": 1649176, 348 | "uri": "scene.bin" 349 | } 350 | ], 351 | "extensionsUsed": [ 352 | "KHR_materials_unlit" 353 | ], 354 | "images": [ 355 | { 356 | "uri": "textures/Clouds_baseColor.png" 357 | }, 358 | { 359 | "uri": "textures/Planet_baseColor.png" 360 | } 361 | ], 362 | "materials": [ 363 | { 364 | "doubleSided": true, 365 | "emissiveTexture": { 366 | "index": 0 367 | }, 368 | "extensions": { 369 | "KHR_materials_unlit": {} 370 | }, 371 | "name": "Clouds", 372 | "pbrMetallicRoughness": { 373 | "baseColorTexture": { 374 | "index": 0 375 | }, 376 | "metallicFactor": 0.0 377 | } 378 | }, 379 | { 380 | "emissiveFactor": [ 381 | 0.23391156271636818, 382 | 0.23391156271636818, 383 | 0.23391156271636818 384 | ], 385 | "emissiveTexture": { 386 | "index": 1 387 | }, 388 | "extensions": { 389 | "KHR_materials_unlit": {} 390 | }, 391 | "name": "Planet", 392 | "pbrMetallicRoughness": { 393 | "baseColorTexture": { 394 | "index": 1 395 | }, 396 | "metallicFactor": 0.0 397 | } 398 | } 399 | ], 400 | "meshes": [ 401 | { 402 | "name": "Object_0", 403 | "primitives": [ 404 | { 405 | "attributes": { 406 | "NORMAL": 1, 407 | "POSITION": 0, 408 | "TEXCOORD_0": 2 409 | }, 410 | "indices": 3, 411 | "material": 0, 412 | "mode": 4 413 | } 414 | ] 415 | }, 416 | { 417 | "name": "Object_1", 418 | "primitives": [ 419 | { 420 | "attributes": { 421 | "NORMAL": 5, 422 | "POSITION": 4, 423 | "TEXCOORD_0": 6 424 | }, 425 | "indices": 7, 426 | "material": 1, 427 | "mode": 4 428 | } 429 | ] 430 | } 431 | ], 432 | "nodes": [ 433 | { 434 | "children": [ 435 | 1 436 | ], 437 | "matrix": [ 438 | 0.9979661703109741, 439 | 0.06371438503265381, 440 | 0.001990502001717701, 441 | 0.0, 442 | 0.0, 443 | 0.031225780025124772, 444 | -0.9995123744010925, 445 | 0.0, 446 | -0.06374546885490417, 447 | 0.9974795579910278, 448 | 0.031162271276116593, 449 | 0.0, 450 | 0.0, 451 | 0.0, 452 | 0.0, 453 | 1.0 454 | ], 455 | "name": "Sketchfab_model" 456 | }, 457 | { 458 | "children": [ 459 | 2 460 | ], 461 | "name": "root" 462 | }, 463 | { 464 | "children": [ 465 | 3, 466 | 5 467 | ], 468 | "matrix": [ 469 | 1.0, 470 | 0.0, 471 | 0.0, 472 | 0.0, 473 | 0.0, 474 | 2.220446049250313e-16, 475 | 1.0, 476 | 0.0, 477 | 0.0, 478 | -1.0, 479 | 2.220446049250313e-16, 480 | 0.0, 481 | 0.0, 482 | 0.0, 483 | 0.0, 484 | 1.0 485 | ], 486 | "name": "GLTF_SceneRootNode" 487 | }, 488 | { 489 | "children": [ 490 | 4 491 | ], 492 | "name": "Clouds_1" 493 | }, 494 | { 495 | "mesh": 0, 496 | "name": "Object_4" 497 | }, 498 | { 499 | "children": [ 500 | 6 501 | ], 502 | "name": "Planet_2" 503 | }, 504 | { 505 | "mesh": 1, 506 | "name": "Object_6" 507 | } 508 | ], 509 | "samplers": [ 510 | { 511 | "magFilter": 9729, 512 | "minFilter": 9987, 513 | "wrapS": 10497, 514 | "wrapT": 10497 515 | } 516 | ], 517 | "scene": 0, 518 | "scenes": [ 519 | { 520 | "name": "Sketchfab_Scene", 521 | "nodes": [ 522 | 0 523 | ] 524 | } 525 | ], 526 | "textures": [ 527 | { 528 | "sampler": 0, 529 | "source": 0 530 | }, 531 | { 532 | "sampler": 0, 533 | "source": 1 534 | } 535 | ] 536 | } 537 | -------------------------------------------------------------------------------- /public/planet/textures/Clouds_baseColor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-knight0227/reactproject/7ecc205f6cb5738843b6b6816284e7f708893710/public/planet/textures/Clouds_baseColor.png -------------------------------------------------------------------------------- /public/planet/textures/Planet_baseColor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-knight0227/reactproject/7ecc205f6cb5738843b6b6816284e7f708893710/public/planet/textures/Planet_baseColor.png -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import styled, { ThemeProvider } from "styled-components"; 2 | import { darkTheme } from "./utils/Themes"; 3 | import Navbar from "./components/Navbar"; 4 | import { BrowserRouter } from "react-router-dom"; 5 | import Hero from "./components/sections/Hero"; 6 | import Skills from "./components/sections/Skills"; 7 | import StarCanvas from "./components/canvas/Stars"; 8 | import { AnimatePresence } from "framer-motion"; 9 | import Education from "./components/sections/Education"; 10 | import Experience from "./components/sections/Experience"; 11 | import Projects from "./components/sections/Projects"; 12 | import Contact from "./components/sections/Contact"; 13 | import Footer from "./components/sections/Footer"; 14 | import ProjectDetails from "./components/Dialog/ProjectDetails"; 15 | import { useState } from "react"; 16 | 17 | const Body = styled.div` 18 | background-color: ${({ theme }) => theme.bg}; 19 | width: 100%; 20 | overflow-x: hidden; 21 | position: relative; 22 | `; 23 | 24 | const Wrapper = styled.div` 25 | padding-bottom: 100px; 26 | background: linear-gradient( 27 | 38.73deg, 28 | rgba(204, 0, 187, 0.15) 0%, 29 | rgba(201, 32, 184, 0) 50% 30 | ), 31 | linear-gradient( 32 | 141.27deg, 33 | rgba(0, 70, 209, 0) 50%, 34 | rgba(0, 70, 209, 0.15) 100% 35 | ); 36 | width: 100%; 37 | clip-path: polygon(0 0, 100% 0, 100% 100%, 30% 98%, 0 100%); 38 | `; 39 | 40 | function App() { 41 | const [openModal, setOpenModal] = useState({ state: false, project: null }); 42 | return ( 43 | 44 | 45 | 46 | 47 | 48 | 49 |
50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
69 |
70 | 71 |
72 |
73 | ); 74 | } 75 | 76 | export default App; 77 | -------------------------------------------------------------------------------- /src/components/Dialog/ProjectDetails.jsx: -------------------------------------------------------------------------------- 1 | import { CloseRounded, GitHub, LinkedIn } from "@mui/icons-material"; 2 | import { Modal } from "@mui/material"; 3 | import React from "react"; 4 | import styled from "styled-components"; 5 | 6 | const Container = styled.div` 7 | width: 100%; 8 | height: 100%; 9 | position: absolute; 10 | top: 0; 11 | left: 0; 12 | background-color: #000000a7; 13 | display: flex; 14 | align-items: top; 15 | justify-content: center; 16 | overflow-y: scroll; 17 | transition: all 0.5s ease; 18 | `; 19 | 20 | const Wrapper = styled.div` 21 | max-width: 800px; 22 | width: 100%; 23 | border-radius: 16px; 24 | margin: 50px 12px; 25 | height: min-content; 26 | background-color: ${({ theme }) => theme.card}; 27 | color: ${({ theme }) => theme.text_primary}; 28 | padding: 20px; 29 | display: flex; 30 | flex-direction: column; 31 | position: relative; 32 | `; 33 | 34 | const Title = styled.div` 35 | font-size: 28px; 36 | font-weight: 600; 37 | color: ${({ theme }) => theme.text_primary}; 38 | margin: 8px 6px 0px 6px; 39 | @media only screen and (max-width: 600px) { 40 | font-size: 24px; 41 | margin: 6px 6px 0px 6px; 42 | } 43 | `; 44 | 45 | const Date = styled.div` 46 | font-size: 16px; 47 | margin: 2px 6px; 48 | font-weight: 400; 49 | color: ${({ theme }) => theme.text_secondary}; 50 | @media only screen and (max-width: 768px) { 51 | font-size: 12px; 52 | } 53 | `; 54 | 55 | const Desc = styled.div` 56 | font-size: 16px; 57 | font-weight: 400; 58 | color: ${({ theme }) => theme.text_primary}; 59 | margin: 8px 6px; 60 | @media only screen and (max-width: 600px) { 61 | font-size: 14px; 62 | margin: 6px 6px; 63 | } 64 | `; 65 | 66 | const Image = styled.img` 67 | width: 100%; 68 | object-fit: cover; 69 | border-radius: 12px; 70 | margin-top: 30px; 71 | box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.3); 72 | `; 73 | 74 | const Label = styled.div` 75 | font-size: 20px; 76 | font-weight: 600; 77 | color: ${({ theme }) => theme.text_primary}; 78 | margin: 8px 6px; 79 | @media only screen and (max-width: 600px) { 80 | font-size: 16px; 81 | margin: 8px 6px; 82 | } 83 | `; 84 | 85 | const Tags = styled.div` 86 | display: flex; 87 | flex-wrap: wrap; 88 | margin: 8px 0px; 89 | @media only screen and (max-width: 600px) { 90 | margin: 4px 0px; 91 | } 92 | `; 93 | 94 | const Tag = styled.div` 95 | font-size: 14px; 96 | font-weight: 400; 97 | color: ${({ theme }) => theme.primary}; 98 | margin: 4px; 99 | padding: 4px 8px; 100 | border-radius: 8px; 101 | background-color: ${({ theme }) => theme.primary + 20}; 102 | @media only screen and (max-width: 600px) { 103 | font-size: 12px; 104 | } 105 | `; 106 | 107 | const Members = styled.div` 108 | display: flex; 109 | flex-direction: column; 110 | gap: 6px; 111 | flex-wrap: wrap; 112 | margin: 12px 6px; 113 | @media only screen and (max-width: 600px) { 114 | margin: 4px 6px; 115 | } 116 | `; 117 | 118 | const Member = styled.div` 119 | display: flex; 120 | align-items: center; 121 | gap: 12px; 122 | `; 123 | 124 | const MemberImage = styled.img` 125 | width: 50px; 126 | height: 50px; 127 | object-fit: cover; 128 | border-radius: 50%; 129 | margin-bottom: 4px; 130 | box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.3); 131 | @media only screen and (max-width: 600px) { 132 | width: 32px; 133 | height: 32px; 134 | } 135 | `; 136 | 137 | const MemberName = styled.div` 138 | font-size: 16px; 139 | font-weight: 500; 140 | width: 200px; 141 | color: ${({ theme }) => theme.text_primary}; 142 | @media only screen and (max-width: 600px) { 143 | font-size: 14px; 144 | } 145 | `; 146 | 147 | const ButtonGroup = styled.div` 148 | display: flex; 149 | justify-content: flex-end; 150 | margin: 12px 0px; 151 | gap: 12px; 152 | `; 153 | 154 | const Button = styled.a` 155 | width: 100%; 156 | text-align: center; 157 | font-size: 16px; 158 | font-weight: 600; 159 | color: ${({ theme }) => theme.text_primary}; 160 | padding: 12px 16px; 161 | border-radius: 8px; 162 | background-color: ${({ theme }) => theme.primary}; 163 | ${({ dull, theme }) => 164 | dull && 165 | ` 166 | background-color: ${theme.bgLight}; 167 | color: ${theme.text_secondary}; 168 | &:hover { 169 | background-color: ${({ theme }) => theme.bg + 99}; 170 | } 171 | `} 172 | cursor: pointer; 173 | text-decoration: none; 174 | transition: all 0.5s ease; 175 | &:hover { 176 | background-color: ${({ theme }) => theme.primary + 99}; 177 | } 178 | @media only screen and (max-width: 600px) { 179 | font-size: 12px; 180 | } 181 | `; 182 | 183 | const ProjectDetails = ({ openModal, setOpenModal }) => { 184 | const project = openModal?.project; 185 | return ( 186 | setOpenModal({ state: false, project: null })} 189 | > 190 | 191 | 192 | setOpenModal({ state: false, project: null })} 200 | /> 201 | 202 | {project?.title} 203 | {project.date} 204 | 205 | {project?.tags.map((tag) => ( 206 | {tag} 207 | ))} 208 | 209 | {project?.description} 210 | {project.member && ( 211 | <> 212 | 213 | 214 | {project?.member.map((member) => ( 215 | 216 | 217 | {member.name} 218 | 223 | 224 | 225 | 230 | 231 | 232 | 233 | ))} 234 | 235 | 236 | )} 237 | 238 | 241 | 244 | 245 | 246 | 247 | 248 | ); 249 | }; 250 | 251 | export default ProjectDetails; 252 | -------------------------------------------------------------------------------- /src/components/HeroBgAnimation/HeroBgAnimationStyle.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | 4 | export const Div = styled.div` 5 | width:600px; 6 | height: 500px; 7 | ` -------------------------------------------------------------------------------- /src/components/HeroBgAnimation/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Div } from './HeroBgAnimationStyle'; 3 | const HeroBgAnimation = () => ( 4 |
5 | 11 | 12 | 19 | 24 | 29 | 30 | 38 | 39 | 40 | 41 | 42 | 47 | 48 | 49 | 50 | 51 | 59 | 65 | 66 | 67 | 68 | 73 | 79 | 80 | 81 | 82 | 90 | 91 | 92 | 93 | 94 | 99 | 100 | 101 | 102 | 103 | 111 | 117 | 118 | 119 | 120 | 125 | 131 | 132 | 133 | 134 | 142 | 148 | 149 | 150 | 151 | 156 | 162 | 163 | 164 | 165 | 173 | 179 | 180 | 181 | 182 | 187 | 193 | 194 | 195 | 196 | 204 | 210 | 211 | 212 | 213 | 218 | 224 | 225 | 226 | 227 | 228 | 236 | 237 | 238 | 239 | 247 | 248 | 249 | 250 | 258 | 259 | 260 | 261 | 269 | 270 | 271 | 272 | 280 | 281 | 282 | 283 | 291 | 292 | 293 | 294 | 302 | 303 | 304 | 305 | 313 | 314 | 315 | 316 | 324 | 325 | 326 | 327 | 335 | 336 | 337 | 338 | 346 | 347 | 348 | 349 | 357 | 358 | 359 | 360 | 361 | 362 |
363 | ); 364 | 365 | export default HeroBgAnimation; -------------------------------------------------------------------------------- /src/components/Navbar.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { Link as LinkR } from "react-router-dom"; 3 | import styled, { useTheme } from "styled-components"; 4 | import { Bio } from "../data/constants"; 5 | import { MenuRounded } from "@mui/icons-material"; 6 | 7 | const Nav = styled.div` 8 | background-color: ${({ theme }) => theme.bg}; 9 | height: 80px; 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | font-size: 1rem; 14 | position: sticky; 15 | top: 0; 16 | z-index: 10; 17 | color: white; 18 | `; 19 | const ColorText = styled.div` 20 | color: ${({ theme }) => theme.primary}; 21 | font-size: 32px; 22 | `; 23 | 24 | const NavbarContainer = styled.div` 25 | width: 100%; 26 | max-width: 1200px; 27 | padding: 0 24px; 28 | display: flex; 29 | align-items: center; 30 | justify-content: space-between; 31 | font-size: 1rem; 32 | `; 33 | const NavLogo = styled(LinkR)` 34 | display: flex; 35 | align-items: center; 36 | width: 80%; 37 | padding: 0 6px; 38 | font-weight: 500; 39 | font-size: 18px; 40 | text-decoration: none; 41 | color: inherit; 42 | `; 43 | 44 | const NavItems = styled.ul` 45 | width: 100%; 46 | display: flex; 47 | align-items: center; 48 | justify-content: center; 49 | gap: 32px; 50 | padding: 0 6px; 51 | list-style: none; 52 | 53 | @media screen and (max-width: 768px) { 54 | display: none; 55 | } 56 | `; 57 | 58 | const NavLink = styled.a` 59 | color: ${({ theme }) => theme.text_primary}; 60 | font-weight: 500; 61 | cursor: pointer; 62 | transition: all 0.2s ease-in-out; 63 | text-decoration: none; 64 | &:hover { 65 | color: ${({ theme }) => theme.primary}; 66 | } 67 | `; 68 | 69 | const ButtonContainer = styled.div` 70 | width: 80%; 71 | height: 100%; 72 | display: flex; 73 | justify-content: end; 74 | align-items: center; 75 | padding: 0 6px; 76 | @media screen and (max-width: 768px) { 77 | display: none; 78 | } 79 | `; 80 | 81 | const GithubButton = styled.a` 82 | border: 1px solid ${({ theme }) => theme.primary}; 83 | color: ${({ theme }) => theme.primary}; 84 | justify-content: center; 85 | display: flex; 86 | align-items: center; 87 | border-radius: 20px; 88 | cursor: pointer; 89 | padding: 10px 20px; 90 | font-size: 16px; 91 | font-weight: 500; 92 | transition: all 0.6s ease-in-out; 93 | text-decoration: none; 94 | &:hover { 95 | background: ${({ theme }) => theme.primary}; 96 | color: ${({ theme }) => theme.text_primary}; 97 | } 98 | `; 99 | 100 | const MobileIcon = styled.div` 101 | height: 100%; 102 | display: flex; 103 | align-items: center; 104 | color: ${({ theme }) => theme.text_primary}; 105 | display: none; 106 | @media screen and (max-width: 768px) { 107 | display: block; 108 | } 109 | `; 110 | 111 | const MobileMenu = styled.ul` 112 | width: 100%; 113 | display: flex; 114 | flex-direction: column; 115 | align-items: start; 116 | gap: 16px; 117 | padding: 0 6px; 118 | list-style: none; 119 | width: 100%; 120 | padding: 12px 40px 24px 40px; 121 | background: ${({ theme }) => theme.card_light + 99}; 122 | position: absolute; 123 | top: 80px; 124 | right: 0; 125 | 126 | transition: all 0.6s ease-in-out; 127 | transform: ${({ isOpen }) => 128 | isOpen ? "translateY(0)" : "translateY(-100%)"}; 129 | border-radius: 0 0 20px 20px; 130 | box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2); 131 | opacity: ${({ isOpen }) => (isOpen ? "100%" : "0")}; 132 | z-index: ${({ isOpen }) => (isOpen ? "1000" : "-1000")}; 133 | `; 134 | 135 | const Navbar = () => { 136 | const [isOpen, setIsOpen] = useState(false); 137 | const theme = useTheme(); 138 | return ( 139 | 196 | ); 197 | }; 198 | 199 | export default Navbar; 200 | -------------------------------------------------------------------------------- /src/components/canvas/Earth.jsx: -------------------------------------------------------------------------------- 1 | import React, { Suspense } from "react"; 2 | import { Canvas } from "@react-three/fiber"; 3 | import { OrbitControls, Preload, useGLTF } from "@react-three/drei"; 4 | 5 | const Earth = () => { 6 | const earth = useGLTF("./planet/scene.gltf"); 7 | return ( 8 | 9 | ); 10 | }; 11 | 12 | const EarthCanvas = () => { 13 | return ( 14 | 26 | 27 | 33 | 34 | 35 | 36 | 37 | ); 38 | }; 39 | 40 | export default EarthCanvas; 41 | -------------------------------------------------------------------------------- /src/components/canvas/Stars.jsx: -------------------------------------------------------------------------------- 1 | import React, { useRef, useState, 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 styled from "styled-components"; 6 | 7 | const StyledCanvasWrapper = styled.div` 8 | width: 100%; 9 | height: auto; 10 | position: absolute; 11 | inset: 0; 12 | `; 13 | 14 | const Stars = (props) => { 15 | const ref = useRef(); 16 | const [sphere] = useState(() => 17 | random.inSphere(new Float32Array(5000), { radius: 1.2 }) 18 | ); 19 | 20 | useFrame((state, delta) => { 21 | ref.current.rotation.x -= delta / 10; 22 | ref.current.rotation.y -= delta / 15; 23 | }); 24 | 25 | return ( 26 | 27 | 28 | 35 | 36 | 37 | ); 38 | }; 39 | 40 | const StyledStarsCanvas = () => { 41 | return ( 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | ); 51 | }; 52 | 53 | export default StyledStarsCanvas; 54 | -------------------------------------------------------------------------------- /src/components/cards/EducationCard.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | import { VerticalTimelineElement } from "react-vertical-timeline-component"; 4 | 5 | const Top = styled.div` 6 | width: 100%; 7 | display: flex; 8 | max-width: 100%; 9 | gap: 12px; 10 | `; 11 | const Image = styled.img` 12 | height: 50px; 13 | border-radius: 10px; 14 | margin-top: 4px; 15 | 16 | @media only screen and (max-width: 768px) { 17 | height: 40px; 18 | } 19 | `; 20 | const Body = styled.div` 21 | width: 100%; 22 | display: flex; 23 | flex-direction: column; 24 | `; 25 | 26 | const Name = styled.div` 27 | font-size: 18px; 28 | font-weight: 600px; 29 | color: ${({ theme }) => theme.text_primary + 99}; 30 | 31 | @media only screen and (max-width: 768px) { 32 | font-size: 14px; 33 | } 34 | `; 35 | const Degree = styled.div` 36 | font-size: 14px; 37 | font-weight: 500px; 38 | color: ${({ theme }) => theme.text_secondary + 99}; 39 | 40 | @media only screen and (max-width: 768px) { 41 | font-size: 12px; 42 | } 43 | `; 44 | const Date = styled.div` 45 | font-size: 12px; 46 | font-weight: 400px; 47 | color: ${({ theme }) => theme.text_secondary + 80}; 48 | 49 | @media only screen and (max-width: 768px) { 50 | font-size: 10px; 51 | } 52 | `; 53 | const Grade = styled.div` 54 | font-size: 14px; 55 | font-weight: 500; 56 | color: ${({ theme }) => theme.text_secondary + 99}; 57 | @media only screen and (max-width: 768px) { 58 | font-size: 12px; 59 | } 60 | `; 61 | 62 | const Description = styled.div` 63 | width: 100%; 64 | font-size: 15px; 65 | font-weight: 400; 66 | color: ${({ theme }) => theme.text_primary + 99}; 67 | margin-bottom: 10px; 68 | @media only screen and (max-width: 768px) { 69 | font-size: 12px; 70 | } 71 | `; 72 | const Span = styled.div``; 73 | 74 | const EducationCard = ({ education }) => { 75 | return ( 76 | 85 | } 86 | contentStyle={{ 87 | display: "flex", 88 | flexDirection: "column", 89 | gap: "12px", 90 | background: "#1d1836", 91 | color: "#fff", 92 | boxShadow: "rgba(23, 92, 230, 0.15) 0px 4px 24px", 93 | // backdropFilter: "blur(3px) saturate(106%)", 94 | backgroundColor: "rgba(17, 25, 40, 0.83)", 95 | border: "1px solid rgba(255, 255, 255, 0.125)", 96 | borderRadius: "6px", 97 | }} 98 | contentArrowStyle={{ 99 | borderRight: "7px solid rgba(255, 255, 255, 0.3)", 100 | }} 101 | date={education.date} 102 | > 103 | 104 | 105 | 106 | {education.school} 107 | {education.degree} 108 | {education.date} 109 | 110 | 111 | 112 | Grade : 113 | {education.grade} 114 | 115 | 116 | {education.desc} 117 | 118 | 119 | ); 120 | }; 121 | 122 | export default EducationCard; 123 | -------------------------------------------------------------------------------- /src/components/cards/ExperienceCard.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | import { VerticalTimelineElement } from "react-vertical-timeline-component"; 4 | 5 | const Top = styled.div` 6 | width: 100%; 7 | display: flex; 8 | max-width: 100%; 9 | gap: 12px; 10 | `; 11 | const Image = styled.img` 12 | height: 50px; 13 | border-radius: 10px; 14 | margin-top: 4px; 15 | 16 | @media only screen and (max-width: 768px) { 17 | height: 40px; 18 | } 19 | `; 20 | const Body = styled.div` 21 | width: 100%; 22 | display: flex; 23 | flex-direction: column; 24 | `; 25 | 26 | const Role = styled.div` 27 | font-size: 18px; 28 | font-weight: 600px; 29 | color: ${({ theme }) => theme.text_primary + 99}; 30 | 31 | @media only screen and (max-width: 768px) { 32 | font-size: 14px; 33 | } 34 | `; 35 | const Company = styled.div` 36 | font-size: 14px; 37 | font-weight: 500px; 38 | color: ${({ theme }) => theme.text_secondary + 99}; 39 | 40 | @media only screen and (max-width: 768px) { 41 | font-size: 12px; 42 | } 43 | `; 44 | const Date = styled.div` 45 | font-size: 12px; 46 | font-weight: 400px; 47 | color: ${({ theme }) => theme.text_secondary + 80}; 48 | 49 | @media only screen and (max-width: 768px) { 50 | font-size: 10px; 51 | } 52 | `; 53 | const Grade = styled.div` 54 | font-size: 14px; 55 | font-weight: 500; 56 | color: ${({ theme }) => theme.text_secondary + 99}; 57 | @media only screen and (max-width: 768px) { 58 | font-size: 12px; 59 | } 60 | `; 61 | 62 | const Description = styled.div` 63 | width: 100%; 64 | font-size: 15px; 65 | font-weight: 400; 66 | color: ${({ theme }) => theme.text_primary + 99}; 67 | margin-bottom: 10px; 68 | @media only screen and (max-width: 768px) { 69 | font-size: 12px; 70 | } 71 | `; 72 | const Span = styled.div` 73 | display: -webkit-box; 74 | max-width: 100%; 75 | `; 76 | const Skills = styled.div` 77 | width: 100%; 78 | display: flex; 79 | gap: 12px; 80 | margin-top: -10px; 81 | `; 82 | const Skill = styled.div` 83 | font-size: 15px; 84 | font-weight: 400; 85 | color: ${({ theme }) => theme.text_primary + 99}; 86 | @media only screen and (max-width: 768px) { 87 | font-size: 12px; 88 | } 89 | `; 90 | 91 | const ItemWrapper = styled.div` 92 | display: flex; 93 | flex-wrap: wrap; 94 | gap: 8px; 95 | `; 96 | 97 | const ExperienceCard = ({ experience }) => { 98 | return ( 99 | 108 | } 109 | contentStyle={{ 110 | display: "flex", 111 | flexDirection: "column", 112 | gap: "12px", 113 | background: "#1d1836", 114 | color: "#fff", 115 | boxShadow: "rgba(23, 92, 230, 0.15) 0px 4px 24px", 116 | // backdropFilter: "blur(3px) saturate(106%)", 117 | backgroundColor: "rgba(17, 25, 40, 0.83)", 118 | border: "1px solid rgba(255, 255, 255, 0.125)", 119 | borderRadius: "6px", 120 | }} 121 | contentArrowStyle={{ 122 | borderRight: "7px solid rgba(255, 255, 255, 0.3)", 123 | }} 124 | date={experience.date} 125 | > 126 | 127 | 128 | 129 | {experience.role} 130 | {experience.company} 131 | {experience.date} 132 | 133 | 134 | 135 | {experience?.desc && {experience?.desc}} 136 | {experience?.skills && ( 137 | <> 138 |
139 | 140 | Skills: 141 | 142 | {experience?.skills?.map((skill, index) => ( 143 | • {skill} 144 | ))} 145 | 146 | 147 | 148 | )} 149 |
150 |
151 | ); 152 | }; 153 | 154 | export default ExperienceCard; 155 | -------------------------------------------------------------------------------- /src/components/cards/ProjectCard.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | 4 | const Card = styled.div` 5 | width: 330px; 6 | height: 490px; 7 | background-color: ${({ theme }) => theme.card}; 8 | cursor: pointer; 9 | border-radius: 10px; 10 | box-shadow: 0 0 12px 4px rgba(0, 0, 0, 0.4); 11 | overflow: hidden; 12 | padding: 26px 20px; 13 | display: flex; 14 | flex-direction: column; 15 | gap: 14px; 16 | transition: all 0.5s ease-in-out; 17 | &:hover { 18 | transform: translateY(-10px); 19 | box-shadow: 0 0 50px 4px rgba(0, 0, 0, 0.6); 20 | filter: brightness(1.1); 21 | } 22 | `; 23 | const Image = styled.img` 24 | width: 100%; 25 | height: 180px; 26 | background-color: ${({ theme }) => theme.white}; 27 | border-radius: 10px; 28 | box-shadow: 0 0 16px 2px rgba(0, 0, 0, 0.3); 29 | `; 30 | const Tags = styled.div` 31 | width: 100%; 32 | display: flex; 33 | align-items: center; 34 | flex-wrap: wrap; 35 | gap: 8px; 36 | margin-top: 4px; 37 | `; 38 | const Tag = styled.div` 39 | font-size: 12px; 40 | font-weight: 400; 41 | color: ${({ theme }) => theme.primary}; 42 | background-color: ${({ theme }) => theme.primary + 15}; 43 | padding: 2px 8px; 44 | border-radius: 10px; 45 | `; 46 | const Details = styled.div` 47 | width: 100%; 48 | display: flex; 49 | flex-direction: column; 50 | gap: 0px; 51 | padding: 0px 2px; 52 | `; 53 | const Title = styled.div` 54 | font-size: 20px; 55 | font-weight: 600; 56 | color: ${({ theme }) => theme.text_secondary}; 57 | overflow: hidden; 58 | display: -webkit-box; 59 | max-width: 100%; 60 | -webkit-line-clamp: 2; 61 | -webkit-box-orient: vertical; 62 | overflow: hidden; 63 | text-overflow: ellipsis; 64 | `; 65 | const Date = styled.div` 66 | font-size: 12px; 67 | margin-left: 2px; 68 | font-weight: 400; 69 | color: ${({ theme }) => theme.text_secondary + 80}; 70 | @media only screen and (max-width: 768px) { 71 | font-size: 10px; 72 | } 73 | `; 74 | const Description = styled.div` 75 | font-weight: 400; 76 | color: ${({ theme }) => theme.text_secondary + 99}; 77 | overflow: hidden; 78 | margin-top: 8px; 79 | display: -webkit-box; 80 | max-width: 100%; 81 | -webkit-line-clamp: 3; 82 | -webkit-box-orient: vertical; 83 | text-overflow: ellipsis; 84 | `; 85 | const Members = styled.div` 86 | display: flex; 87 | align-items: center; 88 | padding-left: 10px; 89 | `; 90 | const Avatar = styled.img` 91 | width: 38px; 92 | height: 38px; 93 | border-radius: 50%; 94 | margin-left: -10px; 95 | background-color: ${({ theme }) => theme.white}; 96 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); 97 | border: 3px solid ${({ theme }) => theme.card}; 98 | `; 99 | const Button = styled.a` 100 | color: ${({ theme }) => theme.primary}; 101 | text-decoration: none; 102 | font-weight: 600; 103 | text-align: center; 104 | `; 105 | 106 | const ProjectCard = ({ project, setOpenModal }) => { 107 | return ( 108 | setOpenModal({ state: true, project: project })}> 109 | 110 | 111 | {project.tags?.map((tag, index) => ( 112 | {tag} 113 | ))} 114 | 115 |
116 | {project.title} 117 | {project.date} 118 | {project.description} 119 |
120 | 121 | {project.member?.map((member) => ( 122 | 123 | ))} 124 | 125 |
126 | ); 127 | }; 128 | 129 | export default ProjectCard; 130 | -------------------------------------------------------------------------------- /src/components/sections/Contact.jsx: -------------------------------------------------------------------------------- 1 | import React, { useRef } from "react"; 2 | import styled from "styled-components"; 3 | import emailjs from "@emailjs/browser"; 4 | import EarthCanvas from "../canvas/Earth"; 5 | 6 | const Container = styled.div` 7 | display: flex; 8 | justify-content: center; 9 | gap: 12px; 10 | z-index: 1; 11 | align-items: center; 12 | @media (max-width: 960px) { 13 | padding: 0px; 14 | } 15 | `; 16 | 17 | const Wrapper = styled.div` 18 | position: relative; 19 | display: flex; 20 | justify-content: space-between; 21 | align-items: center; 22 | flex-direction: column; 23 | width: 100%; 24 | max-width: 1350px; 25 | padding: 0px 0px 80px 0px; 26 | gap: 12px; 27 | @media (max-width: 960px) { 28 | flex-direction: column; 29 | } 30 | `; 31 | 32 | const Title = styled.div` 33 | font-size: 52px; 34 | text-align: center; 35 | font-weight: 600; 36 | margin-top: 20px; 37 | color: ${({ theme }) => theme.text_primary}; 38 | @media (max-width: 768px) { 39 | margin-top: 12px; 40 | font-size: 32px; 41 | } 42 | `; 43 | 44 | const Desc = styled.div` 45 | font-size: 18px; 46 | text-align: center; 47 | max-width: 600px; 48 | color: ${({ theme }) => theme.text_secondary}; 49 | @media (max-width: 768px) { 50 | margin-top: 12px; 51 | font-size: 16px; 52 | } 53 | `; 54 | const ContactForm = styled.form` 55 | width: 95%; 56 | max-width: 600px; 57 | display: flex; 58 | flex-direction: column; 59 | background-color: rgba(17, 25, 40, 0.83); 60 | border: 1px solid rgba(255, 255, 255, 0.125); 61 | padding: 32px; 62 | border-radius: 12px; 63 | box-shadow: rgba(23, 92, 230, 0.1) 0px 4px 24px; 64 | margin-top: 28px; 65 | gap: 12px; 66 | `; 67 | const ContactTitle = styled.div` 68 | font-size: 28px; 69 | margin-bottom: 6px; 70 | font-weight: 600; 71 | color: ${({ theme }) => theme.text_primary}; 72 | `; 73 | const ContactInput = styled.input` 74 | flex: 1; 75 | background-color: transparent; 76 | border: 1px solid ${({ theme }) => theme.text_secondary + 50}; 77 | outline: none; 78 | font-size: 18px; 79 | color: ${({ theme }) => theme.text_primary}; 80 | border-radius: 12px; 81 | padding: 12px 16px; 82 | &:focus { 83 | border: 1px solid ${({ theme }) => theme.primary}; 84 | } 85 | `; 86 | const ContactInputMessage = styled.textarea` 87 | flex: 1; 88 | background-color: transparent; 89 | border: 1px solid ${({ theme }) => theme.text_secondary + 50}; 90 | outline: none; 91 | font-size: 18px; 92 | color: ${({ theme }) => theme.text_primary}; 93 | border-radius: 12px; 94 | padding: 12px 16px; 95 | &:focus { 96 | border: 1px solid ${({ theme }) => theme.primary}; 97 | } 98 | `; 99 | const ContactButton = styled.input` 100 | width: 100%; 101 | text-decoration: none; 102 | text-align: center; 103 | background: hsla(271, 100%, 50%, 1); 104 | background: linear-gradient( 105 | 225deg, 106 | hsla(271, 100%, 50%, 1) 0%, 107 | hsla(294, 100%, 50%, 1) 100% 108 | ); 109 | background: -moz-linear-gradient( 110 | 225deg, 111 | hsla(271, 100%, 50%, 1) 0%, 112 | hsla(294, 100%, 50%, 1) 100% 113 | ); 114 | background: -webkit-linear-gradient( 115 | 225deg, 116 | hsla(271, 100%, 50%, 1) 0%, 117 | hsla(294, 100%, 50%, 1) 100% 118 | ); 119 | padding: 13px 16px; 120 | margin-top: 2px; 121 | border-radius: 12px; 122 | border: none; 123 | color: ${({ theme }) => theme.text_primary}; 124 | font-size: 18px; 125 | font-weight: 600; 126 | `; 127 | 128 | const Contact = () => { 129 | const form = useRef(); 130 | 131 | const handleSubmit = (e) => { 132 | e.preventDefault(); 133 | emailjs 134 | .sendForm( 135 | "service_tox7kqs", 136 | "template_nv7k7mj", 137 | form.current, 138 | "SybVGsYS52j2TfLbi" 139 | ) 140 | .then( 141 | (result) => { 142 | alert("Message Sent"); 143 | form.current.resut(); 144 | }, 145 | (error) => { 146 | alert(error); 147 | } 148 | ); 149 | }; 150 | 151 | return ( 152 | 153 | 154 | 155 | Contact 156 | 157 | Feel free to reach out to me for any questions or opportunities! 158 | 159 | 160 | Email Me 🚀 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | ); 170 | }; 171 | 172 | export default Contact; 173 | -------------------------------------------------------------------------------- /src/components/sections/Education.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | import { education } from "../../data/constants"; 4 | import EducationCard from "../cards/EducationCard"; 5 | import { VerticalTimeline } from "react-vertical-timeline-component"; 6 | import "react-vertical-timeline-component/style.min.css"; 7 | 8 | const Container = styled.div` 9 | margin-top: 100px; 10 | display: flex; 11 | flex-direction: column; 12 | justify-content-center; 13 | position: relative; 14 | z-index: 1; 15 | align-items: center; 16 | `; 17 | const Wrapper = styled.div` 18 | position: relative; 19 | display: flex; 20 | justify-content: space-between; 21 | align-items: center; 22 | flex-direction: column; 23 | width: 100%; 24 | max-width: 1100px; 25 | gap: 12px; 26 | @media (max-width: 960px) { 27 | flex-direction: column; 28 | } 29 | `; 30 | 31 | const Title = styled.div` 32 | font-size: 52px; 33 | text-align: center; 34 | font-weight: 600; 35 | margin-top: 20px; 36 | color: ${({ theme }) => theme.text_primary}; 37 | @media (max-width: 768px) { 38 | margin-top: 12px; 39 | font-size: 32px; 40 | } 41 | `; 42 | 43 | const Desc = styled.div` 44 | font-size: 18px; 45 | text-align: center; 46 | font-weight: 600; 47 | color: ${({ theme }) => theme.text_secondary}; 48 | @media (max-width: 768px) { 49 | font-size: 16px; 50 | } 51 | `; 52 | 53 | const Education = () => { 54 | return ( 55 | 56 | 57 | Education 58 | 63 | My education has been a journey of self-discovery and growth. My 64 | educational details are as follows. 65 | 66 | 67 | 68 | {education.map((education, index) => ( 69 | 70 | ))} 71 | 72 | 73 | 74 | ); 75 | }; 76 | 77 | export default Education; 78 | -------------------------------------------------------------------------------- /src/components/sections/Experience.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | import { experiences } from "../../data/constants"; 4 | import { VerticalTimeline } from "react-vertical-timeline-component"; 5 | import "react-vertical-timeline-component/style.min.css"; 6 | import ExperienceCard from "../cards/ExperienceCard"; 7 | 8 | const Container = styled.div` 9 | margin-top: 100px; 10 | display: flex; 11 | flex-direction: column; 12 | justify-content-center; 13 | position: relative; 14 | z-index: 1; 15 | align-items: center; 16 | `; 17 | const Wrapper = styled.div` 18 | position: relative; 19 | display: flex; 20 | justify-content: space-between; 21 | align-items: center; 22 | flex-direction: column; 23 | width: 100%; 24 | max-width: 1100px; 25 | gap: 12px; 26 | @media (max-width: 960px) { 27 | flex-direction: column; 28 | } 29 | `; 30 | 31 | const Title = styled.div` 32 | font-size: 52px; 33 | text-align: center; 34 | font-weight: 600; 35 | margin-top: 20px; 36 | color: ${({ theme }) => theme.text_primary}; 37 | @media (max-width: 768px) { 38 | margin-top: 12px; 39 | font-size: 32px; 40 | } 41 | `; 42 | 43 | const Desc = styled.div` 44 | font-size: 18px; 45 | text-align: center; 46 | font-weight: 600; 47 | color: ${({ theme }) => theme.text_secondary}; 48 | @media (max-width: 768px) { 49 | font-size: 16px; 50 | } 51 | `; 52 | 53 | const Experience = () => { 54 | return ( 55 | 56 | 57 | Experience 58 | 63 | My work experience as a software engineer and working on different 64 | companies and projects. 65 | 66 | 67 | 68 | {experiences.map((experience, index) => ( 69 | 73 | ))} 74 | 75 | 76 | 77 | ); 78 | }; 79 | 80 | export default Experience; 81 | -------------------------------------------------------------------------------- /src/components/sections/Footer.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | import { Bio } from "../../data/constants"; 4 | import TelegramIcon from "@mui/icons-material/Telegram"; 5 | import PhoneIcon from "@mui/icons-material/Phone"; 6 | import SkypeIcon from "@mui/icons-material/Microsoft"; 7 | 8 | 9 | const FooterContainer = styled.div` 10 | width: 100%; 11 | padding: 2rem 0; 12 | display: flex; 13 | justify-content: center; 14 | position: relative; 15 | z-index: 1; 16 | `; 17 | 18 | const FooterWrapper = styled.div` 19 | width: 100%; 20 | max-width: 1200px; 21 | display: flex; 22 | flex-direction: column; 23 | gap: 14px; 24 | align-items: center; 25 | padding: 1rem; 26 | color: ${({ theme }) => theme.text_primary}; 27 | `; 28 | 29 | const Logo = styled.div` 30 | font-weight: 600; 31 | font-size: 20px; 32 | color: ${({ theme }) => theme.primary}; 33 | `; 34 | 35 | const Nav = styled.nav` 36 | width: 100%; 37 | max-width: 800px; 38 | margin-top: 0.5rem; 39 | display: flex; 40 | flex-direction: row; 41 | gap: 2rem; 42 | justify-content: center; 43 | @media (max-width: 768px) { 44 | flex-wrap: wrap; 45 | gap: 1rem; 46 | justify-content: center; 47 | text-align: center; 48 | font-size: 12px; 49 | } 50 | `; 51 | 52 | const NavLink = styled.a` 53 | color: ${({ theme }) => theme.text_primary}; 54 | text-decoration: none; 55 | font-size: 1.2rem; 56 | transition: color 0.2s ease-in-out; 57 | &:hover { 58 | color: ${({ theme }) => theme.primary}; 59 | } 60 | @media (max-width: 768px) { 61 | font-size: 1rem; 62 | } 63 | `; 64 | 65 | const SocialMediaIcons = styled.div` 66 | display: flex; 67 | margin-top: 1rem; 68 | `; 69 | const SocialMediaIcon = styled.a` 70 | display: inline-block; 71 | margin: 0 1rem; 72 | font-size: 1.5rem; 73 | color: ${({ theme }) => theme.text_primary}; 74 | transition: color 0.2s ease-in-out; 75 | &:hover { 76 | color: ${({ theme }) => theme.primary}; 77 | } 78 | `; 79 | 80 | const Copyright = styled.p` 81 | margin-top: 1.5rem; 82 | font-size: 0.9rem; 83 | color: ${({ theme }) => theme.soft2}; 84 | text-align: center; 85 | `; 86 | 87 | const Footer = () => { 88 | return ( 89 | 90 | 91 | Anh Quan Khuat 92 | 99 | +84 359591558 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | © 2025 Anh Quan Khuat. All rights reserved. 109 | 110 | 111 | ); 112 | }; 113 | 114 | export default Footer; 115 | -------------------------------------------------------------------------------- /src/components/sections/Hero.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | import { Bio } from "../../data/constants"; 4 | import Typewriter from "typewriter-effect"; 5 | import HeroImg from "../../images/HeroImage.png"; 6 | import HeroBgAnimation from "../HeroBgAnimation"; 7 | import { Tilt } from "react-tilt"; 8 | import { motion } from "framer-motion"; 9 | import { 10 | headContainerAnimation, 11 | headContentAnimation, 12 | headTextAnimation, 13 | } from "../../utils/motion"; 14 | import StarCanvas from "../canvas/Stars"; 15 | 16 | const HeroContainer = styled.div` 17 | display: flex; 18 | justify-content: center; 19 | position: relative; 20 | padding: 80px 30px; 21 | z-index: 1; 22 | 23 | @media (max-width: 960px) { 24 | padding: 66px 16px; 25 | } 26 | 27 | @media (max-width: 640px) { 28 | padding: 32px 16px; 29 | } 30 | 31 | clip-path: polygon(0 0, 100% 0, 100% 100%, 70% 95%, 0 100%); 32 | `; 33 | const HeroInnerContainer = styled.div` 34 | position: relative; 35 | display: flex; 36 | justify-content: space-between; 37 | align-items: center; 38 | width: 100%; 39 | max-width: 1100px; 40 | 41 | @media (max-width: 960px) { 42 | flex-direction: column; 43 | } 44 | `; 45 | const HeroLeftContainer = styled.div` 46 | width: 100%; 47 | order: 1; 48 | @media (max-width: 960px) { 49 | order: 2; 50 | margin-bottom: 30px; 51 | display: flex; 52 | gap: 6px; 53 | flex-direction: column; 54 | align-items: center; 55 | } 56 | `; 57 | const HeroRightContainer = styled.div` 58 | width: 100%; 59 | order: 2; 60 | display: flex; 61 | justify-content: end; 62 | @media (max-width: 960px) { 63 | order: 1; 64 | display: flex; 65 | flex-direction: column; 66 | align-items: center; 67 | justify-contents: center; 68 | margin-bottom: 80px; 69 | } 70 | 71 | @media (max-width: 640px) { 72 | margin-bottom: 30px; 73 | } 74 | `; 75 | 76 | const Title = styled.div` 77 | font-weight: 700; 78 | font-size: 50px; 79 | color: ${({ theme }) => theme.text_primary}; 80 | line-height: 68px; 81 | 82 | @media (max-width: 960px) { 83 | text-align: center; 84 | } 85 | 86 | @media (max-width: 960px) { 87 | font-size: 40px; 88 | line-height: 48px; 89 | margin-bottom: 8px; 90 | } 91 | `; 92 | 93 | const TextLoop = styled.div` 94 | font-weight: 600; 95 | font-size: 32px; 96 | display: flex; 97 | gap: 12px; 98 | color: ${({ theme }) => theme.text_primary}; 99 | line-height: 68px; 100 | 101 | @media (max-width: 960px) { 102 | text-align: center; 103 | } 104 | 105 | @media (max-width: 960px) { 106 | font-size: 22px; 107 | line-height: 48px; 108 | margin-bottom: 16px; 109 | } 110 | `; 111 | 112 | const Span = styled.div` 113 | cursor: pointer; 114 | color: ${({ theme }) => theme.primary}; 115 | `; 116 | 117 | const SubTitle = styled.div` 118 | font-size: 20px; 119 | line-height: 32px; 120 | margin-bottom: 42px; 121 | color: ${({ theme }) => theme.text_primary + 95}; 122 | 123 | @media (max-width: 960px) { 124 | text-align: center; 125 | } 126 | 127 | @media (max-width: 960px) { 128 | font-size: 16px; 129 | line-height: 32px; 130 | } 131 | `; 132 | 133 | const ResumeButton = styled.a` 134 | -webkit-appearance: button; 135 | -moz-appearance: button; 136 | appearance: button; 137 | text-decoration: none; 138 | 139 | width: 95%; 140 | max-width: 300px; 141 | text-align: center; 142 | padding: 16px 0; 143 | 144 | background: hsla(271, 100%, 50%, 1); 145 | background: linear-gradient( 146 | 225deg, 147 | hsla(271, 100%, 50%, 1) 0%, 148 | hsla(294, 100%, 50%, 1) 100% 149 | ); 150 | background: -moz-linear-gradient( 151 | 225deg, 152 | hsla(271, 100%, 50%, 1) 0%, 153 | hsla(294, 100%, 50%, 1) 100% 154 | ); 155 | background: -webkit-linear-gradient( 156 | 225deg, 157 | hsla(271, 100%, 50%, 1) 0%, 158 | hsla(294, 100%, 50%, 1) 100% 159 | ); 160 | box-shadow: 20px 20px 60px #1f2634, -20px -20px 60px #1f2634; 161 | border-radius: 50px; 162 | font-weight: 600; 163 | font-size: 20px; 164 | 165 | &:hover { 166 | transform: scale(1.05); 167 | transition: all 0.4s ease-in-out; 168 | box-shadow: 20px 20px 60px #1F2634, 169 | filter: brightness(1); 170 | } 171 | 172 | 173 | @media (max-width: 640px) { 174 | padding: 12px 0; 175 | font-size: 18px; 176 | } 177 | color: white; 178 | `; 179 | 180 | const Img = styled.img` 181 | border-radius: 50%; 182 | width: 300px; 183 | max-width: 400px; 184 | max-height: 400px; 185 | border: 2px solid ${({ theme }) => theme.primary}; 186 | 187 | @media (max-width: 640px) { 188 | max-width: 280px; 189 | max-height: 280px; 190 | } 191 | `; 192 | 193 | const HeroBg = styled.div` 194 | position: absolute; 195 | display: flex; 196 | justify-content: end; 197 | top: 0; 198 | right: 0; 199 | bottom: 0; 200 | left: 0; 201 | width: 100%; 202 | height: 100%; 203 | max-width: 1360px; 204 | overflow: hidden; 205 | padding: 0 30px; 206 | top: 50%; 207 | left: 50%; 208 | -webkit-transform: translateX(-50%) translateY(-50%); 209 | transform: translateX(-50%) translateY(-50%); 210 | 211 | @media (max-width: 960px) { 212 | justify-content: center; 213 | padding: 0 0px; 214 | } 215 | `; 216 | 217 | const Hero = () => { 218 | return ( 219 |
220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | Hi, I am <br /> {Bio.name} 232 | 233 | 234 | I am a 235 | 236 | 243 | 244 | 245 | 246 | 247 | 248 | {Bio.description} 249 | 250 | 251 | 252 | Check Resume 253 | 254 | 255 | 256 | 257 | 258 | Anh Quan Khuat 259 | 260 | 261 | 262 | 263 | 264 | 265 |
266 | ); 267 | }; 268 | 269 | export default Hero; 270 | -------------------------------------------------------------------------------- /src/components/sections/Projects.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import styled from "styled-components"; 3 | import { projects } from "../../data/constants"; 4 | import ProjectCard from "../cards/ProjectCard"; 5 | 6 | const Container = styled.div` 7 | margin-top: 100px; 8 | display: flex; 9 | flex-direction: column; 10 | justify-content-center; 11 | position: relative; 12 | z-index: 1; 13 | padding: 0 16px; 14 | align-items: center; 15 | `; 16 | const Wrapper = styled.div` 17 | position: relative; 18 | display: flex; 19 | justify-content: space-between; 20 | align-items: center; 21 | flex-direction: column; 22 | width: 100%; 23 | max-width: 1100px; 24 | gap: 12px; 25 | @media (max-width: 960px) { 26 | flex-direction: column; 27 | } 28 | `; 29 | 30 | const Title = styled.div` 31 | font-size: 52px; 32 | text-align: center; 33 | font-weight: 600; 34 | margin-top: 20px; 35 | color: ${({ theme }) => theme.text_primary}; 36 | @media (max-width: 768px) { 37 | margin-top: 12px; 38 | font-size: 32px; 39 | } 40 | `; 41 | 42 | const Desc = styled.div` 43 | font-size: 18px; 44 | text-align: center; 45 | font-weight: 600; 46 | color: ${({ theme }) => theme.text_secondary}; 47 | @media (max-width: 768px) { 48 | font-size: 16px; 49 | } 50 | `; 51 | 52 | const ToggleButtonGroup = styled.div` 53 | display: flex; 54 | border: 1.5px solid ${({ theme }) => theme.primary}; 55 | color: ${({ theme }) => theme.primary}; 56 | font-size: 16px; 57 | border-radius: 12px; 58 | font-weight 500; 59 | margin: 22px 0; 60 | @media (max-width: 768px){ 61 | font-size: 12px; 62 | } 63 | `; 64 | 65 | const ToggleButton = styled.div` 66 | padding: 8px 18px; 67 | border-radius: 6px; 68 | cursor: pointer; 69 | &:hover { 70 | background: ${({ theme }) => theme.primary + 20}; 71 | } 72 | @media (max-width: 768px) { 73 | padding: 6px 8px; 74 | border-radius: 4px; 75 | } 76 | ${({ active, theme }) => 77 | active && 78 | ` 79 | background: ${theme.primary + 20}; 80 | `} 81 | `; 82 | 83 | const Divider = styled.div` 84 | width: 1.5px; 85 | background: ${({ theme }) => theme.primary}; 86 | `; 87 | 88 | const CardContainer = styled.div` 89 | display: flex; 90 | justify-content: center; 91 | align-items: center; 92 | gap: 28px; 93 | flex-wrap: wrap; 94 | `; 95 | 96 | const Projects = ({ openModal, setOpenModal }) => { 97 | const [toggle, setToggle] = useState("all"); 98 | return ( 99 | 100 | 101 | Projects 102 | 107 | I have worked on a wide range of projects. From web apps to android 108 | apps. Here are some of my projects. 109 | 110 | 111 | setToggle("all")} 114 | > 115 | ALL 116 | 117 | 118 | setToggle("web app")} 121 | > 122 | WEB APP"S 123 | 124 | 125 | setToggle("android app")} 128 | > 129 | ANDROID APP'S 130 | 131 | 132 | setToggle("machine learning")} 135 | > 136 | MACHINE LEARNING 137 | 138 | 139 | 140 | {toggle === "all" && 141 | projects.map((project) => ( 142 | 147 | ))} 148 | {projects 149 | .filter((item) => item.category === toggle) 150 | .map((project) => ( 151 | 156 | ))} 157 | 158 | 159 | 160 | ); 161 | }; 162 | 163 | export default Projects; 164 | -------------------------------------------------------------------------------- /src/components/sections/Skills.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | import { skills } from "../../data/constants"; 4 | import { Tilt } from "react-tilt"; 5 | 6 | const Container = styled.div` 7 | display: flex; 8 | flex-direction: column; 9 | justify-content-center; 10 | position: relative; 11 | z-index: 1; 12 | align-items: center; 13 | `; 14 | const Wrapper = styled.div` 15 | position: relative; 16 | display: flex; 17 | justify-content: space-between; 18 | align-items: center; 19 | flex-direction: column; 20 | width: 100%; 21 | max-width: 1100px; 22 | gap: 12px; 23 | @media (max-width: 960px) { 24 | flex-direction: column; 25 | } 26 | `; 27 | 28 | const Title = styled.div` 29 | font-size: 52px; 30 | text-align: center; 31 | font-weight: 600; 32 | margin-top: 20px; 33 | color: ${({ theme }) => theme.text_primary}; 34 | @media (max-width: 768px) { 35 | margin-top: 12px; 36 | font-size: 32px; 37 | } 38 | `; 39 | 40 | const Desc = styled.div` 41 | font-size: 18px; 42 | text-align: center; 43 | font-weight: 600; 44 | color: ${({ theme }) => theme.text_secondary}; 45 | @media (max-width: 768px) { 46 | font-size: 16px; 47 | } 48 | `; 49 | 50 | const SkillsContainer = styled.div` 51 | width: 100%; 52 | display: flex; 53 | flex-wrap: wrap; 54 | margin-top: 20px; 55 | gap: 50px; 56 | justify-content: center; 57 | `; 58 | const Skill = styled.div` 59 | width: 100%; 60 | max-width: 500px; 61 | background-color: rgba(17, 25, 40, 0.83); 62 | border: 1px solid rgba(255, 255, 255, 0.125); 63 | box-shadow: rgba(23, 92, 230, 0.15) 0px 4px 24px; 64 | border-radius: 16px; 65 | padding: 18px 36px; 66 | 67 | @media (max-width: 768px) { 68 | max-width: 400px; 69 | padding: 10px 36px; 70 | } 71 | 72 | @media (max-width: 500px) { 73 | max-width: 330px; 74 | padding: 10px 36px; 75 | } 76 | `; 77 | 78 | const SkillTitle = styled.div` 79 | font-size: 28px; 80 | font-weight: 600; 81 | margin-bottom: 20px; 82 | text-align: center; 83 | color: ${({ theme }) => theme.text_secondary}; 84 | `; 85 | 86 | const SkillList = styled.div` 87 | display: flex; 88 | justify-content: center; 89 | flex-wrap: wrap; 90 | gap: 12px; 91 | margin-bottom: 20px; 92 | `; 93 | const SkillItem = styled.div` 94 | font-size: 16px; 95 | font-weight: 400; 96 | color: ${({ theme }) => theme.text_primary + 80}; 97 | border: 1px solid ${({ theme }) => theme.text_primary + 80}; 98 | border-radius: 12px; 99 | padding: 12px 16px; 100 | display: flex; 101 | align-items: center; 102 | justify-content: center; 103 | gap: 8px; 104 | 105 | @media (max-width: 768px) { 106 | font-size: 14px; 107 | padding: 8px 12px; 108 | } 109 | @media (max-width: 500px) { 110 | font-size: 14px; 111 | padding: 6px 12px; 112 | } 113 | `; 114 | 115 | const SkillImage = styled.img` 116 | width: 24px; 117 | height: 24px; 118 | `; 119 | 120 | const Skills = () => { 121 | return ( 122 | 123 | 124 | Skills 125 | 130 | Here are some of my skills on which I have been working on for the 131 | past 3 years. 132 | 133 | 134 | 135 | {skills.map((skill, index) => ( 136 | 137 | 138 | {skill.title} 139 | 140 | {skill.skills.map((item, index_x) => ( 141 | 142 | 143 | {item.name} 144 | 145 | ))} 146 | 147 | 148 | 149 | ))} 150 | 151 | 152 | 153 | ); 154 | }; 155 | 156 | export default Skills; 157 | -------------------------------------------------------------------------------- /src/data/constants.js: -------------------------------------------------------------------------------- 1 | import angularpic from "../images/icons8-angularjs-48.png"; 2 | import flutterpic from "../images/flutterpic.png"; 3 | import vuepic from "../images/vuepic.png"; 4 | import expresspic from "../images/expresspic.png"; 5 | import djangopic from "../images/djangopic.png"; 6 | import jetpackpic from "../images/jetpackpic.png"; 7 | import keraspic from "../images/keraspic.png"; 8 | import copic from "../images/copic.png"; 9 | import xdpic from "../images/xdpic.png"; 10 | import school from "../images/school.png"; 11 | 12 | export const Bio = { 13 | name: "Anh Quan Khuat", 14 | roles: [ 15 | "Full Stack Developer", 16 | "Android Developer", 17 | "AI Developer", 18 | "UI/UX Designer", 19 | "Programmer", 20 | ], 21 | description: 22 | "I am a motivated and versatile individual, always eager to take on new challenges. With a passion for learning I am dedicated to delivering high-quality results. With a positive attitude and a growth mindset, I am ready to make a meaningful contribution and achieve great things.", 23 | github: "https://github.com/Locklee-ss", 24 | resume: 25 | "https://docs.google.com/document/d/192_k3-53Zam2z_tY-oavdgywfWOyim5r/edit?usp=sharing&ouid=115166127635866652406&rtpof=true&sd=true", 26 | linkedin: "https://www.linkedin.com/in/rishav-chanda-b89a791b3/", 27 | twitter: "https://twitter.com/RishavChanda", 28 | insta: "https://www.instagram.com/rishav_chanda/", 29 | facebook: "https://www.facebook.com/rishav.chanda.165/", 30 | telegram: "https://t.me/@madara971123/", 31 | skype: "https://join.skype.com/invite/live:.cid.b27ef7e9762399be", 32 | }; 33 | 34 | export const skills = [ 35 | { 36 | title: "Frontend", 37 | skills: [ 38 | { 39 | name: "React Js", 40 | image: 41 | "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii0xMS41IC0xMC4yMzE3NCAyMyAyMC40NjM0OCI+CiAgPHRpdGxlPlJlYWN0IExvZ288L3RpdGxlPgogIDxjaXJjbGUgY3g9IjAiIGN5PSIwIiByPSIyLjA1IiBmaWxsPSIjNjFkYWZiIi8+CiAgPGcgc3Ryb2tlPSIjNjFkYWZiIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiPgogICAgPGVsbGlwc2Ugcng9IjExIiByeT0iNC4yIi8+CiAgICA8ZWxsaXBzZSByeD0iMTEiIHJ5PSI0LjIiIHRyYW5zZm9ybT0icm90YXRlKDYwKSIvPgogICAgPGVsbGlwc2Ugcng9IjExIiByeT0iNC4yIiB0cmFuc2Zvcm09InJvdGF0ZSgxMjApIi8+CiAgPC9nPgo8L3N2Zz4K", 42 | }, 43 | { 44 | name: "Redux", 45 | image: 46 | "https://d33wubrfki0l68.cloudfront.net/0834d0215db51e91525a25acf97433051f280f2f/c30f5/img/redux.svg", 47 | }, 48 | { 49 | name: "Next Js", 50 | image: 51 | "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACTklEQVR4Ab1XAaQqURB9DyohSykREpRIQSAlBCoECKUFCSRCBBEAaSEABQEoCIEASCwAUICALgCo83do0//9v819XX845O7VnDkzOzP7JWGaBd3C3IJpQVjAHeJ+Rs9a97vKLGrBsB1KgMhEP3FMUUwt4ENMfxr1yQIU4SSjRkbeOZtERmHk6pXQVDlnkHh9S+QLTm1hkiz4n/gzFQuny9FoFLquE+i34x+n02k0m00UCoV3BIzn3MMJrVYLtp1OJ0cS/X4f5/MZhmG8IyDsWtDfEaDIn2232/3zbrvdxuFwwGg04qRBt+VnETBNE0IIkE2n07/erdfrWK/X6Ha73Hb9ZXII3G43ivy3dNRqtZe7lUoFs9mM6oBDwCQCgquALT1FT3a5XF7qIZ/PYzgcolqtcggIIgBZAgRKB6lCRalp2uM8k8mAVMrlchwC+DEBipycE4n5fP44j8ViKJVKSCaTbAJCpgaez4vFIsjoWa/XA50FAgEkEgmEw2F2CkxZBZ5Br5tt1ITcbjd8Ph88Hg+7CBefECCsVitS4aVJcV9D/VMCVITk/Hq9YrPZyBBo2a1YMGvAcQYcj0cCtWMugcdYNhjDiBrP25mx3++x3W6RzWZZ8isfxzQLlsslJpMJpYY5jhkqcOH1ejEYDDAej9FoNOByuZxGsfqVzC7KTqcDSkkqleKsZOqX0mAwiHK5DGrJfr+fs5SqX8sjkQji8ThCoRC+v78Za7l6JagrUh3YkUuZpqgwDaecc9VYSDoV5Fg+at7n+eLN57kuE/EvzHr/Kvs31aYAAAAASUVORK5CYII=", 52 | }, 53 | { 54 | name: "Angular Js", 55 | image:angularpic, 56 | }, 57 | { 58 | name: "Vue Js", 59 | image:vuepic, 60 | }, 61 | { 62 | name: "HTML", 63 | image: "https://www.w3.org/html/logo/badge/html5-badge-h-solo.png", 64 | }, 65 | { 66 | name: "CSS", 67 | image: 68 | "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/CSS3_logo_and_wordmark.svg/1452px-CSS3_logo_and_wordmark.svg.png", 69 | }, 70 | { 71 | name: "JavaScript", 72 | image: 73 | "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/JavaScript-logo.png/800px-JavaScript-logo.png", 74 | }, 75 | { 76 | name: "Bootstrap", 77 | image: 78 | "https://getbootstrap.com/docs/5.3/assets/brand/bootstrap-logo-shadow.png", 79 | }, 80 | { 81 | name: "Material UI", 82 | image: 83 | "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOAAAADgCAMAAAAt85rTAAAAh1BMVEX///8Af/8Ad/8AfP8Aev/v+P8Adf8Ae/+Puv8Adv+72P8Ac/87k/8Agf/t9f/6/f/U5v+lyf/m8f+10//H3v/C2/9Tnf9npv/e7P+w0P9+s/9Il/+Ywf8rjP8xkP/A2f8ch//Q4/9zrf94r/+HuP+dxP8JhP9aoP/a6f9Mmv+py/+Tv/8Ab/9IeMWVAAAHEElEQVR4nO2d6XqqMBBAJUQodcG1tlqpS2tre9//+W6oWgWyTAiB4DfnNwaOZiQkk6HTQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQZCm2X5Pu3Wda/Y91zl8Mhoan3KY9AghD8btQJgeAhL5YMVtEgTRp+GXHx9Cj0EGU7N2AHz1g/RUXm8EOry76PnsaHqIjc76SrwTQQI7b1nO18vw+5Djx4SeDifvRuc9ns/KzhsszDu8kFcSXk7kRerfZLsmf9e1MTpx8ifoeSH5MWpLzOOBXE/jEVVYxX+/9q+h0alvBW2F4tcq8DwNwb/eWb0g6z79qkOxuwty55ALjtYke3i1gp7fW1R6V/ygNHcGqWA30zttCLJQjF6Nmrzl7UAK7csEx1FYOLxyQXYFhzejRi8854JPKbjjHW9BkN0VV89GzabE+3zwqQTnPd7hVgRZKO4MQzH3XwgRXBT7pzVBNkaiHwbtzjec4FMJ9rkXY0vQJBQnT4X/QhcF2eitVCjGS5meS4Kp4l47FMe+KPgcFNQPxVl+INKw4FolmIYi/ClcHnyOCrJ+eoSFYvweAZpzTzBVXAKeq79VweeuYBqKY0VL23UEa0pXMKxFkF3WeiZpZ/gpGJeZCw5qEmSjt6eJqJl3zlNARYJ0UZdgqsgPxRdg8JUR9CPht1q9IPs6ve9CE9sEGnwlBKm/NfLTFfS8KBeKw+IjeHWCoi5jU5Cd9POm0zwEGsGnKxj1zZ9K9QXT6cX38/c6HSjHZeUFqfdirFdO8DcUmeKsz52RqEawgt5pIMgukhwoKftZkeDq2mAVcyZGgiYIBZeXu001vfOXTf1+YsHJqctX1TvdE+zMCQ1pZb3TQcHO8Gex11oDbptg9aAgCrZX0De5Rco+7IYgJUk/LDPSPH14nRTXBZ0SjH4nfKHTSFnYjZp9OP4RPSa6IEjPuRvxkug+DvnBZWZjKjB0QfA60TN5gs8m/V795vpAfOR/0gHBcHdzyEyyEpYnO9H/zf+gA4I0m7umXE45k1+qeXRA8AARVC6InSiMktsjyELxqFLkLJe2SVC+KJ0GHyf3ZNoqQW5OzxlB9lDbBDvxjt9Pg/4X9/jWCfJTe8QZfC0UZH8cuanQMBDnYLZSMJvbyoJPkkXbUsFOd3EZvUXyPGhTwfnuacmPbjhlBDudUcIUfeIrZi/NBFm8hz7tmeRbdcoKsms/HhJlArSJYPfyj92TLSyrGZQUBGEgeL3n+k9G1+CmYHbUZHQNVgVfygk+Z8e9Zmkk7gnG+1w20Z0JFp8970qQN3twT4LchIY7Elxwj78fwck/7uH3Iyg4/H4EBbOMZoLcJlEQxvNKb2a7ZYLCnT13Iije2XMXgtL1DJHguDWCis0FbRdULmS0XFC9FFWrIP+7Li8I2NkjFuR/My4Jgnb2tFcwfodlkLZVEJySUatg2XnRAjPwzh5hLQsrgntuo9qCk0/45gJ/JWjEiuCQcrfTaApq7ewR1pP5sCHYeeYNqvQEtXb2UF84FW9HkHtn1hEc6ezs8SNJOrYtQc7YCi6otbNHtn/NpmDxBg0W1NrZI9+BaFUw/3wDFNTa2UND1R5Sq4Lpn/S1fQqpfTRKNHb2QPZCWBZkofi36hEAUvvn/zSCD7SP27Zgmq91mkYJ14CDBXlaPMgGtBfCvmAaigGlwQZSfwwsSAlwmb0OQfbHsVzCKnMBBf0AXJimHkEwMMFgBc8DeW2foF6dNn5BIIcFQ16KpZihYETrqqA8y4sDvw6Cs4KKLK8CbwPRoM9JQV+zSGK+/KHrgv5Ga49qV7hO46og0coRFKdKuyroJxrtyJPd3RQM4RVSLsPfdgn6R2AboA0nDgp6FDb8HMuDz2FBUB+FrNO4KugRZf1v2DqNs4Kqis/xErwr0bAMdXlUY1HZk8TYg08V11Smvoj6aUJUfF1nx6VH9QZFFQJ4HuQWX59oVGBLW2jKD/ZEHxY6mNY6TbQ2rMllAnBOJlv7Rm+dprqyOWUAz6pFyeVngJc/9G5LYzXEF7dmNI/zs73OImmuuFkzaJSDCnv9Rb/XluC7MNGJJz/UKDfAKzDYBJzC+1VQac0qQ0YlS8dJ9aSLpLVTrvifGNUiaQP86Px5KKBEtUjaBJWFIqxUchNoJVqI9Y5OBV+WqWcaijrlyhvhQbt00C00NNyLXAPDhV7poBvKvDKgCbTSLm7oVVqt0Spl7orOB18W3VA0e/FKE2gmr5m+OqcJ4APUakul1sgLKBTJ4bHpCy2PeoAaBtW9gKwJFKHYzuDLIhugRoIiUC1jKpigr+ONqjXBuyvaexFnExQGqHZfpdoE2ddt2H4ZbiNcB6hk0OhcvD1OoRhGD47OSJjDQrF3d8GXw+H5FgRBEARBEARBEARBEARBEARBEARBEARBEMZ/Z7h0SlKcxhsAAAAASUVORK5CYII=", 84 | }, 85 | { 86 | name: "Flutter", 87 | image:flutterpic, 88 | }, 89 | ], 90 | }, 91 | { 92 | title: "Backend", 93 | skills: [ 94 | { 95 | name: "Node Js", 96 | image: "https://nodejs.org/static/images/logo.svg", 97 | }, 98 | { 99 | name: "Express Js", 100 | image:expresspic, 101 | }, 102 | { 103 | name: "Graph Ql", 104 | image: "https://www.vectorlogo.zone/logos/graphql/graphql-icon.svg", 105 | }, 106 | { 107 | name: "Python", 108 | image: 109 | "https://raw.githubusercontent.com/devicons/devicon/master/icons/python/python-original.svg", 110 | }, 111 | { 112 | name: "Flask", 113 | image: 114 | "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3c/Flask_logo.svg/1280px-Flask_logo.svg.png", 115 | }, 116 | { 117 | name: "Django", 118 | image:djangopic, 119 | }, 120 | { 121 | name: "MySQL", 122 | image: 123 | "https://raw.githubusercontent.com/devicons/devicon/master/icons/mysql/mysql-original-wordmark.svg", 124 | }, 125 | { 126 | name: "Postgresql", 127 | image: "https://www.postgresql.org/media/img/about/press/elephant.png", 128 | }, 129 | { 130 | name: "MongoDB", 131 | image: 132 | "https://raw.githubusercontent.com/devicons/devicon/master/icons/mongodb/mongodb-original-wordmark.svg", 133 | }, 134 | { 135 | name: "Firebase", 136 | image: "https://www.vectorlogo.zone/logos/firebase/firebase-icon.svg", 137 | }, 138 | ], 139 | }, 140 | { 141 | title: "DevOps", 142 | skills: [ 143 | { 144 | name: "AWS", 145 | image: 146 | "https://download.logo.wine/logo/Amazon_Web_Services/Amazon_Web_Services-Logo.wine.png", 147 | }, 148 | { 149 | name: "Google Cloud", 150 | image: 151 | "https://static-00.iconduck.com/assets.00/google-cloud-platform-logo-icon-2048x1824-pg4wzspq.png", 152 | }, 153 | { 154 | name: "Docker", 155 | image: 156 | "https://raw.githubusercontent.com/devicons/devicon/master/icons/docker/docker-original-wordmark.svg", 157 | }, 158 | { 159 | name: "Jenkins", 160 | image: 161 | "https://toppng.com/uploads/preview/jenkins-logo-11609365847mufysaivph.png", 162 | }, 163 | { 164 | name: "Nginx", 165 | image: "https://download.logo.wine/logo/Nginx/Nginx-Logo.wine.png", 166 | }, 167 | { 168 | name: "Grafana", 169 | image: 170 | "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a1/Grafana_logo.svg/1200px-Grafana_logo.svg.png", 171 | }, 172 | { 173 | name: "Kubernetes", 174 | image: 175 | "https://upload.wikimedia.org/wikipedia/commons/0/00/Kubernetes_%28container_engine%29.png", 176 | }, 177 | { 178 | name: "Prometheus", 179 | image: 180 | "https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Prometheus_software_logo.svg/1200px-Prometheus_software_logo.svg.png", 181 | }, 182 | ], 183 | }, 184 | { 185 | title: "Android", 186 | skills: [ 187 | { 188 | name: "Java", 189 | image: 190 | "https://raw.githubusercontent.com/devicons/devicon/master/icons/java/java-original.svg", 191 | }, 192 | { 193 | name: "Kotlin", 194 | image: 195 | "https://www.vectorlogo.zone/logos/kotlinlang/kotlinlang-icon.svg", 196 | }, 197 | { 198 | name: "Jetpack Compose", 199 | image:jetpackpic, 200 | }, 201 | { 202 | name: "XML", 203 | image: 204 | "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSBMw6_RdwKQ9bDFfnKDX1iwMl4bVJEvd9PP53XuIw&s", 205 | }, 206 | { 207 | name: "Android Studio", 208 | image: 209 | "https://developer.android.com/static/studio/images/new-studio-logo-1_1920.png", 210 | }, 211 | ], 212 | }, 213 | { 214 | title: "Machine Learning", 215 | skills: [ 216 | { 217 | name: "Python", 218 | image: 219 | "https://raw.githubusercontent.com/devicons/devicon/master/icons/python/python-original.svg", 220 | }, 221 | { 222 | name: "Tenserflow", 223 | image: 224 | "https://static-00.iconduck.com/assets.00/tensorflow-icon-1911x2048-1m2s54vn.png", 225 | }, 226 | { 227 | name: "Keras", 228 | image:keraspic, 229 | }, 230 | { 231 | name: "Jupyter", 232 | image: 233 | "https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Jupyter_logo.svg/1767px-Jupyter_logo.svg.png", 234 | }, 235 | { 236 | name: "Google Colab", 237 | image:copic, 238 | }, 239 | { 240 | name: "Sk Learn Kit", 241 | image: 242 | "https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Scikit_learn_logo_small.svg/2560px-Scikit_learn_logo_small.svg.png", 243 | }, 244 | ], 245 | }, 246 | { 247 | title: "Others", 248 | skills: [ 249 | { 250 | name: "Git", 251 | image: 252 | "https://e7.pngegg.com/pngimages/713/558/png-clipart-computer-icons-pro-git-github-logo-text-logo-thumbnail.png", 253 | }, 254 | { 255 | name: "GitHub", 256 | image: 257 | "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png", 258 | }, 259 | { 260 | name: "Netlify", 261 | image: 262 | "https://seeklogo.com/images/N/netlify-logo-BD8F8A77E2-seeklogo.com.png", 263 | }, 264 | { 265 | name: "VS Code", 266 | image: 267 | "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Visual_Studio_Code_1.35_icon.svg/512px-Visual_Studio_Code_1.35_icon.svg.png?20210804221519", 268 | }, 269 | { 270 | name: "Postman", 271 | image: 272 | "https://static-00.iconduck.com/assets.00/postman-icon-497x512-beb7sy75.png", 273 | }, 274 | { 275 | name: "Adobe XD", 276 | image:xdpic, 277 | }, 278 | { 279 | name: "Figma", 280 | image: 281 | "https://s3-alpha.figma.com/hub/file/1481185752/fa4cd070-6a79-4e1b-b079-8b9b76408595-cover.png", 282 | }, 283 | ], 284 | }, 285 | ]; 286 | 287 | export const experiences = [ 288 | { 289 | id: 0, 290 | img: "https://firebasestorage.googleapis.com/v0/b/flexi-coding.appspot.com/o/neurobit.jpeg?alt=media&token=1cacbb7b-e5ea-4efb-9b3d-f5a31b9564ad", 291 | role: "Frontend Engineer Intern", 292 | company: "Neurobit", 293 | date: "June 2023 - Nov 2023", 294 | desc: "Enhanced user experiences on Neurobit PSG & Hybrid, Portals by resolving bugs & reduced load time by 40%. Built Neurobit Analytics portal using React Js with seamless interaction of REST APIs using AXIOS optimized with React Query. Refactored previous code to TypeScript, updated with new dependency and integrated Vite with Jest for Unit Testing.", 295 | skills: [ 296 | "ReactJS", 297 | "Redux", 298 | "NodeJs", 299 | "Material UI", 300 | "HTML", 301 | "CSS", 302 | "JavaScript", 303 | ], 304 | doc: "https://firebasestorage.googleapis.com/v0/b/flexi-coding.appspot.com/o/Screenshot%20from%202024-01-25%2022-38-31.png?alt=media&token=2785903f-1a4e-41f5-afd2-6adcfe56d058", 305 | }, 306 | { 307 | id: 1, 308 | img: "https://firebasestorage.googleapis.com/v0/b/flexi-coding.appspot.com/o/flipr.jpeg?alt=media&token=1d72532a-45eb-4c1a-a81a-c9bed9fec543", 309 | role: "DevOps & Fullstack Engineering Intern", 310 | company: "Flipr Inovations Pvt. Ltd.", 311 | date: "Aug 2023 - Oct 2023", 312 | desc: "Built Flipr Connect Platforms using React Js integrated GraphQL with AXIOS, created High level Design and Figma design. Built Backend with GraphQL and Node JS and connected with MongoDb - Reducing API calls by 20%. Dockerized and automated with Kubernetes & Jenkins CI/CD deployed in AWS-EC2 added Prometheus & Grafana for monitoring.", 313 | skills: [ 314 | "Docker", 315 | "Terraform", 316 | "AWS", 317 | "EC2", 318 | "Portainer", 319 | "Nginx", 320 | "JavaScript", 321 | "TypeScript", 322 | "Node Js", 323 | " Next Js", 324 | ], 325 | doc: "https://firebasestorage.googleapis.com/v0/b/flexi-coding.appspot.com/o/1696514649120.jpeg?alt=media&token=e7f6757b-edfa-4138-a692-d6709eeef3e2", 326 | }, 327 | { 328 | id: 2, 329 | img: "https://firebasestorage.googleapis.com/v0/b/flexi-coding.appspot.com/o/Rudraksha.jpeg?alt=media&token=8f83f41e-d0a1-486f-9c7f-dd4cd1d09e8d", 330 | role: "Android Developer Intern", 331 | company: "Rudraksha Welffare Foundation", 332 | date: "June 2021 - Oct 2021", 333 | desc: "• Built RudraShakti - Astrologer App, with MVVM Architecture using Java and Android Studio integrating Firebase SDK. Created One to One video call integration with Socket.IO and Firebase cloud functions and integrated with Retrofit. Created Low Level Design and converted Figma design to XML code.", 334 | skills: [ 335 | "Android", 336 | "Java", 337 | "Kotlin", 338 | "XML", 339 | "Node Js", 340 | "Cloud Firestore", 341 | "Firebase", 342 | "Figma", 343 | ], 344 | doc: "https://firebasestorage.googleapis.com/v0/b/buckoid-917cf.appspot.com/o/WhatsApp%20Image%202023-05-05%20at%2012.07.39%20AM.jpeg?alt=media&token=9f0e1648-568b-422d-bd0b-1f125f722245", 345 | }, 346 | { 347 | id: 3, 348 | img: "https://firebasestorage.googleapis.com/v0/b/flexi-coding.appspot.com/o/flipr.jpeg?alt=media&token=1d72532a-45eb-4c1a-a81a-c9bed9fec543", 349 | role: "Fullstack Externship", 350 | company: "Flipr", 351 | date: "June 2023 - July 2023", 352 | desc: "Built an employee management full stack web app used Docker and deployed on AWS ec2. I was the top performer in the program.", 353 | skills: [ 354 | "ReactJS", 355 | "Redux", 356 | "NodeJs", 357 | "Material UI", 358 | "HTML", 359 | "CSS", 360 | "JavaScript", 361 | "Docker", 362 | "AWS", 363 | "MongoDB", 364 | ], 365 | doc: "https://firebasestorage.googleapis.com/v0/b/flexi-coding.appspot.com/o/1691181448873.jpeg?alt=media&token=ee85eb8f-7247-43cd-9a1d-ce9f58ea62a6", 366 | }, 367 | { 368 | id: 4, 369 | img: "https://firebasestorage.googleapis.com/v0/b/flexi-coding.appspot.com/o/gdsc.jpeg?alt=media&token=c162329c-efaa-4be8-a173-8d3f4c48ea70", 370 | role: "Android Developer", 371 | company: "DSC KIIT", 372 | date: "Nov2021 - Present", 373 | desc: "As an Android developer at the Google Developers Student Club (GDCS), I have had the opportunity to work on exciting projects and collaborate with talented developers who share my passion for technology. Through my involvement with GDCS, I have also had the opportunity to host and participate in numerous events, including hackathons, study jams, and workshops.", 374 | skills: [ 375 | "Leadership", 376 | "Mobile Application Development", 377 | "Kotlin", 378 | "XML", 379 | "Figma", 380 | ], 381 | }, 382 | { 383 | id: 5, 384 | img: "https://firebasestorage.googleapis.com/v0/b/flexi-coding.appspot.com/o/girlScript.jpeg?alt=media&token=e656a621-cf3c-4230-bf0f-e74b4cec6035", 385 | role: "Open Source Contributor ", 386 | company: "GirlScript Summer of Code", 387 | date: "May 2023 - Present", 388 | desc: "Contributed to different open-source projects and learn from industry experts", 389 | }, 390 | ]; 391 | 392 | export const education = [ 393 | { 394 | id: 0, 395 | img: school, 396 | school: "Posts and Telecommunications Institute of Technology", 397 | date: "Oct 2019 - Sep 2023", 398 | grade: "3.4 GPA", 399 | desc: "I am currently pursuing a Bachelor's degree in Computer Science and Engineering at Posts and Telecommunications Institute of Technology, Hanoi. I have completed 8 semesters and have a GPA of 3.4. I have taken courses in Data Structures, Algorithms, Object-Oriented Programming, Database Management Systems, Operating Systems, and Computer Networks, among others. I am also a member of the Google Developers Student Club (GDSC) at KIIT, where I am learning and working on exciting projects with a team of talented developers.", 400 | degree: "Bachelor of Technology - BTech, Information Technology and Engineering", 401 | }, 402 | ]; 403 | 404 | export const projects = [ 405 | { 406 | id: 11, 407 | title: "DecisionHub", 408 | date: "Jan 2024 - Dec 2023", 409 | description: 410 | "A Rule Builder application “Decision Hub” that empowers Business Analysts to create, save, and visualize decision strategies. Provide a no-code rule writing experience and visual representation to test these rules in real-time and observe the calculations at each step.", 411 | image: 412 | "https://github.com/rishavchanda/DecisionHub/raw/master/assets/testRule.jpg", 413 | tags: [ 414 | "React Js", 415 | "PostgressSQL", 416 | "Node Js", 417 | "Express Js", 418 | "Redux", 419 | "React Flow", 420 | ], 421 | category: "web app", 422 | github: "https://github.com/rishavchanda/DecisionHub", 423 | webapp: "https://decisionhub.netlify.app/", 424 | }, 425 | 426 | ]; 427 | 428 | -------------------------------------------------------------------------------- /src/images/HeroImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-knight0227/reactproject/7ecc205f6cb5738843b6b6816284e7f708893710/src/images/HeroImage.png -------------------------------------------------------------------------------- /src/images/copic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-knight0227/reactproject/7ecc205f6cb5738843b6b6816284e7f708893710/src/images/copic.png -------------------------------------------------------------------------------- /src/images/djangopic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-knight0227/reactproject/7ecc205f6cb5738843b6b6816284e7f708893710/src/images/djangopic.png -------------------------------------------------------------------------------- /src/images/expresspic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-knight0227/reactproject/7ecc205f6cb5738843b6b6816284e7f708893710/src/images/expresspic.png -------------------------------------------------------------------------------- /src/images/flutterpic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-knight0227/reactproject/7ecc205f6cb5738843b6b6816284e7f708893710/src/images/flutterpic.png -------------------------------------------------------------------------------- /src/images/icons8-angularjs-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-knight0227/reactproject/7ecc205f6cb5738843b6b6816284e7f708893710/src/images/icons8-angularjs-48.png -------------------------------------------------------------------------------- /src/images/jetpackpic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-knight0227/reactproject/7ecc205f6cb5738843b6b6816284e7f708893710/src/images/jetpackpic.png -------------------------------------------------------------------------------- /src/images/keraspic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-knight0227/reactproject/7ecc205f6cb5738843b6b6816284e7f708893710/src/images/keraspic.png -------------------------------------------------------------------------------- /src/images/school.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-knight0227/reactproject/7ecc205f6cb5738843b6b6816284e7f708893710/src/images/school.png -------------------------------------------------------------------------------- /src/images/vuepic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-knight0227/reactproject/7ecc205f6cb5738843b6b6816284e7f708893710/src/images/vuepic.png -------------------------------------------------------------------------------- /src/images/xdpic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-knight0227/reactproject/7ecc205f6cb5738843b6b6816284e7f708893710/src/images/xdpic.png -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | margin: 0; 6 | padding: 0; 7 | scroll-behavior: smooth; 8 | font-family: "Poppins", sans-serif; 9 | } 10 | 11 | body { 12 | margin: 0px !important; 13 | padding: 0; 14 | font-family: "Montserrat", sans-serif; 15 | } 16 | 17 | /* width */ 18 | ::-webkit-scrollbar { 19 | width: 4px; 20 | height: 80px; 21 | } 22 | 23 | /* Track */ 24 | ::-webkit-scrollbar-track { 25 | background: #222a35; 26 | } 27 | 28 | /* Handle */ 29 | ::-webkit-scrollbar-thumb { 30 | background: #575c66; 31 | border-radius: 6px; 32 | } 33 | 34 | /* Handle on hover */ 35 | ::-webkit-scrollbar-thumb:hover { 36 | background: #626970; 37 | } 38 | 39 | ::-webkit-backdrop-filter { 40 | blur: 3px saturate(106%); 41 | } -------------------------------------------------------------------------------- /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 | 6 | const root = ReactDOM.createRoot(document.getElementById("root")); 7 | root.render( 8 | 9 | 10 | 11 | ); 12 | -------------------------------------------------------------------------------- /src/utils/Themes.js: -------------------------------------------------------------------------------- 1 | export const darkTheme = { 2 | bg: "#090917", 3 | bgLight: "#1C1E27", 4 | primary: "#854CE6", 5 | text_primary: "#F2F3F4", 6 | text_secondary: "#b1b2b3", 7 | card: "#171721", 8 | card_light: "#191924", 9 | button: "#854CE6", 10 | white: "#FFFFFF", 11 | black: "#000000", 12 | }; 13 | 14 | export const lightTheme = { 15 | bg: "#FFFFFF", 16 | bgLight: "#f0f0f0", 17 | primary: "#be1adb", 18 | text_primary: "#111111", 19 | text_secondary: "#48494a", 20 | card: "#FFFFFF", 21 | button: "#5c5b5b", 22 | }; 23 | -------------------------------------------------------------------------------- /src/utils/motion.js: -------------------------------------------------------------------------------- 1 | export const transition = { type: "spring", duration: 0.8 }; 2 | 3 | export const slideAnimation = (direction) => { 4 | return { 5 | initial: { 6 | x: direction === "left" ? -100 : direction === "right" ? 100 : 0, 7 | y: direction === "up" ? 100 : direction === "down" ? -100 : 0, 8 | opacity: 0, 9 | transition: { ...transition, delay: 0.5 }, 10 | }, 11 | animate: { 12 | x: 0, 13 | y: 0, 14 | opacity: 1, 15 | transition: { ...transition, delay: 0 }, 16 | }, 17 | exit: { 18 | x: direction === "left" ? -100 : direction === "right" ? 100 : 0, 19 | y: direction === "up" ? 100 : direction === "down" ? -100 : 0, 20 | transition: { ...transition, delay: 0 }, 21 | }, 22 | }; 23 | }; 24 | 25 | export const fadeAnimation = { 26 | initial: { 27 | opacity: 0, 28 | transition: { ...transition, delay: 0.5 }, 29 | }, 30 | animate: { 31 | opacity: 1, 32 | transition: { ...transition, delay: 0 }, 33 | }, 34 | exit: { 35 | opacity: 0, 36 | transition: { ...transition, delay: 0 }, 37 | }, 38 | }; 39 | 40 | export const headTextAnimation = { 41 | initial: { x: 100, opacity: 0 }, 42 | animate: { x: 0, opacity: 1 }, 43 | transition: { 44 | type: "spring", 45 | damping: 5, 46 | stiffness: 40, 47 | restDelta: 0.001, 48 | duration: 0.3, 49 | }, 50 | }; 51 | 52 | export const headContentAnimation = { 53 | initial: { y: 100, opacity: 0 }, 54 | animate: { y: 0, opacity: 1 }, 55 | transition: { 56 | type: "spring", 57 | damping: 7, 58 | stiffness: 30, 59 | restDelta: 0.001, 60 | duration: 0.6, 61 | delay: 0.2, 62 | delayChildren: 0.2, 63 | }, 64 | }; 65 | 66 | export const headContainerAnimation = { 67 | initial: { x: -100, opacity: 0, transition: { ...transition, delay: 0.5 } }, 68 | animate: { x: 0, opacity: 1, transition: { ...transition, delay: 0 } }, 69 | exit: { x: -100, opacity: 0, transition: { ...transition, delay: 0 } }, 70 | }; 71 | --------------------------------------------------------------------------------