diff --git a/.firebase/hosting.ZGlzdA.cache b/.firebase/hosting.ZGlzdA.cache
new file mode 100644
index 000000000..c7f98bf38
--- /dev/null
+++ b/.firebase/hosting.ZGlzdA.cache
@@ -0,0 +1,24 @@
+bill-buddy.PNG,1716259394717,d8bfd34842e82d01aa8b774c8c8f194c7dcdf1fa0639559e78e291a541cd15f3
+dribbble.png,1715822722700,3900f052127946acc93109e4306d256e7c64bf813a3552b2d0b724d8cb435235
+facebook.png,1715822722700,8fae4bd509b671599b967fed23ba0b194f3d300a422c6ecf7de2bcb10f86e2c6
+github.png,1716209714010,c3b7499f20ce14aebb3ae0587645656d3b98060f1e28718e354c8e17fd7abeb8
+gramedia-clone.PNG,1716260558324,233da44c66b46b5056cc453414306e31f2d43bf084008c88f06e9f69fd5f10e0
+instagram.png,1715822722706,b6c3746cfde243f49c19373084131652431370df3369030d95a72be1371b2a72
+linkedin-profile.JPG,1716256211783,4713d69301242dc6154b7680b8517ff769fa643eaacce0d94a9cff00fec2cd05
+linkedin.png,1716209656165,77ee2e58d0e97059ca7dbea1ba3fd01f0f6474809128bc5356e9bbca242bdb2d
+mountains.png,1715822722711,340d589d79cb7225c163f79b62fa9f9133c2bac37d26f1a53421b1628574bfdc
+other-project.jpg,1716260793678,1d6b80cd8c7308c7a7250f321f5c9f99b2f48fce11d3cbf57ae51c75d50afe66
+people.webp,1715822722713,61c8459e2b0767ff83720dfcc5ba8e3432b81cdc7c3b1d540b92e4d9ae1f35ef
+planets.png,1715822722713,c7a876b97c5e9ba96f0bd646e3ede17d00f29ce0a587039f24818bfa5c7c5a44
+qii-lain.png,1715905281724,2dca6ebddc600d6148c134f01b4a0887b925317e663567435fc4dad1bbdac852
+qii.png,1715903852559,2cca2dce605458df0900693434758e9a8f635a6ffc681447c775508232952d62
+qii2 - Copy.png,1715904822743,c3891ca2428be5a8980a3b1ca75d01124aca81203e59774910e173be05c838c3
+qii2-removebg.png,1715904985941,db96be1125e0c99210a269b04cfd8dd911014b57281635ad0f6e0072990dc24c
+qii2.png,1715904930406,a44e224465aeb4a3fe1ed0d8f53ab54bf145358fd5e8ba5bc20b90a72c556b16
+scroll.png,1715822722713,6010e02d6ca0e5c3862a7a492e1c1e06e8862e41f56221ffc211a8010e531bee
+stars.png,1715822722714,f3cf1f8d9daa1a33138c402d6b21f8183f30038b94864016e89dc6abb3a5927c
+sun.png,1715822722714,0b5bcded1652fc565af84d61f208547fa54acb8b2e9935f8d2ea336607525b8f
+youtube.png,1715822722714,7a79671141212d339037d5e3447cbd6cd61fb09e2e96d75a59a75adc2778cbda
+index.html,1716509777096,bd281eb08b1481528f1702bf39f5fc37fb6154f40e8007324ab7da223c2b13c4
+assets/index-c8065ce3.css,1716509777096,cf72a0011d69760a662604430419d19fcb234b7d6eb70beb8e8280e03dbef5b3
+assets/index-7406f3a5.js,1716509777096,ecad69c06bd2a762930cd76bf2123bd1afe8822d00edc44d4ca7ab854262d03e
diff --git a/.firebaserc b/.firebaserc
new file mode 100644
index 000000000..c9d2bddc2
--- /dev/null
+++ b/.firebaserc
@@ -0,0 +1,5 @@
+{
+ "projects": {
+ "default": "portfolio-qii"
+ }
+}
diff --git a/.gitignore b/.gitignore
index a547bf36d..3b0b40372 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,5 @@ dist-ssr
*.njsproj
*.sln
*.sw?
+
+.env
\ No newline at end of file
diff --git a/README.md b/README.md
index 48a70d937..69e1423d8 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1 @@
-# React + Vite
-
-This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
-
+# Riefqi Alviansyah Portfolio
diff --git a/firebase.json b/firebase.json
new file mode 100644
index 000000000..2c33c295f
--- /dev/null
+++ b/firebase.json
@@ -0,0 +1,16 @@
+{
+ "hosting": {
+ "public": "dist",
+ "ignore": [
+ "firebase.json",
+ "**/.*",
+ "**/node_modules/**"
+ ],
+ "rewrites": [
+ {
+ "source": "**",
+ "destination": "/index.html"
+ }
+ ]
+ }
+}
diff --git a/index.html b/index.html
index 438c9fe03..a4f86f05d 100644
--- a/index.html
+++ b/index.html
@@ -1,10 +1,13 @@
-
+
-
- Lama Dev Portfolio
+
+ Riefqi Alviansyah
diff --git a/package-lock.json b/package-lock.json
index 09f389b3c..9d3cc7503 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,18 +8,23 @@
"name": "starter",
"version": "0.0.0",
"dependencies": {
- "react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "@emailjs/browser": "^4.3.3",
+ "axios": "^1.7.2",
+ "framer-motion": "^10.16.4",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "react-icons": "^5.2.1",
+ "sass": "^1.68.0"
},
"devDependencies": {
- "@types/react": "^18.2.15",
- "@types/react-dom": "^18.2.7",
- "@vitejs/plugin-react": "^4.0.3",
- "eslint": "^8.45.0",
- "eslint-plugin-react": "^7.32.2",
- "eslint-plugin-react-hooks": "^4.6.0",
- "eslint-plugin-react-refresh": "^0.4.3",
- "vite": "^4.4.5"
+ "@types/react": "18.2.15",
+ "@types/react-dom": "18.2.7",
+ "@vitejs/plugin-react": "4.0.3",
+ "eslint": "8.45.0",
+ "eslint-plugin-react": "7.32.2",
+ "eslint-plugin-react-hooks": "4.6.0",
+ "eslint-plugin-react-refresh": "0.4.3",
+ "vite": "4.4.5"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@@ -371,6 +376,29 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@emailjs/browser": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@emailjs/browser/-/browser-4.3.3.tgz",
+ "integrity": "sha512-ltpt2S/WVREIBXptxYAVYBvXb2O6yTUYiRUWF8OLikMxlmiGsIgKpgHppikNd4Df0uAav7jCsQKcOJ3TJFUx5g==",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@emotion/is-prop-valid": {
+ "version": "0.8.8",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
+ "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
+ "optional": true,
+ "dependencies": {
+ "@emotion/memoize": "0.7.4"
+ }
+ },
+ "node_modules/@emotion/memoize": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
+ "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
+ "optional": true
+ },
"node_modules/@esbuild/android-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
@@ -786,9 +814,9 @@
}
},
"node_modules/@eslint/js": {
- "version": "8.51.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz",
- "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==",
+ "version": "8.44.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz",
+ "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -910,47 +938,6 @@
"node": ">= 8"
}
},
- "node_modules/@types/babel__core": {
- "version": "7.20.2",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.2.tgz",
- "integrity": "sha512-pNpr1T1xLUc2l3xJKuPtsEky3ybxN3m4fJkknfIpTCTfIZCDW57oAg+EfCgIIp2rvCe0Wn++/FfodDS4YXxBwA==",
- "dev": true,
- "dependencies": {
- "@babel/parser": "^7.20.7",
- "@babel/types": "^7.20.7",
- "@types/babel__generator": "*",
- "@types/babel__template": "*",
- "@types/babel__traverse": "*"
- }
- },
- "node_modules/@types/babel__generator": {
- "version": "7.6.5",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.5.tgz",
- "integrity": "sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.0.0"
- }
- },
- "node_modules/@types/babel__template": {
- "version": "7.4.2",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.2.tgz",
- "integrity": "sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ==",
- "dev": true,
- "dependencies": {
- "@babel/parser": "^7.1.0",
- "@babel/types": "^7.0.0"
- }
- },
- "node_modules/@types/babel__traverse": {
- "version": "7.20.2",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.2.tgz",
- "integrity": "sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.20.7"
- }
- },
"node_modules/@types/prop-types": {
"version": "15.7.8",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.8.tgz",
@@ -958,9 +945,9 @@
"dev": true
},
"node_modules/@types/react": {
- "version": "18.2.25",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.25.tgz",
- "integrity": "sha512-24xqse6+VByVLIr+xWaQ9muX1B4bXJKXBbjszbld/UEDslGLY53+ZucF44HCmLbMPejTzGG9XgR+3m2/Wqu1kw==",
+ "version": "18.2.15",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.15.tgz",
+ "integrity": "sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==",
"dev": true,
"dependencies": {
"@types/prop-types": "*",
@@ -969,9 +956,9 @@
}
},
"node_modules/@types/react-dom": {
- "version": "18.2.11",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.11.tgz",
- "integrity": "sha512-zq6Dy0EiCuF9pWFW6I6k6W2LdpUixLE4P6XjXU1QHLfak3GPACQfLwEuHzY5pOYa4hzj1d0GxX/P141aFjZsyg==",
+ "version": "18.2.7",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz",
+ "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==",
"dev": true,
"dependencies": {
"@types/react": "*"
@@ -984,15 +971,14 @@
"dev": true
},
"node_modules/@vitejs/plugin-react": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.1.0.tgz",
- "integrity": "sha512-rM0SqazU9iqPUraQ2JlIvReeaxOoRj6n+PzB1C0cBzIbd8qP336nC39/R9yPi3wVcah7E7j/kdU1uCUqMEU4OQ==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.0.3.tgz",
+ "integrity": "sha512-pwXDog5nwwvSIzwrvYYmA2Ljcd/ZNlcsSG2Q9CNDBwnsd55UGAyr2doXtB5j+2uymRCnCfExlznzzSFbBRcoCg==",
"dev": true,
"dependencies": {
- "@babel/core": "^7.22.20",
+ "@babel/core": "^7.22.5",
"@babel/plugin-transform-react-jsx-self": "^7.22.5",
"@babel/plugin-transform-react-jsx-source": "^7.22.5",
- "@types/babel__core": "^7.20.2",
"react-refresh": "^0.14.0"
},
"engines": {
@@ -1060,6 +1046,18 @@
"node": ">=4"
}
},
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -1168,14 +1166,10 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/asynciterator.prototype": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz",
- "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==",
- "dev": true,
- "dependencies": {
- "has-symbols": "^1.0.3"
- }
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/available-typed-arrays": {
"version": "1.0.5",
@@ -1189,12 +1183,33 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/axios": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
+ "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -1205,6 +1220,17 @@
"concat-map": "0.0.1"
}
},
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/browserslist": {
"version": "4.22.1",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
@@ -1293,6 +1319,40 @@
"node": ">=4"
}
},
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -1308,6 +1368,17 @@
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"dev": true
},
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -1394,6 +1465,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@@ -1465,28 +1544,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/es-iterator-helpers": {
- "version": "1.0.15",
- "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz",
- "integrity": "sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==",
- "dev": true,
- "dependencies": {
- "asynciterator.prototype": "^1.0.0",
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.22.1",
- "es-set-tostringtag": "^2.0.1",
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.2.1",
- "globalthis": "^1.0.3",
- "has-property-descriptors": "^1.0.0",
- "has-proto": "^1.0.1",
- "has-symbols": "^1.0.3",
- "internal-slot": "^1.0.5",
- "iterator.prototype": "^1.1.2",
- "safe-array-concat": "^1.0.1"
- }
- },
"node_modules/es-set-tostringtag": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
@@ -1583,27 +1640,27 @@
}
},
"node_modules/eslint": {
- "version": "8.51.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz",
- "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==",
+ "version": "8.45.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz",
+ "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
- "@eslint-community/regexpp": "^4.6.1",
- "@eslint/eslintrc": "^2.1.2",
- "@eslint/js": "8.51.0",
- "@humanwhocodes/config-array": "^0.11.11",
+ "@eslint-community/regexpp": "^4.4.0",
+ "@eslint/eslintrc": "^2.1.0",
+ "@eslint/js": "8.44.0",
+ "@humanwhocodes/config-array": "^0.11.10",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
- "ajv": "^6.12.4",
+ "ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
"debug": "^4.3.2",
"doctrine": "^3.0.0",
"escape-string-regexp": "^4.0.0",
- "eslint-scope": "^7.2.2",
- "eslint-visitor-keys": "^3.4.3",
- "espree": "^9.6.1",
+ "eslint-scope": "^7.2.0",
+ "eslint-visitor-keys": "^3.4.1",
+ "espree": "^9.6.0",
"esquery": "^1.4.2",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
@@ -1637,16 +1694,15 @@
}
},
"node_modules/eslint-plugin-react": {
- "version": "7.33.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz",
- "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==",
+ "version": "7.32.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz",
+ "integrity": "sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==",
"dev": true,
"dependencies": {
"array-includes": "^3.1.6",
"array.prototype.flatmap": "^1.3.1",
"array.prototype.tosorted": "^1.1.1",
"doctrine": "^2.1.0",
- "es-iterator-helpers": "^1.0.12",
"estraverse": "^5.3.0",
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
"minimatch": "^3.1.2",
@@ -1656,7 +1712,7 @@
"object.values": "^1.1.6",
"prop-types": "^15.8.1",
"resolve": "^2.0.0-next.4",
- "semver": "^6.3.1",
+ "semver": "^6.3.0",
"string.prototype.matchall": "^4.0.8"
},
"engines": {
@@ -1922,6 +1978,17 @@
"node": "^10.12.0 || >=12.0.0"
}
},
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -1958,6 +2025,25 @@
"integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==",
"dev": true
},
+ "node_modules/follow-redirects": {
+ "version": "1.15.6",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+ "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
"node_modules/for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@@ -1967,6 +2053,42 @@
"is-callable": "^1.1.3"
}
},
+ "node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/framer-motion": {
+ "version": "10.16.4",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.16.4.tgz",
+ "integrity": "sha512-p9V9nGomS3m6/CALXqv6nFGMuFOxbWsmaOrdmhyQimMIlLl3LC7h7l86wge/Js/8cRu5ktutS/zlzgR7eBOtFA==",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ },
+ "optionalDependencies": {
+ "@emotion/is-prop-valid": "^0.8.2"
+ },
+ "peerDependencies": {
+ "react": "^18.0.0",
+ "react-dom": "^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -1977,7 +2099,6 @@
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
@@ -2221,6 +2342,11 @@
"node": ">= 4"
}
},
+ "node_modules/immutable": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz",
+ "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ=="
+ },
"node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -2290,21 +2416,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-async-function": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
- "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==",
- "dev": true,
- "dependencies": {
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/is-bigint": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
@@ -2317,6 +2428,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/is-boolean-object": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
@@ -2376,43 +2498,14 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/is-finalizationregistry": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz",
- "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==",
- "dev": true,
- "dependencies": {
- "call-bind": "^1.0.2"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-generator-function": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
- "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
- "dev": true,
- "dependencies": {
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
"dependencies": {
"is-extglob": "^2.1.1"
},
@@ -2420,15 +2513,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/is-map": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
- "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==",
- "dev": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/is-negative-zero": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
@@ -2441,6 +2525,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
"node_modules/is-number-object": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
@@ -2481,15 +2573,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-set": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
- "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==",
- "dev": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/is-shared-array-buffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
@@ -2547,15 +2630,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-weakmap": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
- "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==",
- "dev": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/is-weakref": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
@@ -2568,19 +2642,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-weakset": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz",
- "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==",
- "dev": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
@@ -2593,19 +2654,6 @@
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
},
- "node_modules/iterator.prototype": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz",
- "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==",
- "dev": true,
- "dependencies": {
- "define-properties": "^1.2.1",
- "get-intrinsic": "^1.2.1",
- "has-symbols": "^1.0.3",
- "reflect.getprototypeof": "^1.0.4",
- "set-function-name": "^2.0.1"
- }
- },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -2743,6 +2791,25 @@
"yallist": "^3.0.2"
}
},
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -2791,6 +2858,14 @@
"integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
"dev": true
},
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -3004,6 +3079,17 @@
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"dev": true
},
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"node_modules/postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
@@ -3052,6 +3138,11 @@
"react-is": "^16.13.1"
}
},
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
"node_modules/punycode": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
@@ -3104,6 +3195,14 @@
"react": "^18.2.0"
}
},
+ "node_modules/react-icons": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.2.1.tgz",
+ "integrity": "sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw==",
+ "peerDependencies": {
+ "react": "*"
+ }
+ },
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -3119,24 +3218,15 @@
"node": ">=0.10.0"
}
},
- "node_modules/reflect.getprototypeof": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
- "integrity": "sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==",
- "dev": true,
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "get-intrinsic": "^1.2.1",
- "globalthis": "^1.0.3",
- "which-builtin-type": "^1.1.3"
+ "picomatch": "^2.2.1"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">=8.10.0"
}
},
"node_modules/regexp.prototype.flags": {
@@ -3278,6 +3368,22 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/sass": {
+ "version": "1.68.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.68.0.tgz",
+ "integrity": "sha512-Lmj9lM/fef0nQswm1J2HJcEsBUba4wgNx2fea6yJHODREoMFnwRpZydBnX/RjyXw2REIwdkbqE4hrTo4qfDBUA==",
+ "dependencies": {
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ },
+ "bin": {
+ "sass": "sass.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
@@ -3348,7 +3454,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -3481,6 +3586,22 @@
"node": ">=4"
}
},
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
+ },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -3625,14 +3746,14 @@
}
},
"node_modules/vite": {
- "version": "4.4.11",
- "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.11.tgz",
- "integrity": "sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==",
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.5.tgz",
+ "integrity": "sha512-4m5kEtAWHYr0O1Fu7rZp64CfO1PsRGZlD3TAB32UmQlpd7qg15VF7ROqGN5CyqN7HFuwr7ICNM2+fDWRqFEKaA==",
"dev": true,
"dependencies": {
"esbuild": "^0.18.10",
- "postcss": "^8.4.27",
- "rollup": "^3.27.1"
+ "postcss": "^8.4.26",
+ "rollup": "^3.25.2"
},
"bin": {
"vite": "bin/vite.js"
@@ -3710,47 +3831,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/which-builtin-type": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz",
- "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==",
- "dev": true,
- "dependencies": {
- "function.prototype.name": "^1.1.5",
- "has-tostringtag": "^1.0.0",
- "is-async-function": "^2.0.0",
- "is-date-object": "^1.0.5",
- "is-finalizationregistry": "^1.0.2",
- "is-generator-function": "^1.0.10",
- "is-regex": "^1.1.4",
- "is-weakref": "^1.0.2",
- "isarray": "^2.0.5",
- "which-boxed-primitive": "^1.0.2",
- "which-collection": "^1.0.1",
- "which-typed-array": "^1.1.9"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/which-collection": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
- "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
- "dev": true,
- "dependencies": {
- "is-map": "^2.0.1",
- "is-set": "^2.0.1",
- "is-weakmap": "^2.0.1",
- "is-weakset": "^2.0.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/which-typed-array": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz",
diff --git a/package.json b/package.json
index 2e6793c46..5d07e6358 100644
--- a/package.json
+++ b/package.json
@@ -10,8 +10,13 @@
"preview": "vite preview"
},
"dependencies": {
+ "@emailjs/browser": "^4.3.3",
+ "axios": "^1.7.2",
+ "framer-motion": "^10.16.4",
"react": "18.2.0",
- "react-dom": "18.2.0"
+ "react-dom": "18.2.0",
+ "react-icons": "^5.2.1",
+ "sass": "^1.68.0"
},
"devDependencies": {
"@types/react": "18.2.15",
diff --git a/public/bill-buddy.PNG b/public/bill-buddy.PNG
new file mode 100644
index 000000000..040cbf70c
Binary files /dev/null and b/public/bill-buddy.PNG differ
diff --git a/public/github.png b/public/github.png
new file mode 100644
index 000000000..9490ffc6d
Binary files /dev/null and b/public/github.png differ
diff --git a/public/gramedia-clone.PNG b/public/gramedia-clone.PNG
new file mode 100644
index 000000000..f480684c5
Binary files /dev/null and b/public/gramedia-clone.PNG differ
diff --git a/public/hero.png b/public/hero.png
deleted file mode 100644
index e806437f3..000000000
Binary files a/public/hero.png and /dev/null differ
diff --git a/public/linkedin-profile.JPG b/public/linkedin-profile.JPG
new file mode 100644
index 000000000..3b2943d63
Binary files /dev/null and b/public/linkedin-profile.JPG differ
diff --git a/public/linkedin.png b/public/linkedin.png
new file mode 100644
index 000000000..14e8125f8
Binary files /dev/null and b/public/linkedin.png differ
diff --git a/public/other-project.jpg b/public/other-project.jpg
new file mode 100644
index 000000000..f466963c4
Binary files /dev/null and b/public/other-project.jpg differ
diff --git a/public/qii-lain.png b/public/qii-lain.png
new file mode 100644
index 000000000..59f7b0f2b
Binary files /dev/null and b/public/qii-lain.png differ
diff --git a/public/qii.png b/public/qii.png
new file mode 100644
index 000000000..fb28e2706
Binary files /dev/null and b/public/qii.png differ
diff --git a/public/qii2 - Copy.png b/public/qii2 - Copy.png
new file mode 100644
index 000000000..ea7bfbe46
Binary files /dev/null and b/public/qii2 - Copy.png differ
diff --git a/public/qii2-removebg.png b/public/qii2-removebg.png
new file mode 100644
index 000000000..e7a1b82a9
Binary files /dev/null and b/public/qii2-removebg.png differ
diff --git a/public/qii2.png b/public/qii2.png
new file mode 100644
index 000000000..190645053
Binary files /dev/null and b/public/qii2.png differ
diff --git a/src/App.jsx b/src/App.jsx
index cb7b6da73..7f8be53a2 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,5 +1,35 @@
+import "./app.scss";
+import Contact from "./components/contact/Contact";
+import Cursor from "./components/cursor/cursor";
+import Hero from "./components/hero/Hero";
+import NavBar from "./components/navbar/NavBar";
+import Parallax from "./components/parallax/Parallax";
+import Portfolio from "./components/portfolio/Fortpolio";
+import Services from "./components/services/Services";
+
const App = () => {
- return Hello World
;
+ return (
+
+ );
};
export default App;
diff --git a/src/Test.jsx b/src/Test.jsx
new file mode 100644
index 000000000..380bf680e
--- /dev/null
+++ b/src/Test.jsx
@@ -0,0 +1,16 @@
+import "./app.scss";
+import { motion } from "framer-motion";
+
+export default function Test() {
+ return (
+
+
+
+ );
+}
diff --git a/src/app.scss b/src/app.scss
new file mode 100644
index 000000000..c33eb646a
--- /dev/null
+++ b/src/app.scss
@@ -0,0 +1,45 @@
+html {
+ scroll-snap-type: y mandatory;
+ scroll-behavior: smooth;
+}
+
+* {
+ padding: 0;
+ margin: 0;
+ box-sizing: border-box;
+ font-family: "DM Sans", sans-serif;
+}
+
+body {
+ background-color: #0c0c1d;
+ color: lightgray;
+}
+
+a {
+ text-decoration: none;
+ color: inherit;
+}
+
+section {
+ height: 100vh;
+ scroll-snap-align: center;
+}
+
+.course {
+ height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ .box {
+ width: 200px;
+ height: 200px;
+ background-color: white;
+ }
+}
+
+@mixin mobile {
+ @media (max-width: 738px) {
+ @content;
+ }
+}
diff --git a/src/components/contact/Contact.jsx b/src/components/contact/Contact.jsx
new file mode 100644
index 000000000..b881ce3ce
--- /dev/null
+++ b/src/components/contact/Contact.jsx
@@ -0,0 +1,122 @@
+import "./contact.scss";
+import { useRef, useState } from "react";
+import { motion, useInView } from "framer-motion";
+import emailjs from "@emailjs/browser";
+import axios from "axios";
+
+const variants = {
+ initial: {
+ y: 500,
+ opacity: 0,
+ },
+ animate: {
+ y: 0,
+ opacity: 1,
+ transition: {
+ duration: 0.5,
+ stagerChildren: 0.1,
+ },
+ },
+};
+
+export default function Contact() {
+ const ref = useRef();
+ const formRef = useRef();
+ const [error, setError] = useState(false);
+ const [success, setSuccess] = useState(false);
+
+ const isInView = useInView(ref, { margin: "-100px" });
+
+ const sendEmail = (e) => {
+ e.preventDefault();
+
+ emailjs
+ .sendForm("service_ae7deys", "template_zad0sh3", formRef.current, {
+ publicKey: "S15VkE1eAPyN0G8Y_",
+ })
+ .then(
+ () => {
+ setSuccess(true);
+ },
+ () => {
+ setError(true);
+ }
+ );
+ };
+
+ return (
+
+
+ Lets work together
+
+ Mail
+ riefqi.alviansyah1430@gmail.com
+
+
+ Address
+ Depok, Jawa Barat
+
+
+ Phone
+ +62-896-3757-7274
+
+
+
+
+
+
+
+
+
+
+
+
+ Send to rifqi
+ {error && Something went wrong }
+ {success && Message sent successfully }
+
+
+
+ );
+}
diff --git a/src/components/contact/contact.scss b/src/components/contact/contact.scss
new file mode 100644
index 000000000..26b1def5a
--- /dev/null
+++ b/src/components/contact/contact.scss
@@ -0,0 +1,108 @@
+@import "../../app.scss";
+
+.contact {
+ height: 100%;
+ max-width: 1024px;
+ margin: auto;
+ display: flex;
+ align-items: center;
+ gap: 50px;
+
+ @include mobile {
+ width: 100%;
+ padding: 10px;
+ flex-direction: column;
+ gap: 25px;
+ }
+
+ .textContainer {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 40px;
+
+ @include mobile {
+ gap: 10px;
+ text-align: center;
+ align-items: center;
+ margin-top: 50px;
+ }
+
+ h1 {
+ font-size: 100px;
+ line-height: 88px;
+
+ @include mobile {
+ font-size: 36px;
+ }
+ }
+
+ span {
+ font-weight: 300;
+ }
+ }
+
+ .formContainer {
+ flex: 1;
+ position: relative;
+ width: 100%;
+
+ @include mobile {
+ padding: 50px;
+ margin: auto;
+ }
+
+ .phoneSvg {
+ stroke: orange;
+ position: absolute;
+ margin: auto;
+ z-index: -1;
+
+ svg {
+ width: 450px;
+ height: 450px;
+
+ @include mobile {
+ width: 250px;
+ height: 250px;
+ }
+ }
+ }
+
+ form {
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+
+ @include mobile {
+ gap: 10px;
+ }
+
+ input,
+ textarea {
+ padding: 20px;
+ background-color: transparent;
+ border: 1px solid white;
+ color: white;
+ border-radius: 5px;
+
+ @include mobile {
+ padding: 10px;
+ }
+ }
+
+ button {
+ padding: 20px;
+ border: none;
+ background-color: orange;
+ cursor: pointer;
+ font-weight: 500;
+ border-radius: 10px;
+
+ @include mobile {
+ padding: 10px;
+ }
+ }
+ }
+ }
+}
diff --git a/src/components/cursor/cursor.jsx b/src/components/cursor/cursor.jsx
new file mode 100644
index 000000000..d56ea65b7
--- /dev/null
+++ b/src/components/cursor/cursor.jsx
@@ -0,0 +1,26 @@
+import { useEffect, useState } from "react";
+import { motion } from "framer-motion";
+import "./cursor.scss";
+
+export default function Cursor() {
+ const [position, setPOsition] = useState({ x: 0, y: 0 });
+
+ useEffect(() => {
+ const mouseMoveHandle = (e) => {
+ setPOsition({ x: e.clientX, y: e.clientY });
+ };
+
+ window.addEventListener("mousemove", mouseMoveHandle);
+
+ return () => {
+ window.removeEventListener("mousemove", mouseMoveHandle);
+ };
+ }, []);
+
+ return (
+
+ );
+}
diff --git a/src/components/cursor/cursor.scss b/src/components/cursor/cursor.scss
new file mode 100644
index 000000000..6e0908ac0
--- /dev/null
+++ b/src/components/cursor/cursor.scss
@@ -0,0 +1,14 @@
+@import "../../app.scss";
+
+.cursor {
+ width: 50px;
+ height: 50px;
+ border-radius: 50%;
+ border: 1px solid white;
+ position: fixed;
+ z-index: 999;
+
+ @include mobile {
+ display: none;
+ }
+}
diff --git a/src/components/hero/Hero.jsx b/src/components/hero/Hero.jsx
new file mode 100644
index 000000000..2b64ca0d5
--- /dev/null
+++ b/src/components/hero/Hero.jsx
@@ -0,0 +1,102 @@
+import "./hero.scss";
+import { motion } from "framer-motion";
+
+const textVariants = {
+ initial: {
+ x: -500,
+ opacity: 0,
+ },
+ animate: {
+ x: 0,
+ opacity: 1,
+ transition: {
+ duration: 1,
+ stagerChildren: 0.1,
+ },
+ },
+ scrollButton: {
+ opacity: 0,
+ y: 10,
+ transition: {
+ duration: 2,
+ repeat: Infinity,
+ },
+ },
+};
+
+const sliderVariants = {
+ initial: {
+ x: 0,
+ },
+ animate: {
+ x: "-220%",
+ transition: {
+ repeat: Infinity,
+ repeatType: "miror",
+ duration: 20,
+ },
+ },
+};
+
+export default function Hero() {
+ return (
+
+
+
+ RIEFQI ALVIANSYAH
+
+ Full Stack Web Depelover
+
+
+
+ See the Latest Work
+
+
+ Contact Me
+
+
+
+
+
+
+
+
+ I am a Full Stack Web Developer
+
+
+
+
+
+ );
+}
diff --git a/src/components/hero/hero.scss b/src/components/hero/hero.scss
new file mode 100644
index 000000000..b2f4938a2
--- /dev/null
+++ b/src/components/hero/hero.scss
@@ -0,0 +1,105 @@
+@import "../../app.scss";
+
+.hero {
+ height: calc(100vh - 100px);
+ overflow: hidden;
+ background: linear-gradient(180deg, #0c0c1d, #111132);
+ position: relative;
+
+ .wrapper {
+ position: relative;
+ max-width: 1024px;
+ height: 100%;
+ margin: auto;
+
+ .textContainer {
+ height: 100%;
+ width: 70%;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ gap: 40px;
+ position: absolute;
+ z-index: 1;
+
+ @include mobile {
+ height: 50%;
+ width: 100%;
+ gap: 20px;
+ align-items: center;
+ text-align: center;
+ }
+
+ h2 {
+ font-size: 30px;
+ color: rebeccapurple;
+ letter-spacing: 10px;
+ text-decoration: underline;
+
+ @include mobile {
+ font-size: 24px;
+ letter-spacing: 6px;
+ }
+ }
+
+ h1 {
+ font-size: 88px;
+
+ @include mobile {
+ font-size: 36px;
+ }
+ }
+
+ .buttons {
+ button {
+ padding: 20px;
+ border: 1px solid #fff;
+ border-radius: 10px;
+ background-color: transparent;
+ color: white;
+ margin-right: 20px;
+ cursor: pointer;
+ font-weight: 300;
+ }
+ }
+
+ img {
+ width: 50px;
+ }
+ }
+ }
+
+ .imageContainer {
+ height: 100%;
+ position: absolute;
+ top: 0;
+ right: 0;
+ display: flex;
+ justify-content: center;
+ margin-right: 150px;
+
+ @include mobile {
+ top: unset;
+ bottom: 0;
+ height: 50%;
+ width: 100%;
+ margin-right: 0px;
+ }
+
+ img {
+ height: 100%;
+ width: auto;
+ object-fit: cover;
+ }
+ }
+
+ .slidingTextContainer {
+ position: absolute;
+ font-size: 50vh;
+ bottom: -120px;
+ white-space: nowrap;
+ color: #ffffff09;
+ width: 50%;
+ font-weight: bold;
+ }
+}
diff --git a/src/components/navbar/NavBar.jsx b/src/components/navbar/NavBar.jsx
new file mode 100644
index 000000000..5c0bf1f05
--- /dev/null
+++ b/src/components/navbar/NavBar.jsx
@@ -0,0 +1,34 @@
+import SideBar from "../sidebar/SideBar";
+import "./navbar.scss";
+import { motion } from "framer-motion";
+
+export default function NavBar() {
+ return (
+
+ );
+}
diff --git a/src/components/navbar/navbar.scss b/src/components/navbar/navbar.scss
new file mode 100644
index 000000000..35ba582a5
--- /dev/null
+++ b/src/components/navbar/navbar.scss
@@ -0,0 +1,54 @@
+@import "../../app.scss";
+
+.navbar {
+ height: 100px;
+
+ .wrapper {
+ max-width: 1024px;
+ margin: auto;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ height: 100%;
+
+ @include mobile {
+ justify-content: flex-end;
+ padding: 20px;
+ }
+ }
+
+ span {
+ font-weight: bold;
+
+ @include mobile {
+ display: none;
+ }
+ }
+
+ .social {
+ background-color: #fff;
+ display: flex;
+ gap: 5px;
+ border-radius: 10px;
+
+ a {
+ height: 100%;
+ display: flex;
+ align-items: center;
+ padding: 8px;
+
+ img {
+ width: 32px;
+ height: 32px;
+ transition: 0.3s;
+ border-radius: 10px;
+
+ &:hover {
+ scale: 1.1;
+ transform: translateY(-2px);
+ box-shadow: 0 5px 5px 2px rgba(0, 0, 0, 0.5);
+ }
+ }
+ }
+ }
+}
diff --git a/src/components/parallax/Parallax.jsx b/src/components/parallax/Parallax.jsx
new file mode 100644
index 000000000..6d46df292
--- /dev/null
+++ b/src/components/parallax/Parallax.jsx
@@ -0,0 +1,43 @@
+import { useRef } from "react";
+import "./parallax.scss";
+import { motion, useScroll, useTransform } from "framer-motion";
+
+export default function Parallax({ type }) {
+ const ref = useRef();
+
+ const { scrollYProgress } = useScroll({
+ target: ref,
+ offset: ["start start", "end start"],
+ });
+
+ const yText = useTransform(scrollYProgress, [0, 1], ["0%", "300%"]);
+ const yBg = useTransform(scrollYProgress, [0, 1], ["0%", "10%"]);
+
+ return (
+
+
+ {type == "skills" ? "My Skills?" : "What I Do?"}
+
+
+
+
+
+ );
+}
diff --git a/src/components/parallax/parallax.scss b/src/components/parallax/parallax.scss
new file mode 100644
index 000000000..bb7c25d49
--- /dev/null
+++ b/src/components/parallax/parallax.scss
@@ -0,0 +1,64 @@
+@import "../../app.scss";
+
+.parallax {
+ width: 100%;
+ height: 100%;
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ overflow: hidden;
+
+ h1 {
+ font-size: 100px;
+
+ @include mobile {
+ font-size: 72px;
+ text-align: center;
+ }
+ }
+
+ .mountains {
+ background-image: url("/mountains.png");
+ background-size: cover;
+ background-position: bottom;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ z-index: 3;
+
+ @include mobile {
+ background-size: contain;
+ background-repeat: no-repeat;
+ }
+ }
+
+ .planets {
+ background-image: url("/planets.png");
+ background-size: cover;
+ background-position: bottom;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ z-index: 2;
+
+ @include mobile {
+ background-size: contain;
+ background-repeat: no-repeat;
+ }
+ }
+
+ .stars {
+ background-image: url("/stars.png");
+ background-size: cover;
+ background-position: bottom;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ z-index: 1;
+
+ @include mobile {
+ background-size: contain;
+ }
+ }
+}
diff --git a/src/components/portfolio/Fortpolio.jsx b/src/components/portfolio/Fortpolio.jsx
new file mode 100644
index 000000000..26ecc308e
--- /dev/null
+++ b/src/components/portfolio/Fortpolio.jsx
@@ -0,0 +1,81 @@
+import { useRef } from "react";
+import "./portfolio.scss";
+import { motion, useScroll, useSpring, useTransform } from "framer-motion";
+
+const items = [
+ {
+ id: 1,
+ title: "Bill Buddy",
+ img: "/bill-buddy.PNG",
+ description:
+ "Bill Buddy is a web-based app, so users don't need to install it on their smartphones. It is designed for splitting bills with friends, offering features like multiple payment options, tracking member payments, and real-time collaborative bill editing.",
+ demo: "https://drive.google.com/file/d/1Je_u3ATuMeENc0LgUMgmDZxiwx6jd6iU/view?usp=sharing",
+ },
+ {
+ id: 2,
+ title: "Book Store",
+ img: "/gramedia-clone.PNG",
+ description:
+ "This web-based bookstore app, built with Next.js for educational purposes, allows users to browse, search, and purchase books online, featuring a shopping cart, secure checkout, and user account management.",
+ demo: "https://my-app-psi-ashen.vercel.app/",
+ },
+ {
+ id: 3,
+ title: "Other",
+ img: "/other-project.jpg",
+ description: "Yout can find other project on my github.",
+ demo: "https://github.com/riefqialviansyah?tab=repositories",
+ },
+];
+
+function Single({ item }) {
+ const ref = useRef();
+
+ const { scrollYProgress } = useScroll({
+ target: ref,
+ // offset: ["start start", "end start"],
+ });
+
+ const y = useTransform(scrollYProgress, [0, 1], [-300, 300]);
+
+ return (
+
+
+
+
+
+
+
+ {item.title}
+ {item.description}
+
+ See Demo
+
+
+
+
+
+ );
+}
+
+export default function Portfolio() {
+ const ref = useRef();
+ const { scrollYProgress } = useScroll({
+ target: ref,
+ offset: ["end end", "start start"],
+ });
+
+ const scaleX = useSpring(scrollYProgress, { stiffness: 100, damping: 30 });
+
+ return (
+
+
+
Featured Works
+
+
+ {items.map((item) => {
+ return
;
+ })}
+
+ );
+}
diff --git a/src/components/portfolio/portfolio.scss b/src/components/portfolio/portfolio.scss
new file mode 100644
index 000000000..cc5928f49
--- /dev/null
+++ b/src/components/portfolio/portfolio.scss
@@ -0,0 +1,108 @@
+@import "../../app.scss";
+
+.portfolio {
+ position: relative;
+
+ .progress {
+ position: sticky;
+ top: 0;
+ left: 0;
+ padding-top: 40px;
+ text-align: center;
+ color: orange;
+ font-size: 36px;
+
+ @include mobile {
+ padding-top: calc(100vh - 80px);
+ font-size: 24px;
+ }
+
+ .progressBar {
+ height: 10px;
+ background-color: white;
+ }
+ }
+
+ .container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ height: 100%;
+ overflow: hidden;
+
+ .wrapper {
+ max-width: 1024px;
+ height: 100%;
+ margin: auto;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 50px;
+
+ @include mobile {
+ flex-direction: column;
+ gap: 10px;
+ }
+
+ .imgContainer {
+ flex: 1;
+ height: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ @include mobile {
+ width: 100%;
+ max-height: 300px;
+ }
+
+ img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ border-radius: 10px;
+
+ @include mobile {
+ object-fit: contain;
+ }
+ }
+ }
+
+ .textContainer {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 30px;
+
+ @include mobile {
+ transform: none !important;
+ padding: 10px;
+ align-items: center;
+ text-align: center;
+ }
+
+ h2 {
+ font-size: 72px;
+
+ @include mobile {
+ font-size: 36px;
+ }
+ }
+
+ p {
+ color: gray;
+ font-size: 20px;
+ }
+
+ button {
+ background-color: orange;
+ border: none;
+ border-radius: 10px;
+ padding: 10px;
+ width: 200px;
+ cursor: pointer;
+ }
+ }
+ }
+ }
+}
diff --git a/src/components/services/Services.jsx b/src/components/services/Services.jsx
new file mode 100644
index 000000000..0cc8a1bed
--- /dev/null
+++ b/src/components/services/Services.jsx
@@ -0,0 +1,157 @@
+import { useRef } from "react";
+import "./services.scss";
+import { motion } from "framer-motion";
+import { HiArrowRight } from "react-icons/hi";
+
+const variants = {
+ initial: {
+ x: -500,
+ y: 100,
+ opacity: 0,
+ },
+ animate: {
+ x: 0,
+ y: 0,
+ opacity: 1,
+ transition: {
+ duration: 1,
+ stagerChildren: 0.1,
+ },
+ },
+};
+
+export default function Services() {
+ const ref = useRef();
+
+ const isInView =
+ (ref,
+ {
+ margin: "-100px",
+ });
+
+ return (
+
+
+
+ {`"First, solve the problem. Then, write the code."`}
+ - John Johnson
+
+
+
+
+
+
+
+ My
+ Skills
+
+
+
+
+ Let See What I
+ Do
+
+
+
+
+
+
+
+
+
+
+ Languague
+
+
+ Javascrip
+
+
+ Typscript
+
+
+ PHP (Basic)
+
+
+ Go
+
+
+ Backend
+
+
+ NodeJs
+
+
+ Express
+
+
+ ORM Sequelize
+
+
+ Laravel (Explore)
+
+
+ Go
+
+
+ Frontend
+
+
+ ReactJS
+
+
+ NextJs
+
+
+ Go
+
+
+ Mobile
+
+
+ Apollo GraphQL
+
+
+ React Native
+
+
+ Go
+
+
+ Database
+
+
+ PostgreSQL
+
+
+ MongoDB
+
+
+ Go
+
+
+
+ );
+}
diff --git a/src/components/services/services.scss b/src/components/services/services.scss
new file mode 100644
index 000000000..bc171870a
--- /dev/null
+++ b/src/components/services/services.scss
@@ -0,0 +1,162 @@
+@import "../../app.scss";
+
+.services {
+ background: linear-gradient(180deg, #0c0c1d, #111132);
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+
+ .textContainer {
+ flex: 1;
+ align-self: flex-end;
+ display: flex;
+ align-items: center;
+ gap: 20px;
+
+ @include mobile {
+ align-self: center;
+ text-align: center;
+ flex-direction: column;
+ gap: 10px;
+ }
+
+ p {
+ font-size: 200;
+ font-size: 20px;
+ color: gray;
+ text-align: right;
+
+ @include mobile {
+ font-size: 16px;
+ }
+ }
+
+ hr {
+ width: 200px;
+ border: none;
+ border-top: 0.5px solid grey;
+
+ @include mobile {
+ width: 300px;
+ }
+ }
+ }
+
+ .titleContainer {
+ flex: 2;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ @include mobile {
+ width: 100%;
+ }
+
+ .title {
+ display: flex;
+ align-items: center;
+ gap: 50px;
+
+ @include mobile {
+ flex-direction: column;
+ text-align: center;
+ gap: 20px;
+ }
+
+ img {
+ width: 300px;
+ height: 100px;
+ border-radius: 50px;
+ object-fit: cover;
+
+ @include mobile {
+ width: 200px;
+ height: 50px;
+ }
+ }
+
+ h1 {
+ font-size: 96px;
+ font-weight: 100;
+
+ @include mobile {
+ font-size: 36px;
+ }
+ }
+
+ button {
+ width: 300px;
+ height: 100px;
+ border-radius: 50px;
+ background-color: orange;
+ border: none;
+ font-size: 24px;
+ cursor: pointer;
+
+ @include mobile {
+ font-size: 14px;
+ width: 150px;
+ height: 30px;
+ }
+
+ .arrow {
+ font-size: 30px;
+ }
+ }
+ }
+ }
+
+ .listContainer {
+ flex: 2;
+ display: flex;
+ max-width: 1366px;
+ margin: auto;
+
+ @include mobile {
+ width: 100%;
+ flex-direction: column;
+ }
+
+ .box {
+ padding: 50px;
+ border: 0.5px solid gray;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ cursor: pointer;
+
+ @include mobile {
+ border: none;
+ align-items: center;
+ padding: 5px;
+ }
+
+ p {
+ @include mobile {
+ display: none;
+ }
+ }
+ ul {
+ @include mobile {
+ display: none;
+ }
+ }
+ }
+
+ button {
+ padding: 10px;
+ background-color: orange;
+ cursor: pointer;
+ border: none;
+
+ @include mobile {
+ background-color: transparent;
+ border: 1px solid orange;
+ color: orange;
+ width: 50%;
+ padding: 5px;
+ }
+ }
+ }
+}
diff --git a/src/components/sidebar/SideBar.jsx b/src/components/sidebar/SideBar.jsx
new file mode 100644
index 000000000..96eeb2504
--- /dev/null
+++ b/src/components/sidebar/SideBar.jsx
@@ -0,0 +1,37 @@
+import { useState } from "react";
+import "./sidebar.scss";
+import ToggleButton from "./toggleButton/ToggleButton";
+import { motion } from "framer-motion";
+import Links from "./links/Links";
+
+export default function SideBar() {
+ const [open, setOpen] = useState(false);
+
+ const variants = {
+ open: {
+ clipPath: "circle(1200px at 50px 50px)",
+ transition: {
+ type: "spring",
+ stiffness: 20,
+ },
+ },
+ closed: {
+ clipPath: "circle(25px at 50px 50px)",
+ transition: {
+ delay: 0.5,
+ type: "spring",
+ stiffness: 400,
+ damping: 40,
+ },
+ },
+ };
+
+ return (
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/sidebar/links/Links.jsx b/src/components/sidebar/links/Links.jsx
new file mode 100644
index 000000000..600fed3ea
--- /dev/null
+++ b/src/components/sidebar/links/Links.jsx
@@ -0,0 +1,65 @@
+import { motion } from "framer-motion";
+import {
+ HiOutlineHome,
+ HiOutlineBookOpen,
+ HiOutlinePresentationChartLine,
+ HiOutlinePhone,
+} from "react-icons/hi";
+
+const variants = {
+ open: {
+ transition: {
+ staggerChildren: 0.1,
+ },
+ },
+ closed: {
+ transition: {
+ staggerChildren: 0.05,
+ staggerDirection: -1,
+ },
+ },
+};
+
+const itemVariants = {
+ open: {
+ y: 0,
+ opacity: 1,
+ },
+ closed: {
+ y: 50,
+ opacity: 0,
+ },
+};
+
+export default function Links() {
+ const items = [
+ { name: "Homepage", icon: },
+ { name: "Skills", icon: },
+ { name: "Portfolio", icon: },
+ { name: "Contact", icon: },
+ ];
+
+ return (
+
+ {items.map((item) => {
+ return (
+
+ {item.icon}
+ {item.name}
+
+ );
+ })}
+
+ );
+}
diff --git a/src/components/sidebar/sidebar.scss b/src/components/sidebar/sidebar.scss
new file mode 100644
index 000000000..db562deb8
--- /dev/null
+++ b/src/components/sidebar/sidebar.scss
@@ -0,0 +1,61 @@
+@import "../../app.scss";
+
+.sidebar {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ border-color: white;
+ color: black;
+
+ .bg {
+ position: fixed;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ width: 200px;
+ background: #00215e;
+ z-index: 999;
+
+ @include mobile {
+ width: 200px;
+ }
+
+ .links {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ gap: 20px;
+ padding-left: 15px;
+
+ a {
+ font-size: 25px;
+ color: white;
+ display: flex;
+ align-items: center;
+ gap: 5px;
+ box-sizing: border-box;
+
+ @include mobile {
+ font-size: 20px;
+ }
+ }
+ }
+ }
+
+ button {
+ width: 50px;
+ height: 50px;
+ border-radius: 50%;
+ position: fixed;
+ top: 25px;
+ left: 25px;
+ background-color: transparent;
+ border: none;
+ cursor: pointer;
+ z-index: 999;
+ }
+}
diff --git a/src/components/sidebar/toggleButton/ToggleButton.jsx b/src/components/sidebar/toggleButton/ToggleButton.jsx
new file mode 100644
index 000000000..aae7ed392
--- /dev/null
+++ b/src/components/sidebar/toggleButton/ToggleButton.jsx
@@ -0,0 +1,45 @@
+import { motion } from "framer-motion";
+
+export default function ToggleButton({ setOpen }) {
+ return (
+ setOpen((prev) => !prev)}
+ style={{
+ display: "flex",
+ justifyContent: "center",
+ alignItems: "center",
+ }}
+ >
+
+
+
+
+
+
+ );
+}