├── .eslintrc.js ├── .github └── workflows │ ├── codeql-analysis.yml │ ├── deploy-to-production.yml │ ├── deploy-to-stage.yml │ └── lint.yml ├── .gitignore ├── .prettierignore ├── .prettierrc.json ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── api ├── index.js └── name.js ├── extra └── publish.sh ├── package-lock.json ├── package.json ├── public ├── favicon │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── manifest.json │ └── site.webmanifest ├── index.html ├── robots.txt └── sitemap.xml ├── src ├── App.js ├── App.test.js ├── Downloadables │ ├── Pranjal_Jain_CV.pdf │ ├── Resume.pdf │ └── goldman_completion_certificate.pdf ├── Terms │ ├── Privacy.md │ └── Terms.md ├── assets │ ├── Image │ │ ├── logo.ai │ │ ├── logo.png │ │ └── logo.svg │ └── fonts │ │ ├── Avenir.otf │ │ ├── AvenirBold.otf │ │ └── Google sans │ │ ├── Google sans Bold.woff2 │ │ ├── Google sans Medium.ttf │ │ ├── Google sans regular.ttf │ │ └── GoogleSans.woff2 ├── components │ ├── Accordian │ │ ├── Accordian.js │ │ └── Accordian.scss │ ├── CodeList.js │ ├── Education.js │ ├── Hobby.js │ ├── Home.js │ ├── HomeAbout.js │ ├── HomeCard.js │ ├── HomeModal.js │ ├── Left.js │ ├── LeftText.js │ ├── Navigation.js │ ├── ProjectCard.js │ ├── ResumeModal.js │ ├── SocialModal.js │ └── WorkExp.js ├── data │ ├── home_data.json │ └── homecards.json ├── hidden-message.js ├── index.css ├── index.js ├── navigation │ ├── index.js │ └── routes.js ├── pages │ ├── Project.js │ └── ProjectList.js ├── service-worker.js ├── serviceWorkerRegistration.js └── setupTests.js └── vercel.json /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | node: true, 6 | }, 7 | extends: ['eslint:recommended', 'plugin:react/recommended'], 8 | parserOptions: { 9 | ecmaFeatures: { 10 | jsx: true, 11 | }, 12 | ecmaVersion: 12, 13 | sourceType: 'module', 14 | }, 15 | plugins: ['react'], 16 | rules: { 17 | 'react/prop-types': [0, {}], // this is dumb, why is this still recommended 18 | 'react/no-unescaped-entities': [0, {}], 19 | 'no-unused-vars': [1, {}], 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: 'CodeQL' 2 | 3 | on: 4 | push: 5 | branches: [master, Vercel_Check] 6 | pull_request: 7 | branches: [master] 8 | schedule: 9 | - cron: '44 13 * * 1' 10 | 11 | jobs: 12 | analyze: 13 | name: Analyze 14 | runs-on: ubuntu-latest 15 | permissions: 16 | actions: read 17 | contents: read 18 | security-events: write 19 | 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | language: ['javascript'] 24 | steps: 25 | - name: Checkout repository 26 | uses: actions/checkout@v3 27 | - name: Initialize CodeQL 28 | uses: github/codeql-action/init@v2 29 | with: 30 | languages: ${{ matrix.language }} 31 | - name: Autobuild 32 | uses: github/codeql-action/autobuild@v2 33 | - name: Perform CodeQL Analysis 34 | uses: github/codeql-action/analyze@v2 35 | -------------------------------------------------------------------------------- /.github/workflows/deploy-to-production.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to Vercel (production) 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'master' 7 | - 'lighthouse-integration' 8 | 9 | jobs: 10 | setup-environment: 11 | name: Setup deployment environment (Ubuntu - Node 18.x) 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Check out Git repository 15 | uses: actions/checkout@v3 16 | 17 | - name: Set up Node.js 18 | uses: actions/setup-node@v3 19 | with: 20 | node-version: 18 21 | 22 | start-production-deployment: 23 | name: Starts Vercel deployment (Production) (Ubuntu) 24 | runs-on: ubuntu-latest 25 | needs: setup-environment 26 | steps: 27 | - uses: actions/checkout@v3 28 | 29 | - uses: amondnet/vercel-action@v20 30 | with: 31 | vercel-token: ${{ secrets.ZEIT_TOKEN }} 32 | vercel-args: '--prod' 33 | vercel-org-id: ${{ secrets.ORG_ID}} 34 | vercel-project-id: ${{ secrets.PROJECT_ID}} 35 | 36 | # run-lighthouse-tests: 37 | # name: Run LightHouse checks (Ubuntu 18.04) 38 | # runs-on: ubuntu-latest 39 | # needs: start-production-deployment 40 | # env: 41 | # ACTIONS_ALLOW_UNSECURE_COMMANDS: "true" 42 | # steps: 43 | # - uses: actions/checkout@v1 44 | # - name: Resolving deployment url from Zeit 45 | # run: | 46 | # apt update -y >/dev/null && apt install -y jq >/dev/null 47 | # ZEIT_DEPLOYMENT=`curl -H 'Accept: application/json' -H 'Content-Type: application/json' -H 'Authorization: Bearer ${{ secrets.ZEIT_TOKEN }}' https://api.zeit.co/v5/now/deployments?teamId=$(cat now.json | jq -r '.scope') | jq '.deployments [0].url' | tr -d \"` 48 | # echo "::set-env name=ZEIT_DEPLOYMENT_URL::https://$ZEIT_DEPLOYMENT" 49 | # env: 50 | # ZEIT_TOKEN: ${{ secrets.ZEIT_TOKEN }} 51 | # - name: Create temporary folder for artifacts storage 52 | # run: mkdir /tmp/lighthouse-artifacts 53 | # - name: Run Lighthouse 54 | # uses: foo-software/lighthouse-check-action@v1.0.14 55 | # env: 56 | # ACTIONS_ALLOW_UNSECURE_COMMANDS: "true" 57 | # id: lighthouseCheck 58 | # with: 59 | # outputDirectory: /tmp/lighthouse-artifacts 60 | # urls: ${{ env.ZEIT_DEPLOYMENT_URL }} 61 | # - name: Upload artifacts 62 | # uses: actions/upload-artifact@v1 63 | # with: 64 | # name: Lighthouse reports 65 | # path: /tmp/lighthouse-artifacts 66 | # - name: Handle Lighthouse Check results 67 | # uses: foo-software/lighthouse-check-status-action@v1.0.1 68 | # with: 69 | # lighthouseCheckResults: ${{ steps.lighthouseCheck.outputs.lighthouseCheckResults }} 70 | # minAccessibilityScore: "50" 71 | # minBestPracticesScore: "50" 72 | # minPerformanceScore: "30" 73 | # minProgressiveWebAppScore: "50" 74 | # minSeoScore: "50" 75 | -------------------------------------------------------------------------------- /.github/workflows/deploy-to-stage.yml: -------------------------------------------------------------------------------- 1 | # Summary: 2 | # Creates a new deployment on Zeit's platform, when anything is pushed in any branch (except for the "master" branch). 3 | # Read ./README.md for extensive documentation 4 | 5 | name: Deploy to Vercel (staging) 6 | 7 | on: 8 | push: 9 | branches-ignore: 10 | - 'master' 11 | 12 | jobs: 13 | # Configures the deployment environment, install dependencies (like node, npm, etc.) that are requirements for the upcoming jobs 14 | # Ex: Necessary to run `yarn deploy` 15 | setup-environment: 16 | name: Setup deployment environment (Ubuntu 18.04 - Node 10.x) 17 | runs-on: ubuntu-latest 18 | steps: 19 | # ESLint and Prettier must be in `package.json` 20 | - name: Install Node.js dependencies 21 | run: npm install 22 | 23 | # Starts a Zeit deployment, using the staging configuration file of the default institution 24 | # The default institution is the one defined in the `now.json` file (which is a symlink to the actual file) 25 | # N.B: It's Zeit that will perform the actual deployment 26 | start-staging-deployment: 27 | name: Starts Vercel deployment (Staging) (Ubuntu 18.04) 28 | runs-on: ubuntu-latest 29 | env: 30 | ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' 31 | needs: setup-environment 32 | steps: 33 | - uses: actions/checkout@v2 34 | - uses: amondnet/vercel-action@v19 35 | with: 36 | vercel-token: ${{ secrets.ZEIT_TOKEN }} # Required 37 | vercel-org-id: ${{ secrets.ORG_ID}} #Required 38 | vercel-project-id: ${{ secrets.PROJECT_ID}} #Required 39 | 40 | 41 | # # On deployment failure, add a comment to the PR 42 | # - name: Comment PR (Deployment failure) 43 | # uses: unsplash/comment-on-pr@master 44 | # if: failure() 45 | # env: 46 | # GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} 47 | # with: 48 | # msg: "[GitHub Actions]\nDeployment FAILED\n\t Commit ${{ github.sha }} failed to deploy to ${{ env.ZEIT_DEPLOYMENT_URL }} (click to see logs)" 49 | # check_for_duplicate_msg: true # OPTIONAL 50 | 51 | # # On deployment success, add a comment to the PR 52 | # - name: Comment PR (Deployment success) 53 | # uses: unsplash/comment-on-pr@master 54 | # if: success() 55 | # env: 56 | # GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} 57 | # with: 58 | # msg: "[GitHub Actions]\nDeployment SUCCESS\n\t Commit ${{ github.sha }} successfully deployed to ${{ env.ZEIT_DEPLOYMENT_URL }}\n\tDeployment aliased as ${{ env.ZEIT_DEPLOYEMENT_ALIAS }}" 59 | # check_for_duplicate_msg: true # OPTIONAL 60 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Linting Tests 2 | 3 | on: push 4 | 5 | jobs: 6 | run-linters: 7 | name: Run linters 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - name: Check out Git repository 12 | uses: actions/checkout@v3 13 | 14 | - name: Set up Node.js 15 | uses: actions/setup-node@v3 16 | with: 17 | node-version: 18 18 | 19 | - name: NPM set legacy-peer-deps to true 20 | run: 'npm config set legacy-peer-deps true' 21 | 22 | - name: Insatll Prettier 23 | run: 'npm install prettier' 24 | 25 | - name: Insatll ESLint 26 | run: 'npm i eslint' 27 | 28 | - name: Run linters 29 | run: 'npx prettier --check .' 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | ### react ### 3 | .DS_* 4 | *.log 5 | logs 6 | **/*.backup.* 7 | **/*.back.* 8 | 9 | bower_components 10 | # dependencies 11 | /node_modules 12 | /.pnp 13 | .pnp.js 14 | 15 | # testing 16 | /coverage 17 | /config 18 | 19 | # production 20 | /build 21 | 22 | # misc 23 | .DS_Store 24 | .env 25 | .env.local 26 | .env.development.local 27 | .env.test.local 28 | .env.production.local 29 | 30 | # Certificates 31 | rootCA.key 32 | rootCA.pem 33 | rootCA.srl 34 | server.crt 35 | server.csr 36 | server.csr.cnf 37 | server.key 38 | v3.ext 39 | 40 | npm-debug.log* 41 | yarn-debug.log* 42 | yarn-error.log* 43 | 44 | .vercel 45 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Ignore artifacts: 2 | build 3 | coverage -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "always", 3 | "bracketSpacing": false, 4 | "embeddedLanguageFormatting": "auto", 5 | "htmlWhitespaceSensitivity": "css", 6 | "insertPragma": false, 7 | "jsxBracketSameLine": true, 8 | "jsxSingleQuote": true, 9 | "printWidth": 80, 10 | "proseWrap": "preserve", 11 | "quoteProps": "as-needed", 12 | "requirePragma": false, 13 | "semi": false, 14 | "singleQuote": true, 15 | "tabWidth": 2, 16 | "trailingComma": "es5", 17 | "useTabs": true, 18 | "vueIndentScriptAndStyle": false 19 | } 20 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Welcome to the contributions of React portfolio 2 | 3 | We follow a systematic Git Workflow - 4 | 5 | - Create a fork of this repo. 6 | - Clone your fork of your repo on your pc. 7 | - [Add Upstream to your clone](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/configuring-a-remote-for-a-fork) 8 | - **Every change** that you do, it has to be on a branch. Commits on master would directly be closed. 9 | - Make sure that before you create a new branch for new changes,[syncing with upstream](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/syncing-a-fork) is neccesary. 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Pranjal Jain 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### You can fork it and create your own portfolio. 2 | 3 | ![https://david-dm.org/pranjaljain0/portfolio-react.svg](https://david-dm.org/pranjaljain0/portfolio-react.svg) [![devDependencies Status](https://status.david-dm.org/gh/pranjaljain0/portfolio-react.svg?type=dev)](https://david-dm.org/pranjaljain0/portfolio-react?type=dev) [![Total alerts](https://img.shields.io/lgtm/alerts/g/pranjaljain0/portfolio-react.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/pranjaljain0/portfolio-react/alerts/) [![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/pranjaljain0/portfolio-react.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/pranjaljain0/portfolio-react/context:javascript) [![Website pranjalis.me](https://img.shields.io/website-up-down-green-red/http/pranjalis.me.svg)](https://pranjalis.me) [![GitHub license](https://img.shields.io/github/license/pranjaljain0/portfolio-react.svg)](https://github.com/pranjaljain0/portfolio-react/blob/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/pranjaljain0/portfolio-react.svg)](https://GitHub.com/pranjaljain0/portfolio-react/releases/) [![GitHub stars](https://img.shields.io/github/stars/pranjaljain0/portfolio-react.svg?style=social&label=Star&maxAge=2592000)](https://GitHub.com/pranjaljain0/portfolio-react/stargazers/) 4 | 5 | I value keeping my site open source, but as you all know, plagiarism is bad so if you love it feel free to copy it and please give proper credits. If you have issues making use of this portfolio you can refer to [React docs](https://reactjs.org/docs/getting-started.html). Thanks! 6 | 7 | Website [pranjalis.me](https://www.pranjalis.me) 8 | 9 | # Portfolio website 10 | 11 | A portfolio website created using React.js hosted on Vercel. 12 | 13 | ## Pages: 14 | 15 | 1. Home Page 16 | 2. Contact-Us 17 | 3. About-Us 18 | 4. Projects 19 | 20 | ## Stargazers over time 21 | 22 | [![Stargazers over time](https://starchart.cc/pranjaljain0/portfolio-react.svg)](https://starchart.cc/pranjaljain0/portfolio-react) 23 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | -------------------------------------------------------------------------------- /api/index.js: -------------------------------------------------------------------------------- 1 | module.exports = (req, res) => { 2 | const {name = 'World'} = req.query 3 | res.status(200).send(`Hello ${name}!`) 4 | } 5 | -------------------------------------------------------------------------------- /api/name.js: -------------------------------------------------------------------------------- 1 | module.exports = (req, res) => { 2 | const {name = 'World'} = req.query 3 | res.status(200).send(`Hello ${name}!`) 4 | } 5 | -------------------------------------------------------------------------------- /extra/publish.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # die on error 4 | set -e 5 | 6 | # https://gist.github.com/cjus/1047794 7 | echo 'Retrieving latest deploy...' 8 | url=`curl -H "Authorization: Bearer $NETLIFY_ACCESS_TOKEN" https://api.netlify.com/api/v1/sites/pranjalis.me/deploys` 9 | temp=`echo $url | sed 's/\\\\\//\//g' | sed 's/[{}]//g' | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | sed 's/\"\:\"/\|/g' | sed 's/[\,]/ /g' | sed 's/\"//g' | grep -w -m 1 'id'` 10 | 11 | # https://www.netlify.com/docs/api/#deploys 12 | echo "Publishing build ${temp##*|}..." 13 | curl -X POST -H "Authorization: Bearer $NETLIFY_ACCESS_TOKEN" -d "{}" "https://api.netlify.com/api/v1/sites/pranjalis.me/deploys/${temp##*|}/restore" 14 | 15 | # # https://open-api.netlify.com/#/default/lockDeploy 16 | # echo "Locking deploy to ${temp##*|}..." 17 | # curl -X POST -H "Authorization: Bearer $NETLIFY_ACCESS_TOKEN" -d "{}" "https://api.netlify.com/api/v1/deploys/${temp##*|}/lock" 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "portfolio", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@loadable/component": "^5.15.3", 7 | "@sentry/react": "^7.51.0", 8 | "@sentry/tracing": "^7.51.0", 9 | "@testing-library/jest-dom": "^5.16.5", 10 | "@testing-library/user-event": "^14.4.3", 11 | "bootstrap": "^5.2.3", 12 | "browserslist": "^4.21.5", 13 | "gitmoji-cli": "^8.1.1", 14 | "lint-staged": "^13.2.2", 15 | "react": "^18.2.0", 16 | "react-bootstrap": "^2.7.4", 17 | "react-dom": "^18.2.0", 18 | "react-icons": "^4.8.0", 19 | "react-router-dom": "^6.11.1", 20 | "react-scripts": "^5.0.1", 21 | "react-tsparticles": "^2.9.3", 22 | "react-typed": "^1.2.0", 23 | "react-vertical-timeline-component": "^3.6.0", 24 | "sass": "^1.62.1", 25 | "styled-components": "^5.3.10" 26 | }, 27 | "scripts": { 28 | "start": "react-scripts start", 29 | "build": "npm config set legacy-peer-deps true && react-scripts build", 30 | "test": "react-scripts test", 31 | "eject": "react-scripts eject", 32 | "report": "npm run build" 33 | }, 34 | "eslintConfig": { 35 | "extends": "react-app" 36 | }, 37 | "browserslist": { 38 | "production": [ 39 | ">0.2%", 40 | "not dead", 41 | "not op_mini all" 42 | ], 43 | "development": [ 44 | "last 1 chrome version", 45 | "last 1 firefox version", 46 | "last 1 safari version" 47 | ] 48 | }, 49 | "devDependencies": { 50 | "@typescript-eslint/eslint-plugin": "^5.59.2", 51 | "@typescript-eslint/parser": "^5.59.2", 52 | "eslint": "^8.39.0", 53 | "eslint-plugin-react": "^7.32.2", 54 | "prettier": "^2.8.8", 55 | "webpack-bundle-analyzer": "^4.8.0" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /public/favicon/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/public/favicon/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/favicon/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/public/favicon/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/public/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /public/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/public/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/public/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/public/favicon/favicon.ico -------------------------------------------------------------------------------- /public/favicon/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Pranjal Jain Portfolio", 3 | "short_name": "Pranjal Jain", 4 | "description": "Pranjal Jains personal portfolio", 5 | "lang": "en-IN", 6 | "start_url": "/", 7 | "display": "minimal-ui", 8 | "theme_color": "#000000", 9 | "background_color": "#000000", 10 | "icons": [ 11 | { 12 | "src": "./android-chrome-192x192.png", 13 | "sizes": "192x192", 14 | "type": "image/png" 15 | }, 16 | { 17 | "src": "./android-chrome-512x512.png", 18 | "sizes": "512x512", 19 | "type": "image/png", 20 | "purpose": "any maskable" 21 | }, 22 | { 23 | "src": "./apple-touch-icon.png", 24 | "sizes": "180x180", 25 | "type": "image/png" 26 | }, 27 | { 28 | "src": "./favicon-32x32.png", 29 | "sizes": "32x32", 30 | "type": "image/png" 31 | }, 32 | { 33 | "src": "./favicon-16x16.png", 34 | "sizes": "16x16", 35 | "type": "image/png" 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /public/favicon/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Personal Portfolio", 3 | "name": "Pranjal Jain's Personal portfolio", 4 | "icons": [ 5 | { 6 | "src": "/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "start_url": ".", 17 | "display": "standalone", 18 | "theme_color": "#000000", 19 | "background_color": "#ffffff" 20 | } 21 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 17 | 22 | 28 | 34 | 35 | 36 | Pranjal Jain 37 | 42 | 43 | 44 | 45 |
46 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | Sitemap: http://pranjalis.me/sitemap.xml -------------------------------------------------------------------------------- /public/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | https://pranjalis.me/ 9 | 2021-05-26T19:22:07+00:00 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import 'bootstrap/dist/css/bootstrap.min.css' 2 | 3 | import CustomRoutes from './navigation' 4 | import React from 'react' 5 | 6 | const App = () => 7 | // const App = () =>

Pranjal

8 | 9 | export default App 10 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | // __tests__/hidden-message.js 2 | // these imports are something you'd normally configure Jest to import for you 3 | // automatically. Learn more in the setup docs: https://testing-library.com/docs/react-testing-library/setup#cleanup 4 | import '@testing-library/jest-dom' 5 | // NOTE: jest-dom adds handy assertions to Jest and is recommended, but not required 6 | 7 | import React from 'react' 8 | import {render, fireEvent, screen} from '@testing-library/react' 9 | import HiddenMessage from './hidden-message' 10 | 11 | test('shows the children when the checkbox is checked', () => { 12 | const testMessage = 'Test Message' 13 | render({testMessage}) 14 | 15 | // query* functions will return the element or null if it cannot be found 16 | // get* functions will return the element or throw an error if it cannot be found 17 | expect(screen.queryByText(testMessage)).toBeNull() 18 | 19 | // the queries can accept a regex to make your selectors more resilient to content tweaks and changes. 20 | fireEvent.click(screen.getByLabelText(/show/i)) 21 | 22 | // .toBeInTheDocument() is an assertion that comes from jest-dom 23 | // otherwise you could use .toBeDefined() 24 | expect(screen.getByText(testMessage)).toBeInTheDocument() 25 | }) 26 | -------------------------------------------------------------------------------- /src/Downloadables/Pranjal_Jain_CV.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/src/Downloadables/Pranjal_Jain_CV.pdf -------------------------------------------------------------------------------- /src/Downloadables/Resume.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/src/Downloadables/Resume.pdf -------------------------------------------------------------------------------- /src/Downloadables/goldman_completion_certificate.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/src/Downloadables/goldman_completion_certificate.pdf -------------------------------------------------------------------------------- /src/Terms/Privacy.md: -------------------------------------------------------------------------------- 1 | **Privacy Policy** 2 | 3 | Pranjal Jain built the Covid19India app as an Open Source app. This SERVICE is provided by Pranjal Jain at no cost and is intended for use as is. 4 | 5 | This page is used to inform visitors regarding my policies with the collection, use, and disclosure of Personal Information if anyone decided to use my Service. 6 | 7 | If you choose to use my Service, then you agree to the collection and use of information in relation to this policy. The Personal Information that I collect is used for providing and improving the Service. I will not use or share your information with anyone except as described in this Privacy Policy. 8 | 9 | The terms used in this Privacy Policy have the same meanings as in our Terms and Conditions, which is accessible at Covid19India unless otherwise defined in this Privacy Policy. 10 | 11 | **Information Collection and Use** 12 | 13 | For a better experience, while using our Service, I may require you to provide us with certain personally identifiable information. The information that I request will be retained on your device and is not collected by me in any way. 14 | 15 | The app does use third party services that may collect information used to identify you. 16 | 17 | Link to privacy policy of third party service providers used by the app 18 | 19 | - [Google Play Services](https://www.google.com/policies/privacy/) 20 | - [Expo](https://expo.io/privacy) 21 | 22 | **Log Data** 23 | 24 | I want to inform you that whenever you use my Service, in a case of an error in the app I collect data and information (through third party products) on your phone called Log Data. This Log Data may include information such as your device Internet Protocol (“IP”) address, device name, operating system version, the configuration of the app when utilizing my Service, the time and date of your use of the Service, and other statistics. 25 | 26 | **Cookies** 27 | 28 | Cookies are files with a small amount of data that are commonly used as anonymous unique identifiers. These are sent to your browser from the websites that you visit and are stored on your device's internal memory. 29 | 30 | This Service does not use these “cookies” explicitly. However, the app may use third party code and libraries that use “cookies” to collect information and improve their services. You have the option to either accept or refuse these cookies and know when a cookie is being sent to your device. If you choose to refuse our cookies, you may not be able to use some portions of this Service. 31 | 32 | **Service Providers** 33 | 34 | I may employ third-party companies and individuals due to the following reasons: 35 | 36 | - To facilitate our Service; 37 | - To provide the Service on our behalf; 38 | - To perform Service-related services; or 39 | - To assist us in analyzing how our Service is used. 40 | 41 | I want to inform users of this Service that these third parties have access to your Personal Information. The reason is to perform the tasks assigned to them on our behalf. However, they are obligated not to disclose or use the information for any other purpose. 42 | 43 | **Security** 44 | 45 | I value your trust in providing us your Personal Information, thus we are striving to use commercially acceptable means of protecting it. But remember that no method of transmission over the internet, or method of electronic storage is 100% secure and reliable, and I cannot guarantee its absolute security. 46 | 47 | **Links to Other Sites** 48 | 49 | This Service may contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these external sites are not operated by me. Therefore, I strongly advise you to review the Privacy Policy of these websites. I have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services. 50 | 51 | **Children’s Privacy** 52 | 53 | These Services do not address anyone under the age of 13. I do not knowingly collect personally identifiable information from children under 13\. In the case I discover that a child under 13 has provided me with personal information, I immediately delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact me so that I will be able to do necessary actions. 54 | 55 | **Changes to This Privacy Policy** 56 | 57 | I may update our Privacy Policy from time to time. Thus, you are advised to review this page periodically for any changes. I will notify you of any changes by posting the new Privacy Policy on this page. 58 | 59 | This policy is effective as of 2020-05-14 60 | 61 | **Contact Us** 62 | 63 | If you have any questions or suggestions about my Privacy Policy, do not hesitate to contact me at Web Palace. 64 | -------------------------------------------------------------------------------- /src/Terms/Terms.md: -------------------------------------------------------------------------------- 1 | **Terms & Conditions** 2 | 3 | By downloading or using the app, these terms will automatically apply to you – you should make sure therefore that you read them carefully before using the app. You’re not allowed to copy, or modify the app, any part of the app, or our trademarks in any way. You’re not allowed to attempt to extract the source code of the app, and you also shouldn’t try to translate the app into other languages, or make derivative versions. The app itself, and all the trade marks, copyright, database rights and other intellectual property rights related to it, still belong to Pranjal Jain. 4 | 5 | Pranjal Jain is committed to ensuring that the app is as useful and efficient as possible. For that reason, we reserve the right to make changes to the app or to charge for its services, at any time and for any reason. We will never charge you for the app or its services without making it very clear to you exactly what you’re paying for. 6 | 7 | The Covid19India app stores and processes personal data that you have provided to us, in order to provide my Service. It’s your responsibility to keep your phone and access to the app secure. We therefore recommend that you do not jailbreak or root your phone, which is the process of removing software restrictions and limitations imposed by the official operating system of your device. It could make your phone vulnerable to malware/viruses/malicious programs, compromise your phone’s security features and it could mean that the Covid19India app won’t work properly or at all. 8 | 9 | The app does use third party services that declare their own Terms and Conditions. 10 | 11 | Link to Terms and Conditions of third party service providers used by the app 12 | 13 | - [Google Play Services](https://policies.google.com/terms) 14 | - [Expo](https://expo.io/terms) 15 | 16 | You should be aware that there are certain things that Pranjal Jain will not take responsibility for. Certain functions of the app will require the app to have an active internet connection. The connection can be Wi-Fi, or provided by your mobile network provider, but Pranjal Jain cannot take responsibility for the app not working at full functionality if you don’t have access to Wi-Fi, and you don’t have any of your data allowance left. 17 | 18 | If you’re using the app outside of an area with Wi-Fi, you should remember that your terms of the agreement with your mobile network provider will still apply. As a result, you may be charged by your mobile provider for the cost of data for the duration of the connection while accessing the app, or other third party charges. In using the app, you’re accepting responsibility for any such charges, including roaming data charges if you use the app outside of your home territory (i.e. region or country) without turning off data roaming. If you are not the bill payer for the device on which you’re using the app, please be aware that we assume that you have received permission from the bill payer for using the app. 19 | 20 | Along the same lines, Pranjal Jain cannot always take responsibility for the way you use the app i.e. You need to make sure that your device stays charged – if it runs out of battery and you can’t turn it on to avail the Service, Pranjal Jain cannot accept responsibility. 21 | 22 | With respect to Pranjal Jain’s responsibility for your use of the app, when you’re using the app, it’s important to bear in mind that although we endeavour to ensure that it is updated and correct at all times, we do rely on third parties to provide information to us so that we can make it available to you. Pranjal Jain accepts no liability for any loss, direct or indirect, you experience as a result of relying wholly on this functionality of the app. 23 | 24 | At some point, we may wish to update the app. The app is currently available on Android – the requirements for system(and for any additional systems we decide to extend the availability of the app to) may change, and you’ll need to download the updates if you want to keep using the app. Pranjal Jain does not promise that it will always update the app so that it is relevant to you and/or works with the Android version that you have installed on your device. However, you promise to always accept updates to the application when offered to you, We may also wish to stop providing the app, and may terminate use of it at any time without giving notice of termination to you. Unless we tell you otherwise, upon any termination, (a) the rights and licenses granted to you in these terms will end; (b) you must stop using the app, and (if needed) delete it from your device. 25 | 26 | **Changes to This Terms and Conditions** 27 | 28 | I may update our Terms and Conditions from time to time. Thus, you are advised to review this page periodically for any changes. I will notify you of any changes by posting the new Terms and Conditions on this page. 29 | 30 | These terms and conditions are effective as of 2020-05-14 31 | 32 | **Contact Us** 33 | 34 | If you have any questions or suggestions about my Terms and Conditions, do not hesitate to contact me at Web Palace. 35 | -------------------------------------------------------------------------------- /src/assets/Image/logo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/src/assets/Image/logo.ai -------------------------------------------------------------------------------- /src/assets/Image/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/src/assets/Image/logo.png -------------------------------------------------------------------------------- /src/assets/Image/logo.svg: -------------------------------------------------------------------------------- 1 | logo -------------------------------------------------------------------------------- /src/assets/fonts/Avenir.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/src/assets/fonts/Avenir.otf -------------------------------------------------------------------------------- /src/assets/fonts/AvenirBold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/src/assets/fonts/AvenirBold.otf -------------------------------------------------------------------------------- /src/assets/fonts/Google sans/Google sans Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/src/assets/fonts/Google sans/Google sans Bold.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/Google sans/Google sans Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/src/assets/fonts/Google sans/Google sans Medium.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Google sans/Google sans regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/src/assets/fonts/Google sans/Google sans regular.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Google sans/GoogleSans.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pranjaljain0/portfolio-react/cd84ff987cc7d2f46dbb312ff517502ba77444e2/src/assets/fonts/Google sans/GoogleSans.woff2 -------------------------------------------------------------------------------- /src/components/Accordian/Accordian.js: -------------------------------------------------------------------------------- 1 | import './Accordian.scss' 2 | 3 | import {BsChevronDown, BsChevronUp} from 'react-icons/bs' 4 | import React, {useState} from 'react' 5 | 6 | import {AiOutlineLink} from 'react-icons/ai' 7 | 8 | function Accordian({title, data}) { 9 | const [showAccordian, setShowAccordian] = useState(true) 10 | return ( 11 |
12 |
13 |
14 |

{title}

15 | 16 | 17 | 18 | {data.duration} 19 |
20 | setShowAccordian(!showAccordian)} 24 | > 25 | {!showAccordian ? : } 26 | 27 |
28 | {showAccordian && ( 29 |
30 |
    31 | {data.description.map((item, index) => ( 32 |
  • {item}
  • 33 | ))} 34 |
35 |
36 | )} 37 |
38 | ) 39 | } 40 | 41 | export default Accordian 42 | -------------------------------------------------------------------------------- /src/components/Accordian/Accordian.scss: -------------------------------------------------------------------------------- 1 | .portfolio-accordian { 2 | & h3 { 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | display: flex; 8 | background-color: rgba($color: #000000, $alpha: 0.7); 9 | color: #fff; 10 | flex-direction: column; 11 | margin: 10px 0; 12 | padding: 10px; 13 | border-radius: 8px; 14 | 15 | & .header { 16 | display: flex; 17 | justify-content: space-between; 18 | align-items: center; 19 | 20 | & .dropdown-icon { 21 | background-color: #000000; 22 | display: flex; 23 | justify-content: center; 24 | align-items: center; 25 | padding: 8px; 26 | border-radius: 50% 50%; 27 | } 28 | 29 | & .title { 30 | display: flex; 31 | justify-content: center; 32 | align-items: center; 33 | 34 | & span { 35 | margin-left: 8px; 36 | color: rgba($color: #fff, $alpha: 0.6); 37 | } 38 | 39 | & a { 40 | margin-left: 8px; 41 | } 42 | } 43 | } 44 | 45 | & .content { 46 | display: flex; 47 | border-top: 1px solid #fff; 48 | margin-top: 10px; 49 | padding-top: 10px; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/components/CodeList.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import styled from 'styled-components' 3 | 4 | const Card = styled.div` 5 | color: #1d1d1d; 6 | ` 7 | 8 | const Table = styled.table` 9 | width: 100%; 10 | background-color: #1d1d1d; 11 | color: #fff; 12 | border-radius: 11px; 13 | overflow: hidden; 14 | ` 15 | const TR = styled.tr` 16 | display: flex; 17 | background-color: ${(props) => (props.index % 2 ? '#1d1d1d' : '#1d3557')}; 18 | ` 19 | 20 | const TD = styled.td` 21 | flex: 1; 22 | padding: 20px; 23 | ` 24 | 25 | function CodeList({CodeListVal}) { 26 | return ( 27 | 28 | 29 | {CodeListVal.map((Obj, index) => { 30 | return ( 31 |
32 |
33 | 34 | 35 | 36 | 37 | ) 38 | })} 39 |
{Obj.title}{Obj.level}
40 |
41 | ) 42 | } 43 | 44 | export default CodeList 45 | -------------------------------------------------------------------------------- /src/components/Education.js: -------------------------------------------------------------------------------- 1 | import 'react-vertical-timeline-component/style.min.css' 2 | 3 | import { 4 | VerticalTimeline, 5 | VerticalTimelineElement, 6 | } from 'react-vertical-timeline-component' 7 | 8 | import React from 'react' 9 | import {RiBuildingLine} from 'react-icons/ri' 10 | 11 | function Education({EducationObj}) { 12 | return ( 13 | 14 | {EducationObj.map((Obj, index) => { 15 | return ( 16 | } 24 | > 25 |

{Obj.title}

26 |
27 | {Obj.location_city} 28 |
29 |
30 | {Obj.location_state} 31 |
32 |
33 | {Obj.location_country} 34 |
35 |

{Obj.description}

36 |

{Obj.sec_details}

37 |
38 | ) 39 | })} 40 |
41 | ) 42 | } 43 | 44 | export default Education 45 | -------------------------------------------------------------------------------- /src/components/Hobby.js: -------------------------------------------------------------------------------- 1 | import { 2 | FaDumbbell, 3 | FaGuitar, 4 | FaNetworkWired, 5 | FaPuzzlePiece, 6 | } from 'react-icons/fa' 7 | import {MdCardTravel, MdComputer} from 'react-icons/md' 8 | 9 | import React from 'react' 10 | import styled from 'styled-components' 11 | 12 | function hobbyIconCheck(iconName, size) { 13 | if (iconName === 'FaPuzzlePiece') 14 | return 15 | else if (iconName === 'MdComputer') 16 | return 17 | else if (iconName === 'FaDumbbell') 18 | return 19 | else if (iconName === 'MdCardTravel') 20 | return 21 | else if (iconName === 'FaNetworkWired') 22 | return 23 | else if (iconName === 'FaGuitar') return 24 | } 25 | 26 | const Card = styled.div` 27 | color: #1d1d1d; 28 | ` 29 | 30 | const Table = styled.table` 31 | width: 100%; 32 | background-color: #1d1d1d; 33 | color: #fff; 34 | border-radius: 11px; 35 | overflow: hidden; 36 | ` 37 | const TR = styled.tr` 38 | display: flex; 39 | align-items: center; 40 | background-color: ${(props) => (props.index % 2 ? '#1d1d1d' : '#1d3557')}; 41 | ` 42 | 43 | const TD = styled.td` 44 | flex: 1; 45 | padding: 20px; 46 | ` 47 | 48 | const HobbyIcon = styled.div` 49 | margin-left: 10px; 50 | ` 51 | 52 | function Hobby({HobbyListVal}) { 53 | return ( 54 | 55 | 56 | {HobbyListVal.map((Obj, index) => { 57 | return ( 58 | 59 | 60 | {hobbyIconCheck(Obj.hobbyIcon, '30px')} 61 | 62 | 63 | 64 | ) 65 | })} 66 |
{Obj.title}
67 |
68 | ) 69 | } 70 | 71 | export default Hobby 72 | -------------------------------------------------------------------------------- /src/components/Home.js: -------------------------------------------------------------------------------- 1 | import {Col, Container, Row} from 'react-bootstrap' 2 | 3 | import HomeAbout from './HomeAbout' 4 | import Left from './Left' 5 | // import Navigation from "./Navigation"; 6 | import React from 'react' 7 | import homecards from '../data/homecards.json' 8 | import loadable from '@loadable/component' 9 | 10 | // const HomeAbout = loadable(() => import("./HomeAbout")); 11 | const Navigation = loadable(() => import('./Navigation')) 12 | const HomeCard = loadable(() => import('./HomeCard')) 13 | // const Left = loadable(() => import("./Left")); 14 | 15 | export default function Home() { 16 | const HomeCards = homecards.data 17 | 18 | return ( 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |

About Me

29 | 30 | 31 |
32 | 33 | {HomeCards.map((HomeCards, index) => { 34 | return 35 | })} 36 | 37 |
38 | 39 |
40 |
41 |
42 | ) 43 | } 44 | -------------------------------------------------------------------------------- /src/components/HomeAbout.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Home_data from '../data/home_data.json' 3 | 4 | function HomeAbout() { 5 | return ( 6 |
7 |

{Home_data.data.about}

8 |
9 | ) 10 | } 11 | 12 | export default HomeAbout 13 | -------------------------------------------------------------------------------- /src/components/HomeCard.js: -------------------------------------------------------------------------------- 1 | import {GiBookshelf, GiThorHammer} from 'react-icons/gi' 2 | import React, {useState} from 'react' 3 | 4 | import {Col} from 'react-bootstrap' 5 | import {DiJavascript1} from 'react-icons/di' 6 | import {FaGuitar} from 'react-icons/fa' 7 | import {GoRepo} from 'react-icons/go' 8 | import HomeModal from './HomeModal' 9 | import {TiSocialAtCircular} from 'react-icons/ti' 10 | 11 | function seticon(iconName, size) { 12 | if (iconName === 'FaGuitar') return 13 | else if (iconName === 'GiBookshelf') 14 | return 15 | else if (iconName === 'GiThorHammer') 16 | return 17 | else if (iconName === 'DiJavascript1') 18 | return 19 | else if (iconName === 'GoRepo') return 20 | else if (iconName === 'TiSocialAtCircular') 21 | return 22 | } 23 | 24 | function HomeCard({HomeCards}) { 25 | const [lgShow, setLgShow] = useState(false) 26 | 27 | return ( 28 | 29 | 30 |
31 | setLgShow(true)} className='projectLink'> 32 |
43 |

{HomeCards.title}

44 |
45 | {seticon(HomeCards.icon, '50px')} 46 |
47 |
48 |
49 |
50 | 51 | 52 |
53 | ) 54 | } 55 | 56 | export default HomeCard 57 | -------------------------------------------------------------------------------- /src/components/HomeModal.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {Modal} from 'react-bootstrap' 3 | import ProjectList from '../pages/ProjectList' 4 | import CodeList from './CodeList' 5 | import Hobby from './Hobby' 6 | import Education from './Education' 7 | import SocialModal from './SocialModal' 8 | import WorkExp from './WorkExp' 9 | 10 | function setModal(value, valObj) { 11 | if (value === 'Projects') { 12 | return 13 | } else if (value === 'Coding') { 14 | return 15 | } else if (value === 'Hobbies & Interest') { 16 | return 17 | } else if (value === 'Education') { 18 | return 19 | } else if (value === 'Contact') { 20 | return 21 | } else if (value === 'Work Experience') { 22 | return 23 | } 24 | } 25 | 26 | function HomeModal({lgShow, setLgShow, HomeCards}) { 27 | return ( 28 | setLgShow(false)} 32 | aria-labelledby='example-modal-sizes-title-lg' 33 | > 34 | 35 | 36 | {HomeCards.title} 37 | 38 | 39 | {setModal(HomeCards.title, HomeCards.value)} 40 | 41 | ) 42 | } 43 | 44 | export default HomeModal 45 | -------------------------------------------------------------------------------- /src/components/Left.js: -------------------------------------------------------------------------------- 1 | import {Col} from 'react-bootstrap' 2 | import LeftText from './LeftText' 3 | import React from 'react' 4 | // import loadable from '@loadable/component' 5 | 6 | // const Particles = loadable(() => import('react-tsparticles')) 7 | 8 | function Left() { 9 | return ( 10 | 11 | 12 | 13 | ) 14 | } 15 | 16 | export default Left 17 | -------------------------------------------------------------------------------- /src/components/LeftText.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Typed from 'react-typed' 3 | 4 | function LeftText() { 5 | return ( 6 |
7 |
8 |

Hi,

9 | I am 10 |

Pranjal Jain

11 |

12 | 23 |

24 |
25 |
26 | ) 27 | } 28 | 29 | export default LeftText 30 | -------------------------------------------------------------------------------- /src/components/Navigation.js: -------------------------------------------------------------------------------- 1 | import { Button, Nav, Navbar } from 'react-bootstrap' 2 | import { FaDownload, FaGithub, FaLinkedin } from 'react-icons/fa' 3 | import React, { useState } from 'react' 4 | 5 | import PortfolioLogo from '../assets/Image/logo.svg' 6 | import loadable from '@loadable/component' 7 | 8 | const ResumeModal = loadable(() => import('./ResumeModal')) 9 | // import ResumeModal from "./ResumeModal"; 10 | 11 | function Navigation() { 12 | const [showResumeModal, setShowResumeModal] = useState(false) 13 | 14 | return ( 15 | 16 | 17 | 18 | navbar_logo 19 | Pranjal Jain 20 | 21 | 22 | 23 | 24 | 80 | 81 | 82 | { 85 | setShowResumeModal(!showResumeModal) 86 | }} 87 | /> 88 | 89 | ) 90 | } 91 | 92 | export default Navigation 93 | -------------------------------------------------------------------------------- /src/components/ProjectCard.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {Col} from 'react-bootstrap' 3 | 4 | function ProjectCard({projectObj}) { 5 | return ( 6 | 7 | 24 | 25 | ) 26 | } 27 | 28 | export default ProjectCard 29 | -------------------------------------------------------------------------------- /src/components/ResumeModal.js: -------------------------------------------------------------------------------- 1 | import {Modal} from 'react-bootstrap' 2 | import React from 'react' 3 | 4 | function ResumeModal({showResumeModal, closeModal}) { 5 | return ( 6 | 12 | 13 | Resume 14 | 15 | 16 | 23 | 24 | 25 | ) 26 | } 27 | 28 | export default ResumeModal 29 | -------------------------------------------------------------------------------- /src/components/SocialModal.js: -------------------------------------------------------------------------------- 1 | import {AiOutlineGithub, AiOutlineLinkedin} from 'react-icons/ai' 2 | import {Button, Container, FormControl, InputGroup} from 'react-bootstrap' 3 | 4 | import React from 'react' 5 | import styled from 'styled-components' 6 | 7 | const Social = styled.div` 8 | display: flex; 9 | flex-direction: column; 10 | min-height: 50vh; 11 | padding: 5px; 12 | ` 13 | 14 | const SocialIcons = styled.div` 15 | display: flex; 16 | width: 100%; 17 | ` 18 | 19 | const CustomLink = styled.a` 20 | display: block; 21 | color: inherit; 22 | text-decoration: none; 23 | &:hover { 24 | color: inherit; 25 | text-decoration: none; 26 | } 27 | ` 28 | 29 | const Icon = styled.div` 30 | flex: 1; 31 | text-align: center; 32 | margin-bottom: 20px; 33 | padding: 20px; 34 | background-color: #ebf2fa; 35 | border-radius: 11px; 36 | cursor: pointer; 37 | vertical-align: middle; 38 | background: #d6249f; 39 | ${(props) => { 40 | if (props.label === 'instagram') { 41 | return 'background: radial-gradient(circle at 30% 107%, #fdf497 0%, #fdf497 5%, #fd5949 45%,#d6249f 60%,#285AEB 90%);' 42 | } else if (props.label === 'github') { 43 | return 'background: linear-gradient(to top, #7dbbe6 0%,#00acee 100%); margin-right: 20px;' 44 | } else if (props.label === 'linkedin') { 45 | return 'background: linear-gradient(to top, #0e76a8 0%,#00acee 100%);' 46 | } 47 | }} 48 | box-shadow: 0px 3px 10px rgba(0,0,0,.25); 49 | color: #fff; 50 | & svg { 51 | flex: 1; 52 | height: 50px; 53 | } 54 | ` 55 | 56 | const ButtonForm = styled.div` 57 | margin-top: 15px; 58 | ` 59 | 60 | function SocialModal() { 61 | return ( 62 | 63 | 64 | 65 | 66 | 67 | 68 | @pranjaljain0 69 | 70 | 71 | 72 | 73 | 77 | @pranjaljain0 78 | 79 | 80 | 81 | 82 | 83 | 88 | 89 | 90 | 91 | 96 | 97 | 98 | 99 | 108 | 109 | 110 | 111 | 114 | 115 | 116 | 117 | ) 118 | } 119 | 120 | export default SocialModal 121 | -------------------------------------------------------------------------------- /src/components/WorkExp.js: -------------------------------------------------------------------------------- 1 | import Accordian from './Accordian/Accordian' 2 | import React from 'react' 3 | 4 | function WorkExp({WorkExpObj}) { 5 | return ( 6 |
7 | {WorkExpObj.map((Obj, index) => { 8 | return 9 | })} 10 |
11 | ) 12 | } 13 | 14 | export default WorkExp 15 | -------------------------------------------------------------------------------- /src/data/home_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "about": "I discovered my passion for computer science when I was a sophomore in High School; it was then, when I started learning more for my passion. I am pursuing my bachelor's degree at Avantika University, major in Computer science and engineering. A year later I was introduced to Embedded systems, where I discovered the love for electrics and electronics and also for embedded systems. Then I got a scholarship opportunity to do a research work on Smart grid and started the never-ending journey of becoming a developer along with sharpening my eye for innovations." 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/data/homecards.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "title": "Projects", 5 | "value": [ 6 | { 7 | "id": 1, 8 | "title": "Chatbox", 9 | "description": "This is an application developed for an in-depth understanding of WebSockets. For the front end, I have used React JS and sockets IO & For the backend, implemented sockets using Express JS.", 10 | "projectRoute": "https://chatbox-frontend.vercel.app/", 11 | "githubUrl": "https://github.com/pranjaljain0/chatbox-frontend", 12 | "badgeTitle": [ 13 | "Socket", 14 | "ReactJS", 15 | "ExpressJS", 16 | "HTML", 17 | "CSS" 18 | ], 19 | "initialColor": "#56CCF2", 20 | "finalColor": "#2F80ED", 21 | "language": "C++" 22 | }, 23 | { 24 | "id": 2, 25 | "title": "The Yellow Mushroom", 26 | "description": "Created a website home page for a start-up company that is in the field of Design and Development. Created the frontend using React JS using multiple custom-made reusable components.", 27 | "projectRoute": "https://yellowmushrooms.netlify.app/", 28 | "badgeTitle": [ 29 | "ReactJS", 30 | "ExpressJS", 31 | "HTML", 32 | "CSS" 33 | ], 34 | "initialColor": "#373B44", 35 | "finalColor": "#4286f4", 36 | "language": "Java" 37 | }, 38 | { 39 | "id": 3, 40 | "title": "Refactored Waffles", 41 | "description": "This is a web application made as a submission for the MongoDB Atlas Hackathon 2021, This project is an E-commerce store purely made using tools provided by MondoDB", 42 | "projectRoute": "https://refactored-waffle-lake.vercel.app/", 43 | "githubUrl": "https://github.com/pranjaljain0/refactored-waffle", 44 | "badgeTitle": [ 45 | "NextJS", 46 | "MongoDB", 47 | "HTML", 48 | "CSS" 49 | ], 50 | "initialColor": "#f12711", 51 | "finalColor": "#f5af19", 52 | "language": "JavaScript" 53 | }, 54 | { 55 | "id": 4, 56 | "title": "ZenHotline", 57 | "projectRoute": "https://dev.zenhotline.com/", 58 | "description": "Initiated a medical teleconsultation platform using reactJS as a front-end framework created almost 40+ reusable components Executed a middleware with ExpressJS that consisted of 60+ endpoints to perform backend operations Integrated nearly 10 accessories tools to schedule, maintain and organize meetings/video calls between clients and professionals", 59 | "badgeTitle": [ 60 | "ReactJS", 61 | "ExpressJS", 62 | "HTML", 63 | "CSS", 64 | "Firebase" 65 | ], 66 | "initialColor": "#11998e", 67 | "finalColor": "#38ef7d", 68 | "language": "Haskell" 69 | }, 70 | { 71 | "id": 5, 72 | "title": "Cards", 73 | "projectRoute": "https://credit-card-landing-page-ui.vercel.app/", 74 | "description": "Its a project where I was exploring integration of 3D objects which are exported from blender to the web applications which can in turn make the web a more enhanced experience for users.", 75 | "badgeTitle": [ 76 | "ReactJS", 77 | "ExpressJS", 78 | "HTML", 79 | "CSS", 80 | "ModelViewer", 81 | "Blender", 82 | "ThreeJS" 83 | ], 84 | "githubUrl": "https://github.com/pranjaljain0/Credit-Card-Landing-Page-UI", 85 | "initialColor": "#f05053", 86 | "finalColor": "#e1eec3", 87 | "language": "Ruby" 88 | } 89 | ], 90 | "route": "/projects", 91 | "initialColor": "#56CCF2", 92 | "finalColor": "#2F80ED", 93 | "icon": "GiThorHammer" 94 | }, 95 | { 96 | "title": "Coding", 97 | "value": [ 98 | { 99 | "title": "Python", 100 | "level": "Advance" 101 | }, 102 | { 103 | "title": "HTML", 104 | "level": "Advance" 105 | }, 106 | { 107 | "title": "PHP", 108 | "level": "Advance" 109 | }, 110 | { 111 | "title": "JAVA", 112 | "level": "Advance" 113 | }, 114 | { 115 | "title": "C++", 116 | "level": "Advance" 117 | }, 118 | { 119 | "title": "C", 120 | "level": "Advance" 121 | }, 122 | { 123 | "title": "Android", 124 | "level": "Intermediate" 125 | }, 126 | { 127 | "title": "JS", 128 | "level": "Intermediate" 129 | }, 130 | { 131 | "title": "MongoDB", 132 | "level": "Intermediate" 133 | }, 134 | { 135 | "title": "ReactJS", 136 | "level": "Beginner" 137 | } 138 | ], 139 | "route": "/languages", 140 | "initialColor": "#373B44", 141 | "finalColor": "#4286f4", 142 | "icon": "DiJavascript1" 143 | }, 144 | { 145 | "title": "Hobbies & Interest", 146 | "value": [ 147 | { 148 | "title": "Solving puzzles", 149 | "hobbyIcon": "FaPuzzlePiece" 150 | }, 151 | { 152 | "title": "Computing", 153 | "hobbyIcon": "MdComputer" 154 | }, 155 | { 156 | "title": "Going to the gym", 157 | "hobbyIcon": "FaDumbbell" 158 | }, 159 | { 160 | "title": "Travelling", 161 | "hobbyIcon": "MdCardTravel" 162 | }, 163 | { 164 | "title": "Networking", 165 | "hobbyIcon": "FaNetworkWired" 166 | }, 167 | { 168 | "title": "Playing guitar", 169 | "hobbyIcon": "FaGuitar" 170 | } 171 | ], 172 | "route": "#", 173 | "initialColor": "#f12711", 174 | "finalColor": "#f5af19", 175 | "icon": "FaGuitar" 176 | }, 177 | { 178 | "title": "Education", 179 | "value": [ 180 | { 181 | "title": "New Jersey Institute of Technology", 182 | "duration": "2021-2023", 183 | "location_city": "Newark", 184 | "location_state": "New Jersey", 185 | "location_country": "US", 186 | "description": "Masters of Scinece", 187 | "sec_details": "Computer Science & Technology", 188 | "color": "#fef54b", 189 | "text": "#1d1d1d" 190 | }, 191 | { 192 | "title": "Avantika University", 193 | "duration": "2017-2021", 194 | "location_city": "Ujjain", 195 | "location_state": "Madhya Pradesh", 196 | "location_country": "IN", 197 | "description": "Bachelor of Technology", 198 | "sec_details": "Specialization : Computer Science engineering", 199 | "color": "#fef54b", 200 | "text": "#1d1d1d" 201 | }, 202 | { 203 | "title": "The Sanskaar Valley School", 204 | "duration": "2012 - 2016", 205 | "location_city": "Bhopal", 206 | "location_state": "Madhya Pradesh", 207 | "location_country": "IN", 208 | "description": "High school", 209 | "sec_details": "ISC- 66%; ICSE- 87%", 210 | "color": "#ffe54a", 211 | "text": "#1d1d1d" 212 | }, 213 | { 214 | "title": "The Scindia School", 215 | "duration": "2008 - 2011", 216 | "location_city": "Gwalior", 217 | "location_state": "Madhya Pradesh", 218 | "location_country": "IN", 219 | "description": "High school", 220 | "sec_details": "", 221 | "color": "#ffd448", 222 | "text": "#1d1d1d" 223 | }, 224 | { 225 | "title": "St. Joseph's Co-ed School ", 226 | "duration": "2003 - 2007", 227 | "location_city": "Bhopal", 228 | "location_state": "Madhya Pradesh", 229 | "location_country": "IN", 230 | "description": "Middle school", 231 | "sec_details": "", 232 | "color": "#ffc446", 233 | "text": "#1d1d1d" 234 | } 235 | ], 236 | "route": "#", 237 | "initialColor": "#007991", 238 | "finalColor": "#78ffd6", 239 | "icon": "GiBookshelf" 240 | }, 241 | { 242 | "title": "Contact", 243 | "value": [ 244 | { 245 | "title": "instagram", 246 | "link": "" 247 | }, 248 | { 249 | "title": "linkedin", 250 | "link": "" 251 | }, 252 | { 253 | "title": "github", 254 | "link": "" 255 | }, 256 | { 257 | "title": "instagram", 258 | "link": "" 259 | } 260 | ], 261 | "route": "#", 262 | "initialColor": "#11998e", 263 | "finalColor": "#38ef7d", 264 | "icon": "TiSocialAtCircular" 265 | }, 266 | { 267 | "title": "Work Experience", 268 | "value": [ 269 | { 270 | "title": "HUDE Labs", 271 | "duration": "3 Months", 272 | "location": "Bhopal, Madhya Pradesh 462024, IN", 273 | "url": "http://hudelabs.com/", 274 | "description": [ 275 | "Learned and implemented the concept of Block Element Modifier in HTML & CSS." 276 | ] 277 | }, 278 | { 279 | "title": "Emote Electric", 280 | "description": [ 281 | "Developed and designed an interactive Website for Emote Electric, using HTML, CSS & PHP.", 282 | "Created AWS EC2 Instance to host the website on the AWS Cloud." 283 | ], 284 | "duration": "3 Months", 285 | "location": "Coimbatore, Tamil Nadu 641032, IN", 286 | "url": "https://emoteelectric.com/" 287 | }, 288 | { 289 | "title": "Semantic Technologies", 290 | "description": [ 291 | "Worked on the MyBenefits360 which is a comprehensive and powerful online portal that automates, manages and supports Core Insurance, Wellness Benefits and Fitness Integrations" 292 | ], 293 | "duration": "6 Months", 294 | "location": "Remote", 295 | "url": "https://www.mybenefits360.com/" 296 | }, 297 | { 298 | "title": "CollegePass", 299 | "description": [ 300 | "Developed and designed an interactive advising platform for college admission, using React.js, Node.js & AWS.", 301 | "Deployed service workers to perform browser operations on the PWA." 302 | ], 303 | "duration": "6 Months", 304 | "location": "Remote", 305 | "url": "https://collegepass.org/" 306 | } 307 | ], 308 | "route": "#", 309 | "initialColor": "#e1eec3", 310 | "finalColor": "#f05053", 311 | "icon": "GoRepo" 312 | } 313 | ] 314 | } -------------------------------------------------------------------------------- /src/hidden-message.js: -------------------------------------------------------------------------------- 1 | // hidden-message.js 2 | import React from 'react' 3 | 4 | // NOTE: React Testing Library works well with React Hooks and classes. 5 | // Your tests will be the same regardless of how you write your components. 6 | function HiddenMessage({children}) { 7 | const [showMessage, setShowMessage] = React.useState(false) 8 | return ( 9 |
10 | 11 | setShowMessage(e.target.checked)} 15 | checked={showMessage} 16 | /> 17 | {showMessage ? children : null} 18 |
19 | ) 20 | } 21 | 22 | export default HiddenMessage 23 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: Avenir; 3 | font-display: swap; 4 | unicode-range: U+000-5FF; 5 | /* Download only latin glyphs */ 6 | src: url(./assets/fonts/Avenir.otf); 7 | } 8 | 9 | @font-face { 10 | font-family: AvenirBold; 11 | font-display: swap; 12 | unicode-range: U+000-5FF; 13 | /* Download only latin glyphs */ 14 | src: url(./assets/fonts/AvenirBold.otf); 15 | } 16 | 17 | @font-face { 18 | font-family: GoogleSans; 19 | font-display: swap; 20 | font-style: normal; 21 | unicode-range: U+000-5FF; 22 | /* Download only latin glyphs */ 23 | src: url('./assets/fonts/Google sans/GoogleSans.woff2') format('woff2'); 24 | /* Super Modern Browsers */ 25 | } 26 | 27 | * { 28 | box-sizing: border-box; 29 | font-family: 'GoogleSans', 'Gill Sans', 'Gill Sans MT', Calibri, 30 | 'Trebuchet MS', sans-serif; 31 | } 32 | 33 | html, 34 | body, 35 | #app, 36 | #app > div { 37 | height: 100%; 38 | overflow-x: hidden; 39 | } 40 | 41 | .nvabar-custon { 42 | background: linear-gradient(120deg, #00e4d0, #5983e8); 43 | display: flex; 44 | justify-content: space-between; 45 | align-items: center; 46 | } 47 | 48 | .mainRow { 49 | height: 100%; 50 | display: flex; 51 | } 52 | 53 | .innerContainer { 54 | position: absolute; 55 | bottom: 0; 56 | height: 100%; 57 | padding-top: 55px; 58 | } 59 | 60 | .LeftSec { 61 | background-color: #1d1d1d; 62 | background: linear-gradient(0deg, #1d1d1d, rgb(19, 19, 19)); 63 | color: #fff; 64 | z-index: 999; 65 | max-width: 100%; 66 | } 67 | 68 | .navbar_logo_container { 69 | flex: 1; 70 | display: flex; 71 | align-items: center; 72 | justify-content: flex-start; 73 | margin-left: 20px; 74 | } 75 | 76 | .navbar_logo_container span { 77 | text-decoration: none; 78 | color: #fff; 79 | font-size: 1.8em; 80 | } 81 | 82 | .navbar_logo_container:hover { 83 | text-decoration: none; 84 | } 85 | 86 | a.navbar_logo_container { 87 | text-decoration: none; 88 | } 89 | 90 | .navbar-collapse { 91 | flex: 1 !important; 92 | align-items: center; 93 | justify-content: flex-end; 94 | } 95 | 96 | .moving-gradient { 97 | color: #fff; 98 | background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); 99 | background-size: 400% 400%; 100 | outline: none; 101 | border: 2px solid #fff; 102 | -webkit-animation: Gradient 15s ease infinite; 103 | -moz-animation: Gradient 15s ease infinite; 104 | animation: Gradient 15s ease infinite; 105 | width: 100% !important; 106 | } 107 | 108 | @media only screen and (max-width: 768px) { 109 | .moving-gradient button { 110 | width: 100vw !important; 111 | } 112 | } 113 | 114 | @-webkit-keyframes Gradient { 115 | 0% { 116 | background-position: 0% 50%; 117 | } 118 | 119 | 50% { 120 | background-position: 100% 50%; 121 | } 122 | 123 | 100% { 124 | background-position: 0% 50%; 125 | } 126 | } 127 | 128 | @-moz-keyframes Gradient { 129 | 0% { 130 | background-position: 0% 50%; 131 | } 132 | 133 | 50% { 134 | background-position: 100% 50%; 135 | } 136 | 137 | 100% { 138 | background-position: 0% 50%; 139 | } 140 | } 141 | 142 | @keyframes Gradient { 143 | 0% { 144 | background-position: 0% 50%; 145 | } 146 | 147 | 50% { 148 | background-position: 100% 50%; 149 | } 150 | 151 | 100% { 152 | background-position: 0% 50%; 153 | } 154 | } 155 | 156 | @media (min-width: 992px) { 157 | .navbar-expand-lg .navbar-nav { 158 | flex-direction: row; 159 | justify-content: center; 160 | align-items: center; 161 | } 162 | } 163 | 164 | .navbar_logo { 165 | height: 50px; 166 | margin: 0; 167 | padding: 0; 168 | margin-right: 10px; 169 | } 170 | 171 | .cols { 172 | margin: 0 !important; 173 | padding: 0 !important; 174 | } 175 | 176 | .RightSec { 177 | height: 100%; 178 | width: 100%; 179 | display: -webkit-box; 180 | display: -webkit-flex; 181 | display: -ms-flexbox; 182 | display: flex; 183 | margin: 0 !important; 184 | padding: 0 !important; 185 | } 186 | 187 | .RightUpperSec { 188 | width: 100%; 189 | display: -webkit-box; 190 | display: -webkit-flex; 191 | display: -ms-flexbox; 192 | display: flex; 193 | margin: 0 !important; 194 | padding: 0 !important; 195 | font-size: 16px; 196 | } 197 | 198 | .RightLowerSec { 199 | width: 100%; 200 | display: -webkit-box; 201 | display: -webkit-flex; 202 | display: -ms-flexbox; 203 | display: flex; 204 | margin: 0 !important; 205 | padding: 0 !important; 206 | } 207 | 208 | .ColStyle { 209 | background: linear-gradient(0deg, #434343, #000); 210 | color: #fff; 211 | margin: 0 !important; 212 | padding: 0 !important; 213 | display: flex; 214 | flex-direction: column; 215 | cursor: pointer; 216 | } 217 | 218 | .innerColImg { 219 | background-position: center; 220 | background-repeat: no-repeat; 221 | background-size: cover; 222 | height: 100%; 223 | transition: all 0.2s; 224 | padding: 20px; 225 | } 226 | 227 | .innerColImg:hover { 228 | transform: scale(1.2); 229 | } 230 | 231 | .innerCol { 232 | text-align: center; 233 | flex: 1; 234 | overflow: hidden; 235 | height: 200px; 236 | } 237 | 238 | .innerImage { 239 | align-self: center; 240 | width: 100%; 241 | } 242 | 243 | .particlejs { 244 | position: absolute; 245 | top: 0; 246 | bottom: 0; 247 | left: 0; 248 | width: 50%; 249 | } 250 | 251 | .preTitle { 252 | font-size: 180%; 253 | } 254 | 255 | .name_big { 256 | background: -webkit-linear-gradient(45deg, hsl(243, 100%, 59%), #00ff95 100%); 257 | -webkit-background-clip: text; 258 | background-clip: text; 259 | -webkit-text-fill-color: transparent; 260 | font-weight: 700; 261 | font-size: 250%; 262 | display: inline; 263 | } 264 | 265 | .leftText { 266 | height: 100%; 267 | display: flex; 268 | align-items: center; 269 | flex-direction: row; 270 | margin: 0px 40px; 271 | font-size: 140%; 272 | } 273 | 274 | .flex-fix { 275 | display: block; 276 | flex-direction: row; 277 | } 278 | 279 | a.projectLink { 280 | text-decoration: none !important; 281 | cursor: pointer; 282 | } 283 | 284 | .animated_text { 285 | font-size: 140%; 286 | font-weight: bold; 287 | } 288 | 289 | .projectTitle { 290 | font-size: 120%; 291 | color: #fff; 292 | margin: 20px 0px; 293 | } 294 | 295 | .RightUpperSecContent { 296 | margin: auto; 297 | padding: 1rem; 298 | display: flex; 299 | justify-content: center; 300 | align-items: flex-start; 301 | flex-direction: column; 302 | height: 100%; 303 | } 304 | 305 | .RightUpperSecContent h2 { 306 | background: -webkit-linear-gradient(45deg, hsl(243, 100%, 59%), #00ff95 100%); 307 | -webkit-background-clip: text; 308 | background-clip: text; 309 | -webkit-text-fill-color: transparent; 310 | font-weight: 700; 311 | font-size: 300%; 312 | display: inline; 313 | } 314 | 315 | .RightUpperSecContent p { 316 | margin: 0px 0px; 317 | } 318 | 319 | .projectValue { 320 | font-size: 180%; 321 | font-weight: bold; 322 | color: #fff; 323 | margin: auto 0; 324 | font-family: AvenirBold; 325 | } 326 | 327 | .iconHolder { 328 | display: flex; 329 | } 330 | 331 | .iconHolder svg { 332 | flex: 1; 333 | } 334 | 335 | .modal-content { 336 | border-radius: 11px !important; 337 | } 338 | 339 | .project_list_item_link { 340 | text-decoration: none; 341 | color: #fff; 342 | cursor: pointer; 343 | } 344 | 345 | .project_list_item_link:focus, 346 | .project_list_item_link:hover { 347 | text-decoration: none; 348 | color: #fff; 349 | } 350 | 351 | .project_list_item { 352 | width: 100%; 353 | padding: 20px; 354 | border-radius: 11px; 355 | background-color: #00e4d0; 356 | margin: 10px 0px; 357 | } 358 | 359 | .project_list_item a { 360 | text-decoration: none; 361 | color: #fff; 362 | } 363 | 364 | .projectGithubIcon { 365 | font-size: 1.8rem; 366 | margin-left: 10px; 367 | } 368 | 369 | .project_list_item .badge { 370 | margin: 4px 6px 4px 0px; 371 | font-size: 0.8em; 372 | padding: 6px 12px; 373 | } 374 | 375 | .VerticalTimeline::before { 376 | background-image: linear-gradient(0deg, red, yellow) !important; 377 | } 378 | 379 | .ButtonGroup { 380 | margin: 20px 0; 381 | } 382 | 383 | @media only screen and (max-width: 1190px) { 384 | /* For tab: */ 385 | 386 | .LeftSec { 387 | height: 100vh; 388 | } 389 | } 390 | 391 | @media only screen and (max-width: 768px) { 392 | /* For mobile phones: */ 393 | 394 | .LeftSec { 395 | height: 100vh; 396 | } 397 | } 398 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import './index.css' 2 | 3 | import * as serviceWorkerRegistration from './serviceWorkerRegistration' 4 | 5 | import App from './App' 6 | import React from 'react' 7 | import ReactDOM from 'react-dom/client' 8 | 9 | ReactDOM.createRoot(document.getElementById('root')).render( 10 | 11 | 12 | 13 | ) 14 | 15 | serviceWorkerRegistration.register() 16 | -------------------------------------------------------------------------------- /src/navigation/index.js: -------------------------------------------------------------------------------- 1 | import {Route, BrowserRouter as Router, Routes} from 'react-router-dom' 2 | 3 | import React from 'react' 4 | import routes from './routes' 5 | 6 | export default function CustomRoutes() { 7 | return ( 8 | 9 | 10 | {/* } /> */} 11 | {routes.map((route, i) => ( 12 | 13 | ))} 14 | 15 | 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /src/navigation/routes.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import loadable from '@loadable/component' 3 | const Home = loadable(() => 4 | import( 5 | /* webpackChunkName: "home" */ 6 | /* webpackPrefetch: true */ 7 | '../components/Home' 8 | ) 9 | ) 10 | const Project = loadable(() => 11 | import( 12 | /* webpackChunkName: "Project" */ 13 | '../pages/Project' 14 | ) 15 | ) 16 | const ProjectList = loadable(() => 17 | import( 18 | /* webpackChunkName: "ProjectList" */ 19 | '../pages/ProjectList' 20 | ) 21 | ) 22 | 23 | const routes = [ 24 | { 25 | path: '/', 26 | element: , 27 | exact: true, 28 | }, 29 | { 30 | path: '/projects', 31 | element: , 32 | }, 33 | { 34 | path: '/projects/:project_id', 35 | element: , 36 | }, 37 | ] 38 | 39 | export default routes 40 | -------------------------------------------------------------------------------- /src/pages/Project.js: -------------------------------------------------------------------------------- 1 | import {Col, Container, Row} from 'react-bootstrap' 2 | 3 | import Navigation from '../components/Navigation' 4 | import React from 'react' 5 | import homecards from '../data/homecards.json' 6 | 7 | function Project(props) { 8 | var project_id = props.match.params.project_id 9 | 10 | const projectsData = homecards.data.find((data) => data.title === 'Projects') 11 | const projectData = projectsData.value 12 | ? projectsData.value.find((project) => project.id === project_id) 13 | : {} 14 | 15 | return ( 16 | 17 | 18 | 19 | 20 | 21 | {Object.entries(projectData).map(([key, value], index) => { 22 | return ( 23 | 24 |

{key}

25 | {value} 26 |
27 | ) 28 | })} 29 | 30 |
31 |
32 |
33 | ) 34 | } 35 | 36 | export default Project 37 | -------------------------------------------------------------------------------- /src/pages/ProjectList.js: -------------------------------------------------------------------------------- 1 | import {AiFillGithub} from 'react-icons/ai' 2 | import {Badge} from 'react-bootstrap' 3 | import React from 'react' 4 | 5 | function ProjectList({ProjectListVal}) { 6 | return ( 7 |
8 | {ProjectListVal && 9 | ProjectListVal.sort((a, b) => { 10 | if (a.title > b.title) return 1 11 | if (a.title < b.title) return -1 12 | return 0 13 | }).map((Obj, index) => { 14 | return ( 15 | 20 |
31 |

32 | {Obj.title} 33 | {Obj.githubUrl && ( 34 | 35 | 36 | 37 | )} 38 |

39 | {Object.keys(Obj.badgeTitle).map((item, index) => { 40 | return ( 41 | 42 | {Obj.badgeTitle[item]} 43 | 44 | ) 45 | })} 46 |

{Obj.description}

47 |
48 | 49 | ) 50 | })} 51 |
52 | ) 53 | } 54 | 55 | export default ProjectList 56 | -------------------------------------------------------------------------------- /src/service-worker.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-restricted-globals */ 2 | 3 | // This service worker can be customized! 4 | // See https://developers.google.com/web/tools/workbox/modules 5 | // for the list of available Workbox modules, or add any other 6 | // code you'd like. 7 | // You can also remove this file if you'd prefer not to use a 8 | // service worker, and the Workbox build step will be skipped. 9 | 10 | import {createHandlerBoundToURL, precacheAndRoute} from 'workbox-precaching' 11 | 12 | import {ExpirationPlugin} from 'workbox-expiration' 13 | import {StaleWhileRevalidate} from 'workbox-strategies' 14 | import {clientsClaim} from 'workbox-core' 15 | import {registerRoute} from 'workbox-routing' 16 | 17 | clientsClaim() 18 | 19 | // Precache all of the assets generated by your build process. 20 | // Their URLs are injected into the manifest variable below. 21 | // This variable must be present somewhere in your service worker file, 22 | // even if you decide not to use precaching. See https://cra.link/PWA 23 | precacheAndRoute(self.__WB_MANIFEST) 24 | 25 | // Set up App Shell-style routing, so that all navigation requests 26 | // are fulfilled with your index.html shell. Learn more at 27 | // https://developers.google.com/web/fundamentals/architecture/app-shell 28 | const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$') 29 | registerRoute( 30 | // Return false to exempt requests from being fulfilled by index.html. 31 | ({request, url}) => { 32 | // If this isn't a navigation, skip. 33 | if (request.mode !== 'navigate') { 34 | return false 35 | } // If this is a URL that starts with /_, skip. 36 | 37 | if (url.pathname.startsWith('/_')) { 38 | return false 39 | } // If this looks like a URL for a resource, because it contains // a file extension, skip. 40 | 41 | if (url.pathname.match(fileExtensionRegexp)) { 42 | return false 43 | } // Return true to signal that we want to use the handler. 44 | 45 | return true 46 | }, 47 | createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html') 48 | ) 49 | 50 | // An example runtime caching route for requests that aren't handled by the 51 | // precache, in this case same-origin .png requests like those from in public/ 52 | registerRoute( 53 | // Add in any other file extensions or routing criteria as needed. 54 | ({url}) => 55 | url.origin === self.location.origin && url.pathname.endsWith('.png'), // Customize this strategy as needed, e.g., by changing to CacheFirst. 56 | new StaleWhileRevalidate({ 57 | cacheName: 'images', 58 | plugins: [ 59 | // Ensure that once this runtime cache reaches a maximum size the 60 | // least-recently used images are removed. 61 | new ExpirationPlugin({maxEntries: 50}), 62 | ], 63 | }) 64 | ) 65 | 66 | // This allows the web app to trigger skipWaiting via 67 | // registration.waiting.postMessage({type: 'SKIP_WAITING'}) 68 | self.addEventListener('message', (event) => { 69 | if (event.data && event.data.type === 'SKIP_WAITING') { 70 | self.skipWaiting() 71 | } 72 | }) 73 | 74 | // Any other custom service worker logic can go here. 75 | -------------------------------------------------------------------------------- /src/serviceWorkerRegistration.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://cra.link/PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.0/8 are considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ) 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 25 | // if ('serviceWorker' in navigator) { 26 | // The URL constructor is available in all browsers that support SW. 27 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href) 28 | if (publicUrl.origin !== window.location.origin) { 29 | // Our service worker won't work if PUBLIC_URL is on a different origin 30 | // from what our page is served on. This might happen if a CDN is used to 31 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 32 | return 33 | } 34 | 35 | window.addEventListener('load', () => { 36 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js` 37 | // const swUrl = `${process.env.PUBLIC_URL}/custom-service-worker.js`; 38 | 39 | if (isLocalhost) { 40 | // This is running on localhost. Let's check if a service worker still exists or not. 41 | checkValidServiceWorker(swUrl, config) 42 | 43 | // Add some additional logging to localhost, pointing developers to the 44 | // service worker/PWA documentation. 45 | navigator.serviceWorker.ready.then(() => { 46 | console.log( 47 | 'This web app is being served cache-first by a service ' + 48 | 'worker. To learn more, visit https://cra.link/PWA' 49 | ) 50 | }) 51 | } else { 52 | // Is not localhost. Just register service worker 53 | registerValidSW(swUrl, config) 54 | } 55 | }) 56 | } 57 | } 58 | 59 | function registerValidSW(swUrl, config) { 60 | navigator.serviceWorker 61 | .register(swUrl) 62 | .then((registration) => { 63 | registration.onupdatefound = () => { 64 | const installingWorker = registration.installing 65 | if (installingWorker == null) { 66 | return 67 | } 68 | installingWorker.onstatechange = () => { 69 | if (installingWorker.state === 'installed') { 70 | if (navigator.serviceWorker.controller) { 71 | // At this point, the updated precached content has been fetched, 72 | // but the previous service worker will still serve the older 73 | // content until all client tabs are closed. 74 | console.log( 75 | 'New content is available and will be used when all ' + 76 | 'tabs for this page are closed. See https://cra.link/PWA.' 77 | ) 78 | 79 | // Execute callback 80 | if (config && config.onUpdate) { 81 | config.onUpdate(registration) 82 | } 83 | } else { 84 | // At this point, everything has been precached. 85 | // It's the perfect time to display a 86 | // "Content is cached for offline use." message. 87 | console.log('Content is cached for offline use.') 88 | 89 | // Execute callback 90 | if (config && config.onSuccess) { 91 | config.onSuccess(registration) 92 | } 93 | } 94 | } 95 | } 96 | } 97 | }) 98 | .catch((error) => { 99 | console.error('Error during service worker registration:', error) 100 | }) 101 | } 102 | 103 | function checkValidServiceWorker(swUrl, config) { 104 | // Check if the service worker can be found. If it can't reload the page. 105 | fetch(swUrl, { 106 | headers: {'Service-Worker': 'script'}, 107 | }) 108 | .then((response) => { 109 | // Ensure service worker exists, and that we really are getting a JS file. 110 | const contentType = response.headers.get('content-type') 111 | if ( 112 | response.status === 404 || 113 | (contentType != null && contentType.indexOf('javascript') === -1) 114 | ) { 115 | // No service worker found. Probably a different app. Reload the page. 116 | navigator.serviceWorker.ready.then((registration) => { 117 | registration.unregister().then(() => { 118 | window.location.reload() 119 | }) 120 | }) 121 | } else { 122 | // Service worker found. Proceed as normal. 123 | registerValidSW(swUrl, config) 124 | } 125 | }) 126 | .catch(() => { 127 | console.log( 128 | 'No internet connection found. App is running in offline mode.' 129 | ) 130 | }) 131 | } 132 | 133 | export function unregister() { 134 | if ('serviceWorker' in navigator) { 135 | navigator.serviceWorker.ready 136 | .then((registration) => { 137 | registration.unregister() 138 | }) 139 | .catch((error) => { 140 | console.error(error.message) 141 | }) 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect' 6 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "public": false, 4 | "redirects": [ 5 | { 6 | "source": "/redCheck", 7 | "destination": "https://github.com/pranjaljain0" 8 | } 9 | ], 10 | "github": { 11 | "enabled": false 12 | }, 13 | "headers": [ 14 | { 15 | "source": "/(.*)", 16 | "headers": [ 17 | { 18 | "key": "Cache-Control", 19 | "value": "public, max-age=31556952, immutable" 20 | } 21 | ] 22 | } 23 | ] 24 | } 25 | --------------------------------------------------------------------------------