├── src
├── content
│ ├── content.d.ts
│ ├── landing
│ │ ├── landing-config.json
│ │ └── landing.md
│ ├── about
│ │ ├── about.md
│ │ └── about-config.json
│ ├── common
│ │ └── common.json
│ ├── featured-projects
│ │ └── featured-projects-config.json
│ └── other-projects
│ │ └── other-projects-config.json
├── react-app-env.d.ts
├── theme
│ ├── fonts
│ │ ├── logo-type
│ │ │ └── Monsieur-Pomme.ttf
│ │ └── _font.scss
│ ├── colors
│ │ └── Colors.ts
│ ├── index.ts
│ └── component-styles
│ │ └── ComponentStyles.ts
├── utils
│ ├── assets
│ │ ├── cursor.svg
│ │ └── pointer.svg
│ ├── Functions.ts
│ ├── Icons.tsx
│ └── useScroll.ts
├── setupTests.ts
├── App.scss
├── shared
│ ├── date
│ │ └── Date.tsx
│ ├── navbar
│ │ ├── logo-type
│ │ │ └── LogoType.tsx
│ │ ├── Navbar.tsx
│ │ └── drawer
│ │ │ └── Drawer.tsx
│ ├── page-header
│ │ └── PageHeader.tsx
│ ├── color-mode-button
│ │ └── ColorModeButton.tsx
│ ├── tags
│ │ └── Tags.tsx
│ ├── footer
│ │ └── Footer.tsx
│ ├── socials
│ │ └── Socials.tsx
│ ├── project-card-footer
│ │ └── ProjectCardFooter.tsx
│ └── content
│ │ └── Content.tsx
├── reportWebVitals.ts
├── index.scss
├── pages
│ ├── about
│ │ ├── common
│ │ │ ├── title
│ │ │ │ └── Title.tsx
│ │ │ └── expandable
│ │ │ │ └── Expandable.tsx
│ │ ├── blog
│ │ │ └── Blog.tsx
│ │ ├── skills
│ │ │ └── Skills.tsx
│ │ ├── experience
│ │ │ └── Experience.tsx
│ │ ├── education
│ │ │ └── Education.tsx
│ │ └── About.tsx
│ ├── featured-projects
│ │ ├── FeaturedProjects.tsx
│ │ └── featured-project-card
│ │ │ └── FeaturedProjectCard.tsx
│ ├── other-projects
│ │ ├── other-project-card
│ │ │ └── OtherProjectCard.tsx
│ │ └── OtherProjects.tsx
│ └── landing
│ │ └── Landing.tsx
├── index.tsx
└── App.tsx
├── public
├── robots.txt
├── logo.png
├── favicon.ico
├── assets
│ ├── HP.jpeg
│ ├── HP.webp
│ ├── name-pro.mp3
│ ├── landing
│ │ ├── face.jpeg
│ │ └── face.webp
│ ├── readme
│ │ └── banner.png
│ ├── other-projects
│ │ ├── bank.jpeg
│ │ ├── bank.webp
│ │ ├── noq.jpeg
│ │ ├── noq.webp
│ │ ├── post.jpeg
│ │ ├── post.webp
│ │ ├── bunder.jpeg
│ │ ├── bunder.webp
│ │ ├── nutricare.jpeg
│ │ ├── nutricare.webp
│ │ ├── suicide-analyzer.jpeg
│ │ └── suicide-analyzer.webp
│ └── featured-projects
│ │ ├── asctb.jpeg
│ │ ├── asctb.webp
│ │ ├── trackcta.jpeg
│ │ ├── trackcta.webp
│ │ ├── measure-ux.jpeg
│ │ ├── measure-ux.webp
│ │ ├── scrapbook.jpeg
│ │ └── scrapbook.webp
├── manifest.json
├── 404.html
└── index.html
├── .prettierrc
├── .gitignore
├── tsconfig.json
├── .github
└── workflows
│ ├── firebase-hosting-prod.yml
│ └── firebase-hosting-demo.yml
├── LICENSE
├── package.json
└── README.md
/src/content/content.d.ts:
--------------------------------------------------------------------------------
1 | declare module "*.md";
2 |
--------------------------------------------------------------------------------
/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/logo.png
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/public/assets/HP.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/HP.jpeg
--------------------------------------------------------------------------------
/public/assets/HP.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/HP.webp
--------------------------------------------------------------------------------
/public/assets/name-pro.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/name-pro.mp3
--------------------------------------------------------------------------------
/public/assets/landing/face.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/landing/face.jpeg
--------------------------------------------------------------------------------
/public/assets/landing/face.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/landing/face.webp
--------------------------------------------------------------------------------
/public/assets/readme/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/readme/banner.png
--------------------------------------------------------------------------------
/public/assets/other-projects/bank.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/other-projects/bank.jpeg
--------------------------------------------------------------------------------
/public/assets/other-projects/bank.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/other-projects/bank.webp
--------------------------------------------------------------------------------
/public/assets/other-projects/noq.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/other-projects/noq.jpeg
--------------------------------------------------------------------------------
/public/assets/other-projects/noq.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/other-projects/noq.webp
--------------------------------------------------------------------------------
/public/assets/other-projects/post.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/other-projects/post.jpeg
--------------------------------------------------------------------------------
/public/assets/other-projects/post.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/other-projects/post.webp
--------------------------------------------------------------------------------
/public/assets/other-projects/bunder.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/other-projects/bunder.jpeg
--------------------------------------------------------------------------------
/public/assets/other-projects/bunder.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/other-projects/bunder.webp
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 120,
3 | "semi": true,
4 | "singleQuote": false,
5 | "tabWidth": 4,
6 | "trailingComma": "all"
7 | }
8 |
--------------------------------------------------------------------------------
/public/assets/featured-projects/asctb.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/featured-projects/asctb.jpeg
--------------------------------------------------------------------------------
/public/assets/featured-projects/asctb.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/featured-projects/asctb.webp
--------------------------------------------------------------------------------
/public/assets/other-projects/nutricare.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/other-projects/nutricare.jpeg
--------------------------------------------------------------------------------
/public/assets/other-projects/nutricare.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/other-projects/nutricare.webp
--------------------------------------------------------------------------------
/public/assets/featured-projects/trackcta.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/featured-projects/trackcta.jpeg
--------------------------------------------------------------------------------
/public/assets/featured-projects/trackcta.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/featured-projects/trackcta.webp
--------------------------------------------------------------------------------
/src/theme/fonts/logo-type/Monsieur-Pomme.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/src/theme/fonts/logo-type/Monsieur-Pomme.ttf
--------------------------------------------------------------------------------
/public/assets/featured-projects/measure-ux.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/featured-projects/measure-ux.jpeg
--------------------------------------------------------------------------------
/public/assets/featured-projects/measure-ux.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/featured-projects/measure-ux.webp
--------------------------------------------------------------------------------
/public/assets/featured-projects/scrapbook.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/featured-projects/scrapbook.jpeg
--------------------------------------------------------------------------------
/public/assets/featured-projects/scrapbook.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/featured-projects/scrapbook.webp
--------------------------------------------------------------------------------
/public/assets/other-projects/suicide-analyzer.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/other-projects/suicide-analyzer.jpeg
--------------------------------------------------------------------------------
/public/assets/other-projects/suicide-analyzer.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hrishikeshpaul/portfolio-template-v2/HEAD/public/assets/other-projects/suicide-analyzer.webp
--------------------------------------------------------------------------------
/src/content/landing/landing-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "headline": "Hello, I'm Hrishikesh Paul.",
3 | "picture": "/assets/landing/face.webp",
4 | "jpg": "/assets/landing/face.jpeg"
5 | }
6 |
--------------------------------------------------------------------------------
/src/utils/assets/cursor.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/utils/assets/pointer.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/src/App.scss:
--------------------------------------------------------------------------------
1 | ::-webkit-scrollbar {
2 | width: 5px;
3 | height: 3px;
4 | }
5 | ::-webkit-scrollbar-thumb {
6 | background: gray;
7 | border-radius: 3px;
8 | }
9 |
10 | ::-webkit-scrollbar-track {
11 | background: transparent;
12 | border-radius: 0px;
13 | box-shadow: inset 0px 0px 0px 0px #f0f0f0;
14 | }
15 |
--------------------------------------------------------------------------------
/src/utils/Functions.ts:
--------------------------------------------------------------------------------
1 | import { configs } from "shared/content/Content";
2 |
3 | export const open = (link: string) => window.open(link, "_blank");
4 |
5 | export const onResumeOpen = () => {
6 | open(configs.common.resume);
7 | };
8 |
9 | export const onMailTo = () => {
10 | open("mailto:" + configs.common.email);
11 | };
12 |
--------------------------------------------------------------------------------
/src/shared/date/Date.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Text } from "@chakra-ui/react";
4 |
5 | interface Props {
6 | year: string;
7 | }
8 |
9 | export const Date: FC = ({ year }) => {
10 | return (
11 |
12 | {year}
13 |
14 | );
15 | };
16 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "HP",
3 | "name": "Portfolio • Hrishikesh Paul",
4 | "icons": [
5 | {
6 | "src": "logo.png",
7 | "type": "image/png",
8 | "sizes": "512x512"
9 | }
10 | ],
11 | "start_url": ".",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
25 | firebase.json
26 | .firebaserc
--------------------------------------------------------------------------------
/src/content/landing/landing.md:
--------------------------------------------------------------------------------
1 | Welcome 👋 I'm a _Frontend Software Engineer_ at [Reputation](https://reputation.com/) based out of Chicago, Illinois. I recently graduated from Indiana University with a Masters degree in Computer Science and I'm passionate about **Software Development**, **UX Design** and **Artificial Intelligence**.
2 |
3 | I'm currently working with,
4 |
5 | - React (TS)
6 | - NodeJS
7 | - Flask (Python)
8 | - HTML/SCSS
9 | - WebSockets
10 | - GraphQL
11 |
--------------------------------------------------------------------------------
/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals';
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/src/theme/fonts/_font.scss:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Urbanist:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap");
2 | @import url("https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700;800&display=swap");
3 |
4 | @font-face {
5 | font-family: "Signature";
6 | src: local("Signature"), url(./logo-type/Monsieur-Pomme.ttf) format("truetype");
7 | font-display: fallback;
8 | }
9 |
--------------------------------------------------------------------------------
/src/utils/Icons.tsx:
--------------------------------------------------------------------------------
1 | export { BiLink as LinkIcon } from "react-icons/bi";
2 | export {
3 | FaLinkedin as LinkedInIcon,
4 | FaGithub as GitHubIcon,
5 | FaFacebookSquare as FacebookIcon,
6 | FaInstagramSquare as InstagramIcon,
7 | FaYoutubeSquare as YoutubeIcon,
8 | FaVolumeUp as VolumeIcon,
9 | FaHamburger as MenuIcon,
10 | } from "react-icons/fa";
11 | export { FiChevronDown as ChevronDownIcon, FiChevronUp as ChevronUpIcon } from "react-icons/fi";
12 | export { HiArrowSmRight as ArrowRightIcon, HiMail as MailIcon } from "react-icons/hi";
13 | export { IoMoon as MoonIcon, IoSunny as SunIcon } from "react-icons/io5";
14 |
--------------------------------------------------------------------------------
/src/index.scss:
--------------------------------------------------------------------------------
1 | @import "src/theme/fonts/font.scss";
2 |
3 | * {
4 | box-sizing: border-box;
5 | }
6 |
7 | html,
8 | body,
9 | #root {
10 | height: 100%;
11 | cursor: url(./utils/assets/cursor.svg) 20 20, auto !important;
12 |
13 | *::selection {
14 | background: var(--hp-colors-orange-200);
15 | transition: all 0.25s ease-in-out !important;
16 | }
17 | }
18 |
19 | .autograph__path {
20 | opacity: 0;
21 | animation-timing-function: linear;
22 | animation-fill-mode: forwards;
23 |
24 | .animated & {
25 | opacity: 1;
26 | animation-name: line;
27 | }
28 | }
29 |
30 | @keyframes line {
31 | 100% {
32 | stroke-dashoffset: 0;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/pages/about/common/title/Title.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Heading, StyleProps, Text } from "@chakra-ui/react";
4 |
5 | interface Props extends StyleProps {
6 | title: string;
7 | }
8 |
9 | export const ArticleTitle: FC = ({ title, ...props }) => {
10 | return (
11 |
12 | {title}
13 |
14 | );
15 | };
16 |
17 | export const SectionTitle: FC = ({ title, ...props }) => {
18 | return (
19 |
20 | {title}
21 |
22 | );
23 | };
24 |
--------------------------------------------------------------------------------
/src/pages/about/blog/Blog.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Box, Link } from "@chakra-ui/react";
4 |
5 | import { ArticleTitle } from "pages/about/common/title/Title";
6 | import { configs } from "shared/content/Content";
7 |
8 | export const Blog: FC = () => {
9 | return (
10 | <>
11 |
12 |
13 | {configs.about.blog.map((item) => (
14 |
15 |
16 | {item.title}
17 |
18 |
19 | ))}
20 | >
21 | );
22 | };
23 |
--------------------------------------------------------------------------------
/src/shared/navbar/logo-type/LogoType.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Box, Text, useBreakpointValue } from "@chakra-ui/react";
4 |
5 | interface Props {
6 | text: {
7 | mobile: string;
8 | desktop: string;
9 | };
10 | }
11 |
12 | export const LogoType: FC = ({ text }) => {
13 | const variant = useBreakpointValue({ base: text.mobile, md: text.desktop });
14 |
15 | return (
16 |
17 |
18 | {variant}
19 |
20 |
21 | );
22 | };
23 |
--------------------------------------------------------------------------------
/src/theme/colors/Colors.ts:
--------------------------------------------------------------------------------
1 | import { ColorHues } from "@chakra-ui/react";
2 |
3 | /**
4 | * Generated via https://lyft-colorbox.herokuapp.com/
5 | */
6 | export const PrimaryColors: ColorHues = {
7 | 50: "#FF9597",
8 | 100: "#FD6568",
9 | 200: "#F9383B",
10 | 300: "#F21115",
11 | 400: "#E90004",
12 | 500: "#DD0004",
13 | 600: "#CD0003",
14 | 700: "#B80003",
15 | 800: "#A00003",
16 | 900: "#870002",
17 | };
18 |
19 | export const PrimaryDarkColors: ColorHues = {
20 | 50: "#F5F5F5",
21 | 100: "#F0EEEE",
22 | 200: "#ECE7E7",
23 | 300: "#D5CCCD",
24 | 400: "#706868",
25 | 500: "#807777",
26 | 600: "#50494A",
27 | 700: "#2A2727",
28 | 800: "#131212",
29 | 900: "#0A0909",
30 | };
31 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "esModuleInterop": true,
8 | "allowSyntheticDefaultImports": true,
9 | "strict": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "noFallthroughCasesInSwitch": true,
12 | "module": "esnext",
13 | "moduleResolution": "node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx",
18 | "baseUrl": "src",
19 | "typeRoots": ["src/content/content.d.ts", "./node_modules/@types"]
20 | },
21 | "include": ["src"]
22 | }
23 |
--------------------------------------------------------------------------------
/src/pages/about/skills/Skills.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Box } from "@chakra-ui/react";
4 |
5 | import { configs } from "shared/content/Content";
6 | import { Tags } from "shared/tags/Tags";
7 | import { ArticleTitle, SectionTitle } from "../common/title/Title";
8 |
9 | export const Skills: FC = () => {
10 | return (
11 | <>
12 |
13 |
14 |
15 | {configs.about.skills.map((skill) => (
16 |
17 |
18 |
19 |
20 | ))}
21 | >
22 | );
23 | };
24 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 |
4 | import { ChakraProvider, ColorModeScript } from "@chakra-ui/react";
5 |
6 | import { theme } from "theme";
7 | import reportWebVitals from "./reportWebVitals";
8 | import { App } from "./App";
9 |
10 | import "./index.scss";
11 |
12 | ReactDOM.render(
13 |
14 |
15 |
16 |
17 |
18 | ,
19 | document.getElementById("root"),
20 | );
21 |
22 | // If you want to start measuring performance in your app, pass a function
23 | // to log results (for example: reportWebVitals(console.log))
24 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
25 | reportWebVitals();
26 |
--------------------------------------------------------------------------------
/src/content/about/about.md:
--------------------------------------------------------------------------------
1 | Hi there ✌️ nice to meet you! I'm a _Frontend Software Engineer_ at [Reputation](https://reputation.com/) based out of Chicago, Illinois.
2 |
3 | I'm an aspiring Software Engineer with a passion for writing code and making things on the web look pretty. I'm well acquainted with various *UX design* & *research methods* as well as *frontend*, *backend*, *database* and *cloud technologies*. I have always been a firm believer in the human element of design and knowing your audience. Therefore, I strive to create simple, functional and impactful user experiences. I primarily code in **Python** and **Typescript**, and use **Adobe XD** and **Illustrator** for designing.
4 |
5 | In my free time, I love to play volleyball, watch football ⚽, cook, play the guitar, explore neighborhoods through food and occasionally bring out my inner photographer. Also, did someone say sushi? 🍣
6 |
--------------------------------------------------------------------------------
/src/theme/index.ts:
--------------------------------------------------------------------------------
1 | import { ThemeConfig, extendTheme, withDefaultColorScheme } from "@chakra-ui/react";
2 |
3 | import { PrimaryColors, PrimaryDarkColors } from "theme/colors/Colors";
4 | import { components } from "theme/component-styles/ComponentStyles";
5 |
6 | const config: ThemeConfig = {
7 | cssVarPrefix: "hp",
8 | };
9 |
10 | const fonts = {
11 | body: "'Urbanist', sans-serif",
12 | heading: "'Playfair Display', serif;",
13 | };
14 |
15 | const colors = {
16 | primary: {
17 | ...PrimaryColors,
18 | },
19 | gray: {
20 | ...PrimaryDarkColors,
21 | },
22 | };
23 |
24 | export const bgLight = "white";
25 | export const bgDark = "gray.800";
26 | export const NavbarHeight = "144px";
27 |
28 | export const theme = extendTheme(
29 | {
30 | config,
31 | colors,
32 | fonts,
33 | components,
34 | },
35 | withDefaultColorScheme({ colorScheme: "primary" }),
36 | );
37 |
--------------------------------------------------------------------------------
/src/pages/featured-projects/FeaturedProjects.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Box } from "@chakra-ui/react";
4 |
5 | import { FeaturedProjectCard, ImagePosition } from "pages/featured-projects/featured-project-card/FeaturedProjectCard";
6 | import { configs } from "shared/content/Content";
7 |
8 | export const FeaturedProjects: FC = () => {
9 | return (
10 |
16 | {configs.featuredProjects.map((project, idx) => (
17 |
22 | ))}
23 |
24 | );
25 | };
26 |
--------------------------------------------------------------------------------
/src/shared/page-header/PageHeader.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Box, Text } from "@chakra-ui/react";
4 |
5 | interface Props {
6 | id?: string;
7 | label: string;
8 | }
9 | export const PageHeader: FC = ({ id, label }) => {
10 | const borderColor = "gray.500";
11 |
12 | return (
13 |
30 |
31 | {label}
32 |
33 |
34 | );
35 | };
36 |
--------------------------------------------------------------------------------
/src/content/common/common.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Hrishikesh Paul",
3 | "logoType": {
4 | "mobile": "HP",
5 | "desktop": "Hrishikesh Paul"
6 | },
7 | "mainPicture": "/assets/HP.webp",
8 | "mainPictureJPG": "/assets/HP.jpeg",
9 | "pronunciation": "/ri-shi-kaysh/",
10 | "audioFile": "/assets/name-pro.mp3",
11 | "cssVarPrefix": "hp",
12 | "email": "hrishikeshpaul12@gmail.com",
13 | "linkedin": "https://www.linkedin.com/in/hrishikeshpaul/",
14 | "github": "https://github.com/hrishikeshpaul",
15 | "resume": "https://docs.google.com/viewer?url=https://docs.google.com/document/d/1s3G7PiPHlK3Ett_W-WUU01GQnsggiLrWZB3IiMAgBEk/export?format=pdf",
16 | "socials": [
17 | {
18 | "type": "linkedin",
19 | "link": "https://www.linkedin.com/in/hrishikeshpaul/"
20 | },
21 | {
22 | "type": "github",
23 | "link": "https://github.com/hrishikeshpaul"
24 | },
25 | {
26 | "type": "mail",
27 | "link": "mailto:hrishikeshpaul12@gmail.com"
28 | }
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/.github/workflows/firebase-hosting-prod.yml:
--------------------------------------------------------------------------------
1 | name: Deploy to Firebase Hosting on Prod
2 | 'on':
3 | push:
4 | branches:
5 | - main
6 | jobs:
7 | build_and_deploy:
8 | if: ${{ github.repository }} == secrets.REPO_NAME
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v2
12 |
13 | - name: Use Node.js ${{ matrix.node-version }}
14 | uses: actions/setup-node@v1
15 | with:
16 | node-version: ${{ matrix.node-version }}
17 |
18 | - name: Install dependencies
19 | run: yarn install
20 |
21 | - name: Build app
22 | run: yarn build
23 |
24 | - name: Create firebase.json and .firebaserc
25 | run: |
26 | echo ${{ secrets.FIREBASE_JSON }} | base64 -d >> firebase.json
27 | echo ${{ secrets.FIREBASERC }} | base64 -d >> .firebaserc
28 |
29 | - name: Deploy to Firebase Hosting
30 | run: |
31 | npm install -g firebase-tools
32 | firebase deploy --only hosting:prod --project=${{ secrets.FIREBASE_PROJECT_NAME }} --token=${{ secrets.FIREBASE_TOKEN }} --non-interactive
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Hrishikesh Paul
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.
--------------------------------------------------------------------------------
/.github/workflows/firebase-hosting-demo.yml:
--------------------------------------------------------------------------------
1 | name: Deploy to Firebase Hosting to Demo
2 | 'on':
3 | push:
4 | branches:
5 | - main
6 | jobs:
7 | build_and_deploy:
8 | if: ${{ github.repository }} == 'hrishikeshpaul/portfolio-template-v2'
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v2
12 |
13 | - name: Use Node.js ${{ matrix.node-version }}
14 | uses: actions/setup-node@v1
15 | with:
16 | node-version: ${{ matrix.node-version }}
17 |
18 | - name: Install dependencies
19 | run: yarn install
20 |
21 | - name: Build app
22 | run: yarn build
23 |
24 | - name: Create firebase.json and .firebaserc
25 | run: |
26 | echo ${{ secrets.FIREBASE_JSON }} | base64 -d >> firebase.json
27 | echo ${{ secrets.FIREBASERC }} | base64 -d >> .firebaserc
28 |
29 | - name: Deploy to Firebase Hosting
30 | run: |
31 | npm install -g firebase-tools
32 | firebase deploy --only hosting:demo --project=${{ secrets.FIREBASE_PROJECT_NAME }} --token=${{ secrets.FIREBASE_TOKEN }} --non-interactive
33 |
--------------------------------------------------------------------------------
/src/shared/color-mode-button/ColorModeButton.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { HStack, IconButton, StyleProps, useColorMode, useColorModeValue } from "@chakra-ui/react";
4 |
5 | import { MoonIcon, SunIcon } from "utils/Icons";
6 |
7 | export const ColorModeButton: FC = (props) => {
8 | const color = useColorModeValue("gray.800", "white");
9 | const { colorMode, toggleColorMode } = useColorMode();
10 |
11 | return (
12 |
13 | : }
21 | variant="ghost"
22 | size="xs"
23 | onClick={() => {
24 | toggleColorMode();
25 | window.scrollBy(0, 1);
26 | window.scrollBy(0, -1);
27 | }}
28 | w="32px"
29 | h="32px"
30 | />
31 |
32 | );
33 | };
34 |
--------------------------------------------------------------------------------
/src/shared/tags/Tags.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Flex, Box, Badge } from "@chakra-ui/react";
4 |
5 | interface Props {
6 | id: string;
7 | tags: Array;
8 | size?: string;
9 | delay?: number;
10 | }
11 |
12 | export const Tags: FC = ({ id, tags, size = "sm" }) => {
13 | return (
14 |
15 | {tags.map((tag, idx) => (
16 |
17 |
29 | {tag}
30 |
31 |
32 | ))}
33 |
34 | );
35 | };
36 |
--------------------------------------------------------------------------------
/src/utils/useScroll.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 |
3 | export const WorkPageId = "page-work";
4 | export const AboutPageId = "page-about";
5 |
6 | export enum Page {
7 | Work = "work",
8 | About = "about",
9 | }
10 |
11 | const pageIds = [WorkPageId, AboutPageId];
12 |
13 | export const useScroll = () => {
14 | const [page, setPage] = useState("");
15 |
16 | const scrollHandler = () => {
17 | const documentTop = document.scrollingElement?.scrollTop!;
18 | const pages = pageIds.map((page) => document.getElementById(page));
19 | let newPage = "";
20 |
21 | pages.forEach((page) => {
22 | if (page) {
23 | const top = page.offsetTop;
24 | const height = page.clientHeight;
25 |
26 | if (top < documentTop && top + height > documentTop) {
27 | newPage = page.id;
28 | }
29 | }
30 | });
31 |
32 | setPage(newPage);
33 | };
34 |
35 | useEffect(() => {
36 | setTimeout(() => {
37 | scrollHandler();
38 | }, 100);
39 |
40 | document.addEventListener("scroll", scrollHandler);
41 |
42 | return () => {
43 | document.removeEventListener("scroll", () => {});
44 | };
45 | }, []);
46 |
47 | return page;
48 | };
49 |
--------------------------------------------------------------------------------
/src/pages/about/experience/Experience.tsx:
--------------------------------------------------------------------------------
1 | import { FC, useState } from "react";
2 |
3 | import { Accordion, AccordionItem } from "@chakra-ui/react";
4 |
5 | import { configs } from "shared/content/Content";
6 | import { Expandable } from "pages/about/common/expandable/Expandable";
7 | import { ArticleTitle } from "pages/about/common/title/Title";
8 |
9 | export const Experience: FC = () => {
10 | const [experiencesExpanded, setExperiencesExpanded] = useState([]);
11 |
12 | return (
13 | <>
14 |
15 |
16 |
17 | {configs.about.experiences.map((exp, idx) => (
18 |
19 |
29 |
30 | ))}
31 |
32 | >
33 | );
34 | };
35 |
--------------------------------------------------------------------------------
/src/pages/about/education/Education.tsx:
--------------------------------------------------------------------------------
1 | import { FC, useState } from "react";
2 |
3 | import { Accordion, AccordionItem } from "@chakra-ui/react";
4 | import { configs } from "shared/content/Content";
5 | import { Expandable } from "pages/about/common/expandable/Expandable";
6 | import { ArticleTitle } from "pages/about/common/title/Title";
7 |
8 | export const Education: FC = () => {
9 | const [educationExpanded, setEducationExpanded] = useState([]);
10 |
11 | return (
12 | <>
13 |
14 |
15 |
16 |
17 |
18 | {configs.about.educations.map((edu, idx) => (
19 |
20 |
30 |
31 | ))}
32 |
33 | >
34 | );
35 | };
36 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "portfolio-3",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@chakra-ui/react": "^1.8.3",
7 | "@emotion/react": "^11",
8 | "@emotion/styled": "^11",
9 | "@testing-library/jest-dom": "^5.16.2",
10 | "@testing-library/react": "^12.1.2",
11 | "@testing-library/user-event": "^13.5.0",
12 | "aos": "^2.3.4",
13 | "framer-motion": "^5",
14 | "json-loader": "^0.5.7",
15 | "react": "^17.0.2",
16 | "react-dom": "^17.0.2",
17 | "react-icons": "^4.3.1",
18 | "react-markdown": "^8.0.0",
19 | "react-scripts": "5.0.0",
20 | "sass": "^1.49.7",
21 | "typescript": "^4.5.5",
22 | "web-vitals": "^2.1.4"
23 | },
24 | "devDependencies": {
25 | "@types/aos": "^3.0.4",
26 | "@types/jest": "^27.4.0",
27 | "@types/node": "^16.11.22",
28 | "@types/react": "^17.0.39",
29 | "@types/react-dom": "^17.0.11"
30 | },
31 | "scripts": {
32 | "start": "react-scripts start",
33 | "build": "react-scripts build",
34 | "test": "react-scripts test",
35 | "eject": "react-scripts eject",
36 | "deploy": "git push prod main"
37 | },
38 | "eslintConfig": {
39 | "extends": [
40 | "react-app",
41 | "react-app/jest"
42 | ]
43 | },
44 | "browserslist": {
45 | "production": [
46 | ">0.2%",
47 | "not dead",
48 | "not op_mini all"
49 | ],
50 | "development": [
51 | "last 1 chrome version",
52 | "last 1 firefox version",
53 | "last 1 safari version"
54 | ]
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/shared/footer/Footer.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Box, Heading, Flex, Text } from "@chakra-ui/react";
4 |
5 | import { configs } from "shared/content/Content";
6 | import { PageHeader } from "shared/page-header/PageHeader";
7 | import { onMailTo } from "utils/Functions";
8 | import { Socials } from "shared/socials/Socials";
9 |
10 | const headerStyles = {
11 | cursor: "pointer",
12 | transition: "color 0.2s ease-in-out",
13 | isTruncated: true,
14 | fontSize: { base: "2xl", md: "3xl" },
15 | _hover: { color: "primary.500" },
16 | _active: { color: "primary.500" },
17 | };
18 |
19 | export const Footer: FC = () => {
20 | return (
21 | <>
22 |
23 |
24 |
25 | {configs.common.email}
26 |
27 |
28 |
29 | If you want to know more about my experiences and journey, or just talk in general, get in touch! ✌️
30 |
31 |
32 |
33 |
34 |
42 | This site is hand-crafted, with care by me.
43 | © {new Date().getFullYear()} All rights reserved.
44 |
45 | >
46 | );
47 | };
48 |
--------------------------------------------------------------------------------
/public/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Hrishikesh Paul
6 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/pages/other-projects/other-project-card/OtherProjectCard.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Image, Box, Flex, Heading, Text } from "@chakra-ui/react";
4 |
5 | import { Tags } from "shared/tags/Tags";
6 | import { ProjectCardFooter } from "shared/project-card-footer/ProjectCardFooter";
7 |
8 | interface Props {
9 | id: string;
10 | title: string;
11 | demo?: string;
12 | github?: string;
13 | tags: string[];
14 | description: string;
15 | readMore?: string;
16 | image: string;
17 | jpg: string;
18 | }
19 |
20 | export const OtherProjectCard: FC = ({ id, title, demo, github, tags, description, readMore, image, jpg }) => {
21 | return (
22 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | {title}
39 |
40 |
41 | {description}
42 |
43 |
44 |
45 |
46 |
47 |
48 | );
49 | };
50 |
--------------------------------------------------------------------------------
/src/pages/other-projects/OtherProjects.tsx:
--------------------------------------------------------------------------------
1 | import { FC, useState } from "react";
2 |
3 | import { Box, Button, Flex } from "@chakra-ui/react";
4 | import { configs } from "shared/content/Content";
5 | import { OtherProjectCard } from "pages/other-projects/other-project-card/OtherProjectCard";
6 | import { ChevronDownIcon, ChevronUpIcon } from "utils/Icons";
7 |
8 | const initialCount = 3;
9 | const incrementor = 3;
10 |
11 | export const OtherProjects: FC = () => {
12 | const [count, setCount] = useState(initialCount);
13 |
14 | const scrollToElement = (idx: number) => {
15 | const elementTop = document
16 | .getElementById(`other-project-card-${configs.otherProjects[idx].id}`)
17 | ?.getBoundingClientRect().top;
18 |
19 | if (elementTop) {
20 | window.scrollTo({ top: elementTop + window.scrollY - 64, behavior: "smooth" });
21 | }
22 | };
23 |
24 | const onShowMore = () => {
25 | const oldCount = count;
26 | setCount(count + incrementor);
27 | setTimeout(() => {
28 | scrollToElement(oldCount);
29 | }, 1);
30 | };
31 |
32 | const onShowLess = () => {
33 | setCount(initialCount);
34 | scrollToElement(initialCount);
35 | };
36 |
37 | return (
38 |
39 | {configs.otherProjects.map((project, idx) => (
40 | {idx < count && }
41 | ))}
42 | 3 ? "flex" : "none"}>
43 | {count < configs.otherProjects.length ? (
44 | } variant="link" onClick={onShowMore}>
45 | Show More
46 |
47 | ) : (
48 | } variant="link" onClick={onShowLess}>
49 | Show Less
50 |
51 | )}
52 |
53 |
54 | );
55 | };
56 |
--------------------------------------------------------------------------------
/src/shared/socials/Socials.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Button, HStack, IconButton, Tooltip } from "@chakra-ui/react";
4 |
5 | import { configs } from "shared/content/Content";
6 | import { onResumeOpen, open } from "utils/Functions";
7 | import { FacebookIcon, GitHubIcon, InstagramIcon, LinkedInIcon, MailIcon, YoutubeIcon } from "utils/Icons";
8 |
9 | const LinksToIconMapper: Record = {
10 | linkedin: ,
11 | github: ,
12 | facebook: ,
13 | instagram: ,
14 | youtube: ,
15 | mail: ,
16 | };
17 |
18 | interface Props {
19 | resume?: boolean;
20 | exclude?: Array;
21 | delay?: number;
22 | }
23 |
24 | export const Socials: FC = ({ resume = true, exclude, delay = 800 }) => {
25 | return (
26 |
27 | {resume && (
28 |
31 | )}
32 | {configs.common.socials.map(
33 | (social, idx) =>
34 | !exclude?.includes(social.type) && (
35 |
36 |
48 | ),
49 | )}
50 |
51 | );
52 | };
53 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Portfolio Template 🖐
2 | > Version 2 of a simple, minimal and responsive personal website template, built using React, TypeScript, HTML and SCSS.
3 |
4 | 
5 |
6 | 💻 Live [demo](https://hpaul-v2.web.app/)
7 |
8 | ---
9 |
10 | ## Table of Contents
11 |
12 | - [Installation](#installation)
13 | - [Usage](#usage)
14 | - [Contributing](#contributing)
15 | - [Connect](#connect)
16 | - [License](#license)
17 |
18 | ---
19 |
20 | ## Installation
21 |
22 | ### Setup
23 |
24 | Close repository
25 |
26 | ```shell
27 | $ git clone https://github.com/hrishikeshpaul/portfolio-template-v2.git
28 | ```
29 |
30 | To install the node packages used in the project:
31 |
32 | ```shell
33 | $ cd portfolio-template-v2
34 | $ yarn install
35 | ```
36 |
37 | Compiles and hot-reloads for development
38 |
39 | ```shell
40 | $ yarn start
41 | ```
42 |
43 | Compiles and minifies for production
44 | ```shell
45 | $ yarn build
46 | ```
47 |
48 | ## Usage
49 |
50 | All the information can be edited in the JSONs and Markdowns in the [content folder](https://github.com/hrishikeshpaul/portfolio-template-v2/tree/main/src/content). Each section of the portfolio has its own folder. The `common.json` file contains details that are used throughout the website.
51 |
52 | All the images are in `public/assets`.
53 |
54 | ## Contributing
55 |
56 | - Clone this repo to your local machine.
57 | - Checkout to a new branch. Give it a relevant name!
58 | - Create a pull request
59 |
60 | ## Connect
61 |
62 | - Website at `https://hrishikeshpaul.github.io/`
63 | - LinkedIn at `hrishikeshpaul`
64 |
65 | ## License
66 |
67 | [](https://github.com/hrishikeshpaul/portfolio-template-v2/blob/master/LICENSE)
68 |
69 | - **[MIT license](http://opensource.org/licenses/mit-license.php)**
70 | - Copyright 2022 © Hrishikesh Paul
--------------------------------------------------------------------------------
/src/theme/component-styles/ComponentStyles.ts:
--------------------------------------------------------------------------------
1 | import { ComponentStyleConfig } from "@chakra-ui/react";
2 |
3 | const TextStyles: ComponentStyleConfig = {
4 | baseStyle: {
5 | fontWeight: 500,
6 | },
7 | };
8 |
9 | const ContainerStyles: ComponentStyleConfig = {
10 | baseStyle: {
11 | maxW: "container.xl",
12 | },
13 | };
14 |
15 | const ButtonStyles: ComponentStyleConfig = {
16 | baseStyle: {
17 | fontWeight: "bold",
18 | },
19 | variants: {
20 | solid: {
21 | color: "white",
22 | },
23 | secondary: (props: any) => {
24 | return {
25 | color: props.colorMode === "dark" ? "white" : "gray.900",
26 | backgroundColor: props.colorMode === "dark" ? "gray.700" : "gray.50",
27 | _hover: {
28 | backgroundColor: props.colorMode === "dark" ? "gray.600" : "gray.100",
29 | },
30 | _active: {
31 | backgroundColor: props.colorMode === "dark" ? "gray.600" : "gray.200",
32 | },
33 | };
34 | },
35 | icon: (props: any) => {
36 | return {
37 | color: props.colorMode === "dark" ? "white" : "gray.900",
38 | background: "transparent",
39 | _hover: {
40 | background: "transparent",
41 | color: "primary.500",
42 | },
43 | _focus: {
44 | background: "transparent",
45 | },
46 | _active: {
47 | background: "transparent",
48 | },
49 | };
50 | },
51 | },
52 | defaultProps: {
53 | variant: "solid",
54 | },
55 | };
56 |
57 | const LinkStyles: ComponentStyleConfig = {
58 | baseStyle: (props) => {
59 | let color = "primary.600";
60 |
61 | if (props.colorMode === "dark") color = "primary.100";
62 |
63 | return {
64 | fontWeight: 700,
65 | color,
66 | };
67 | },
68 | };
69 |
70 | export const components = {
71 | Text: { ...TextStyles },
72 | Container: { ...ContainerStyles },
73 | Link: { ...LinkStyles },
74 | Button: { ...ButtonStyles },
75 | };
76 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Portfolio • Hrishikesh Paul
8 |
9 |
13 |
14 |
15 |
16 |
17 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 | import { FC, useEffect, lazy, Suspense } from "react";
2 |
3 | import { Box, Container, Center, Spinner } from "@chakra-ui/react";
4 | import AOS from "aos";
5 |
6 | import { NavbarHeight } from "theme";
7 | import { AboutPageId, WorkPageId } from "utils/useScroll";
8 |
9 | import "./App.scss";
10 | import "aos/dist/aos.css";
11 |
12 | const Navbar = lazy(() => import("shared/navbar/Navbar").then((module) => ({ default: module.Navbar })));
13 | const Landing = lazy(() => import("pages/landing/Landing").then((module) => ({ default: module.Landing })));
14 | const PageHeader = lazy(() =>
15 | import("shared/page-header/PageHeader").then((module) => ({ default: module.PageHeader })),
16 | );
17 | const Footer = lazy(() => import("shared/footer/Footer").then((module) => ({ default: module.Footer })));
18 | const FeaturedProjects = lazy(() =>
19 | import("pages/featured-projects/FeaturedProjects").then((module) => ({
20 | default: module.FeaturedProjects,
21 | })),
22 | );
23 | const OtherProjects = lazy(() =>
24 | import("pages/other-projects/OtherProjects").then((module) => ({
25 | default: module.OtherProjects,
26 | })),
27 | );
28 | const About = lazy(() => import("pages/about/About").then((module) => ({ default: module.About })));
29 |
30 | const Loader: FC = () => (
31 |
32 |
33 |
34 | );
35 |
36 | export const App: FC = () => {
37 | useEffect(() => {
38 | AOS.init({ once: true });
39 | }, []);
40 |
41 | return (
42 | }>
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | );
65 | };
66 |
--------------------------------------------------------------------------------
/src/shared/project-card-footer/ProjectCardFooter.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Button, Flex, IconButton, useBreakpointValue } from "@chakra-ui/react";
4 |
5 | import { ArrowRightIcon, GitHubIcon, LinkIcon } from "utils/Icons";
6 | import { open } from "utils/Functions";
7 |
8 | interface GitHubButtonProps {
9 | github?: string;
10 | display?: any;
11 | }
12 |
13 | interface ReadMoreProps {
14 | readMore?: string;
15 | }
16 |
17 | interface LiveDemoProps {
18 | demo?: string;
19 | display?: any;
20 | }
21 |
22 | interface Props extends GitHubButtonProps, ReadMoreProps, LiveDemoProps {}
23 |
24 | export const ReadMore: FC = ({ readMore }) => {
25 | return readMore ? (
26 | }
32 | onClick={() => open(readMore)}
33 | >
34 | Read More
35 |
36 | ) : null;
37 | };
38 |
39 | export const GitHubButton: FC = ({ github, display }) => {
40 | const as = useBreakpointValue({ base: IconButton, lg: Button });
41 |
42 | return github ? (
43 | }
51 | icon={}
52 | onClick={() => open(github)}
53 | >
54 | GitHub
55 |
56 | ) : null;
57 | };
58 |
59 | export const LiveDemo: FC = ({ demo, display }) => {
60 | const as = useBreakpointValue({ base: IconButton, lg: Button });
61 |
62 | return demo ? (
63 | }
69 | icon={}
70 | onClick={() => open(demo)}
71 | >
72 | Live Demo
73 |
74 | ) : null;
75 | };
76 |
77 | export const ProjectCardFooter: FC = ({ readMore, github, demo }) => {
78 | return (
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | );
87 | };
88 |
--------------------------------------------------------------------------------
/src/pages/landing/Landing.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Center, Container, Heading, Image, HStack, Stack, Flex, Box, IconButton, Button } from "@chakra-ui/react";
4 |
5 | import { Content, configs, useContent, MarkdownFile } from "shared/content/Content";
6 | import { Socials } from "shared/socials/Socials";
7 | import { WorkPageId } from "utils/useScroll";
8 | import { ChevronDownIcon } from "utils/Icons";
9 |
10 | export const Landing: FC = () => {
11 | const content = useContent(MarkdownFile.Landing);
12 |
13 | const scrollIntoView = () => {
14 | const featuredHeader = document.getElementById(WorkPageId);
15 |
16 | if (featuredHeader) {
17 | featuredHeader.scrollIntoView({ behavior: "smooth" });
18 | }
19 | };
20 |
21 | return (
22 |
23 |
24 |
25 |
26 |
27 |
33 | {configs.landing.headline}
34 |
35 |
36 | {content.landing}
37 |
38 |
39 |
40 |
41 |
42 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | }
64 | onClick={scrollIntoView}
65 | >
66 |
67 |
68 | );
69 | };
70 |
--------------------------------------------------------------------------------
/src/shared/content/Content.tsx:
--------------------------------------------------------------------------------
1 | import { FC, useEffect, useState } from "react";
2 |
3 | import { Text, Stack, StyleProps, Link, UnorderedList } from "@chakra-ui/react";
4 | import ReactMarkdown from "react-markdown";
5 |
6 | import common from "content/common/common.json";
7 | import landing from "content/landing/landing-config.json";
8 | import featuredProjects from "content/featured-projects/featured-projects-config.json";
9 | import otherProjects from "content/other-projects/other-projects-config.json";
10 | import about from "content/about/about-config.json";
11 |
12 | import LandingMd from "content/landing/landing.md";
13 | import AboutMd from "content/about/about.md";
14 |
15 | export const configs = {
16 | common,
17 | landing,
18 | featuredProjects,
19 | otherProjects,
20 | about,
21 | };
22 |
23 | interface State {
24 | landing: string;
25 | about: string;
26 | }
27 |
28 | export enum MarkdownFile {
29 | Landing = "landing",
30 | About = "about",
31 | }
32 |
33 | const Mapper = {
34 | [MarkdownFile.Landing]: LandingMd,
35 | [MarkdownFile.About]: AboutMd,
36 | };
37 |
38 | export const useContent = (fileName: MarkdownFile) => {
39 | const [data, setData] = useState({ landing: "", about: "" });
40 |
41 | useEffect(() => {
42 | fetch(Mapper[fileName])
43 | .then((res) => res.text())
44 | .then((text) => setData((data) => ({ ...data, [fileName]: text })));
45 | }, [fileName]);
46 |
47 | return data;
48 | };
49 |
50 | interface Props extends StyleProps {
51 | children?: string;
52 | }
53 |
54 | export const Content: FC = ({ children, ...rest }) => {
55 | return (
56 |
57 | ,
60 | a: ({ node, ...props }) => (
61 |
62 | ),
63 | ul: ({ node, ...props }) => {
64 | const { ordered, ...rest } = props;
65 |
66 | return (
67 |
76 | );
77 | },
78 | li: ({ node, ...props }) => {
79 | const { ordered, ...rest } = props;
80 |
81 | return ;
82 | },
83 | }}
84 | >
85 | {children as string}
86 |
87 |
88 | );
89 | };
90 |
--------------------------------------------------------------------------------
/src/pages/about/About.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Box, Flex, Heading, Text, Image, Button, IconButton } from "@chakra-ui/react";
4 |
5 | import { configs, Content, MarkdownFile, useContent } from "shared/content/Content";
6 | import { Blog } from "pages/about/blog/Blog";
7 | import { Education } from "pages/about/education/Education";
8 | import { Experience } from "pages/about/experience/Experience";
9 | import { Skills } from "pages/about/skills/Skills";
10 | import { VolumeIcon } from "utils/Icons";
11 |
12 | export const About: FC = () => {
13 | const content = useContent(MarkdownFile.About);
14 |
15 | const onPlay = () => {
16 | const audio = new Audio(configs.common.audioFile);
17 | audio.play();
18 | };
19 |
20 | return (
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | {configs.common.name}
32 |
33 |
34 | {configs.common.pronunciation}
35 |
36 |
37 | }
44 | onClick={onPlay}
45 | data-aos="fade"
46 | data-aos-delay="400"
47 | />
48 |
49 |
50 | {content.about}
51 |
52 |
53 |
54 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | );
75 | };
76 |
--------------------------------------------------------------------------------
/src/content/featured-projects/featured-projects-config.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "featured-project-trackcta",
4 | "title": "trackCTA",
5 | "year": "Dec 2021 - Present",
6 | "location": "Chicago",
7 | "demo": "https://www.trackcta.com/",
8 | "github": "https://github.com/hrishikeshpaul/trackcta",
9 | "tags": ["React", "TypeScript", "NodeJS", "Web Sockets", "i18n", "Google Maps", "GCP", "CI/CD", "Shell"],
10 | "description": "An internationalized web app to track and predict Chicago Transit Authority (CTA) busses and trains.",
11 | "image": "/assets/featured-projects/trackcta.webp",
12 | "jpg": "/assets/featured-projects/trackcta.jpeg"
13 | },
14 | {
15 | "id": "featured-project-asctb-reporter",
16 | "title": "ASCT+B Reporter",
17 | "year": "Jun 2020 - Jun 2021",
18 | "location": "Indiana University",
19 | "demo": "https://hubmapconsortium.github.io/ccf-asct-reporter/",
20 | "github": "https://github.com/hrishikeshpaul/ccf-asct-reporter",
21 | "tags": ["Angular 11", "TypeScript", "NodeJS", "NGXS", "Vega", "TravisCI", "Open Source"],
22 | "description": "A collaboration with the NIH to build visualization tool to envision large biomedical datasets for researchers, doctors and experts.",
23 | "readMore": "https://hrishikeshpaul.medium.com/asct-b-reporter-a-visualization-tool-d4dd29de97d8",
24 | "image": "/assets/featured-projects/asctb.webp",
25 | "jpg": "/assets/featured-projects/asctb.jpeg"
26 | },
27 | {
28 | "id": "featured-project-scrapbook",
29 | "title": "Scrapbook",
30 | "year": "Jan 2021 - May 2021",
31 | "location": "Indiana University",
32 |
33 | "tags": [
34 | "Angular 11",
35 | "Flask",
36 | "Node",
37 | "Python",
38 | "TypeScript",
39 | "Docker",
40 | "Docker Hub",
41 | "Jenkins",
42 | "Kubernetes",
43 | "GKE",
44 | "GCP"
45 | ],
46 | "demo": "http://34.69.102.109/",
47 | "github": "https://github.com/hrishikeshpaul/scrapbook",
48 | "description": "A micro-service architecture based web application that enables users to upload, share and manage images.",
49 | "readMore": "https://hrishikeshpaul.medium.com/scrapbook-a-micro-service-based-photo-sharing-application-3a8760681af6",
50 | "image": "/assets/featured-projects/scrapbook.webp",
51 | "jpg": "/assets/featured-projects/scrapbook.jpeg"
52 | },
53 | {
54 | "id": "featured-project-measure-ux",
55 | "location": "Indiana University",
56 | "title": "Measuring User Experience",
57 | "year": "Sep 2020 - Dec 2020",
58 | "tags": ["UX Research", "User Journey", "Experience Mapping", "Surveys", "Interviews", "Adobe XD"],
59 | "description": "A project to quantify user experiences demonstrated by measuring the user experience of uploading a photo on Instagram.",
60 | "readMore": "https://hrishikeshpaul.medium.com/measuring-user-experience-an-instagram-case-study-89bfb78f2c6b",
61 | "image": "/assets/featured-projects/measure-ux.webp",
62 | "jpg": "/assets/featured-projects/measure-ux.jpeg"
63 | }
64 | ]
65 |
--------------------------------------------------------------------------------
/src/shared/navbar/Navbar.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Box, Button, Container, Flex, HStack, useColorModeValue } from "@chakra-ui/react";
4 |
5 | import { configs } from "shared/content/Content";
6 | import { LogoType } from "shared/navbar/logo-type/LogoType";
7 | import { bgDark, bgLight } from "theme";
8 | import { onResumeOpen } from "utils/Functions";
9 | import { AboutPageId, useScroll, WorkPageId } from "utils/useScroll";
10 | import { MenuDrawer } from "./drawer/Drawer";
11 | import { ColorModeButton } from "shared/color-mode-button/ColorModeButton";
12 |
13 | export const Navbar: FC = () => {
14 | const bg = useColorModeValue(bgLight, bgDark);
15 | const navItemColor = useColorModeValue("gray.800", "white");
16 | const currentPage = useScroll();
17 |
18 | const toSection = (section: string) => {
19 | document.getElementById(section)?.scrollIntoView({ behavior: "smooth" });
20 | };
21 |
22 | return (
23 |
24 |
25 |
26 |
27 |
28 |
29 |
41 |
53 |
56 |
57 |
58 |
59 |
60 |
65 |
66 |
67 |
68 | );
69 | };
70 |
--------------------------------------------------------------------------------
/src/content/other-projects/other-projects-config.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "other-project-post",
4 | "title": "Part of Speech Tagger",
5 | "year": "Aug 2019 - Dec 2019",
6 | "github": "https://github.com/hrishikeshpaul/post",
7 | "demo": "https://hrishikeshpaul.github.io/post/",
8 | "tags": ["Python", "Vue", "Flask", "Artificial Intelligence", "Language Processing"],
9 | "description": "Post is a simple algorithm that was developed to tag a word in a sentence corresponding to its part of speech. The algorithm makes of a probabilistic approach along with some randomness, together which forms the basis of an algorithm called Gibbs Sampling.",
10 | "image": "/assets/other-projects/post.webp",
11 | "jpg": "/assets/other-projects/post.jpeg"
12 |
13 | },
14 | {
15 | "id": "other-project-noq",
16 | "title": "NoQ Job Portal",
17 | "year": "Aug 2019 - Dec 2019",
18 | "github": "https://github.com/hrishikeshpaul/noq",
19 | "demo": "http://noq-client.herokuapp.com/login",
20 | "tags": ["Vue", "NodeJS", "JavaScript", "MongoDB", "Heroku", "Agile", "Sockets", "JIRA"],
21 | "description": "NoQ is a tool which allows for both employers and students to skip the hassle seen in modern day career fairs, while effectively pairing up students with employees based on various factors.",
22 | "readMore": "https://hrishikeshpaul.medium.com/noq-a-job-portal-for-college-career-fairs-9996bbb37a1c",
23 | "image": "/assets/other-projects/noq.webp",
24 | "jpg": "/assets/other-projects/noq.jpeg"
25 | },
26 | {
27 | "id": "other-project-bank-compare",
28 | "title": "Experience Design Anaysis",
29 | "year": "Aug 2019 - Dec 2019",
30 | "tags": ["UX Design", "Analysis", "Adobe XD", "Mockups"],
31 | "description": "This project demonstrates how the selection of colors, fonts, shapes, languages, layout and other styles can lead to drastically different user experiences, by comparing landing pages of 3 bank websites built from scratch.",
32 | "readMore": "https://drive.google.com/file/d/1GY2WmRZgvBgFx6OlAMcAj8_DQVmS5VBw/view",
33 | "image": "/assets/other-projects/bank.webp",
34 | "jpg": "/assets/other-projects/bank.jpeg"
35 | },
36 | {
37 | "id": "other-project-bunder",
38 | "title": "Bunder",
39 | "year": "Jan 2020 - Apr 2020",
40 | "tags": ["Surveying", "User Interviews", "Ideation", "Analysis", "Product Planning"],
41 | "description": "An MVP Proposal - Bunder is an intuitive web platform for micro-communities to share sensitive data with privacy within the community and allow engagement amongst them.",
42 | "readMore": "https://drive.google.com/file/d/1sj9wL7uEokNpk6VUu3nsiPHf3TZeu4lT/view?usp=sharing",
43 | "image": "/assets/other-projects/bunder.webp",
44 | "jpg": "/assets/other-projects/bunder.jpeg"
45 | },
46 | {
47 | "id": "other-project-suicide-analyzer",
48 | "title": "Suicide Analyzer",
49 | "tags": ["AngularJS", "JavaScript", "Express", "NodeJS", "Leaflet", "Heroku", "Python", "Pandas"],
50 | "description": "This is a web application, uses a map to demonstrate the number suicides committed around the globe, according to a dataset provided by the WHO.",
51 | "github": "https://github.com/hrishikeshpaul/whodata",
52 | "image": "/assets/other-projects/suicide-analyzer.webp",
53 | "jpg": "/assets/other-projects/suicide-analyzer.jpeg"
54 | },
55 | {
56 | "id": "other-project-nutricare",
57 | "title": "Nutricare",
58 | "tags": ["AngularJS", "JavaScript", "Express", "NodeJS", "Leaflet", "Heroku", "Python", "Pandas"],
59 | "description": "A web app for patients to input nutrient intake data and researchers to analyse the data with the help of graphs and tables. A researcher can conduct studies on N different subjects for a particular problem statement.",
60 | "readMore": "https://angel.co/projects/576300-nutricare",
61 | "image": "/assets/other-projects/nutricare.webp",
62 | "jpg": "/assets/other-projects/nutricare.jpeg"
63 | }
64 | ]
65 |
--------------------------------------------------------------------------------
/src/content/about/about-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "educations": [
3 | {
4 | "id": "edu-1",
5 | "school": "Indiana University",
6 | "degree": "Master of Science in Computer Science",
7 | "duration": "Aug 2019 - May 2021",
8 | "content": [
9 | "GPA: 4/4",
10 | "Courses: Software Engineering, Distributed Systems, Operating Systems, Advanced Algorithms, Experience Design"
11 | ]
12 | },
13 | {
14 | "id": "edu-2",
15 | "school": "Manipal University",
16 | "degree": "Bachelors in Computer Engineering",
17 | "duration": "Aug 2015 - Jul 2019",
18 | "content": [
19 | "GPA: 8/10",
20 | "Courses: Data Structures, OOP, Algorithms, Software Engineering, Computer Networks, Artificial Intelligence"
21 | ]
22 | }
23 | ],
24 | "experiences": [
25 | {
26 | "id": "exp-1",
27 | "company": "Reputation",
28 | "position": "Software Engineer (Frontend)",
29 | "duration": "Jun 2020 - Jun 2021",
30 | "description": [
31 | "Revamping the current report generation framework using React, that aggregates data from 30 modules to support an interactive cartesian system.",
32 | "Integrated user activity data from BigQuery into a custom tailored dashboard available to 10000+ clients.",
33 | "Spearheaded the work on multiple reports for 5 priority clients to provide additional functionalities."
34 | ]
35 | },
36 | {
37 | "id": "exp-2",
38 | "company": "CNS (NIH), Indiana University",
39 | "position": "Software Engineer",
40 | "duration": "Jun 2020 - Jun 2021",
41 | "description": [
42 | "Developed state of the art visualization tools for researchers and doctors to envision large biological datasets using Angular 11, Node & Vega.",
43 | "Devised an algorithm to compute statistics that highlight anomalies in the data and displayed them on an intuitive interface.",
44 | "Created detailed UX flows, experience maps, wire-frames and conducted interviews across various biological consortia to enhance user experience."
45 | ]
46 | },
47 | {
48 | "id": "exp-3",
49 | "company": "Skylark Drones",
50 | "position": "Software Engineer Intern",
51 | "duration": "Jan 2019 - Jun 2019",
52 | "description": [
53 | "Developed a web app for mission planning, control and execution using Vue & Flask, thereby improving onside project performance by 22%.",
54 | "Designed an icon set for various functionalities using Illustrator, which improved usability by 20%."
55 | ]
56 | }
57 | ],
58 | "skills": [
59 | {
60 | "title": "Programming",
61 | "tools": [
62 | "TypeScript",
63 | "JavaScript",
64 | "Python",
65 | "C/C++",
66 | "Java",
67 | "NoSQL",
68 | "SQL",
69 | "Shell",
70 | "React Native",
71 | "Vega (D3.js)"
72 | ]
73 | },
74 | {
75 | "title": "Web",
76 | "tools": ["React", "Angular 11", "Vue", "NodeJS", "Flask", "Redux", "NGXS", "HTML/CSS", "OAuth", "i18n"]
77 | },
78 | {
79 | "title": "Databases",
80 | "tools": ["MongoDB", "Redis", "MySQL", "Firebase"]
81 | },
82 |
83 | {
84 | "title": "OS & Tools",
85 | "tools": ["MacOS", "Linux", "Git", "Agile (Scrum)", "MVC", "Jenkins", "Heroku", "Docker", "Kubernetes"]
86 | },
87 | {
88 | "title": "Design & Research",
89 | "tools": [
90 | "Surveys",
91 | "Interviews",
92 | "User Research",
93 | "Design Strategy",
94 | "Experience Mapping",
95 | "Adobe XD",
96 | "Illustrator"
97 | ]
98 | }
99 | ],
100 | "blog": [
101 | {
102 | "id": "blog-1",
103 | "title": "A beginner's guide to github",
104 | "link": "https://hrishikeshpaul12.medium.com/a-beginners-guide-to-github-a811e662a777"
105 | },
106 | {
107 | "id": "blog-2",
108 | "title": "User Experience Design – A little more than just design",
109 | "link": "https://hrishikeshpaul12.medium.com/user-experience-design-a-little-more-than-just-design-afdb941aeb5"
110 | }
111 | ]
112 | }
113 |
--------------------------------------------------------------------------------
/src/pages/about/common/expandable/Expandable.tsx:
--------------------------------------------------------------------------------
1 | import { FC, useEffect, useState, useMemo } from "react";
2 |
3 | import { Box, Button, AccordionButton, AccordionPanel, Text, Flex, UnorderedList } from "@chakra-ui/react";
4 | import { SectionTitle } from "pages/about/common/title/Title";
5 |
6 | interface Props {
7 | expanded: number[];
8 | idx: number;
9 | onChange: (expanded: any) => void;
10 | title: string;
11 | subTitle: string;
12 | date: string;
13 | content: string[];
14 | id: string;
15 | }
16 |
17 | export const Expandable: FC = ({ expanded, id, idx, title, subTitle, date, content, onChange }) => {
18 | const isExpanded = useMemo(() => expanded.includes(idx), [expanded, idx]);
19 | const [isOverflowing, setIsOverflowing] = useState(false);
20 | const showSeeMoreBtn = useMemo(
21 | () => (content.length > 1 && !isExpanded) || (!isExpanded && isOverflowing),
22 | [isOverflowing, isExpanded, content],
23 | );
24 |
25 | useEffect(() => {
26 | const firstPointId = `first-point-${id}`;
27 | const element = document.getElementById(firstPointId);
28 |
29 | if (element) {
30 | if (element.scrollWidth >= element.parentElement?.scrollWidth!) {
31 | setIsOverflowing(true);
32 | } else {
33 | setIsOverflowing(false);
34 | }
35 | }
36 | }, [id]);
37 |
38 | return (
39 | <>
40 |
49 |
50 | {subTitle}
51 |
52 | {date}
53 |
54 |
55 | {!isExpanded ? (
56 |
57 | {content[0]}
58 |
59 | ) : (
60 |
61 |
62 | {content[0]}
63 |
64 |
65 | )}
66 | {showSeeMoreBtn && (
67 |
85 | )}
86 |
87 |
88 |
89 |
90 | {content.slice(1).map((cont, idx) => (
91 |
92 | {cont}
93 |
94 | ))}
95 |
96 | {expanded.includes(idx) && (
97 |
98 |
111 |
112 | )}
113 |
114 | >
115 | );
116 | };
117 |
--------------------------------------------------------------------------------
/src/pages/featured-projects/featured-project-card/FeaturedProjectCard.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from "react";
2 |
3 | import { Box, Flex, Heading, Image, Text } from "@chakra-ui/react";
4 | import { Tags } from "shared/tags/Tags";
5 | import { ProjectCardFooter } from "shared/project-card-footer/ProjectCardFooter";
6 |
7 | export enum ImagePosition {
8 | Right,
9 | Left,
10 | }
11 | interface Props {
12 | id: string;
13 | title: string;
14 | year: string;
15 | location: string;
16 | demo?: string;
17 | github?: string;
18 | tags: string[];
19 | description: string;
20 | readMore?: string;
21 | image: string;
22 | imagePosition: ImagePosition;
23 | jpg: string;
24 | }
25 |
26 | const ImagePositionLayoutMapper: Record = {
27 | [ImagePosition.Right]: "row",
28 | [ImagePosition.Left]: "row-reverse",
29 | };
30 |
31 | const ImagePositionPaddingRightMapper: Record = {
32 | [ImagePosition.Right]: "8",
33 | [ImagePosition.Left]: "0",
34 | };
35 |
36 | const ImagePositionPaddingLeftMapper: Record = {
37 | [ImagePosition.Right]: "0",
38 | [ImagePosition.Left]: "8",
39 | };
40 |
41 | export const FeaturedProjectCard: FC = ({
42 | id,
43 | title,
44 | demo,
45 | github,
46 | tags,
47 | description,
48 | readMore,
49 | image,
50 | imagePosition,
51 | location,
52 | year,
53 | jpg,
54 | }) => {
55 | return (
56 |
62 |
70 |
71 |
72 | {title}
73 |
74 |
83 | {year} • {location}
84 |
85 |
86 |
93 |
94 |
95 |
96 |
105 | {description}
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
122 |
123 |
124 |
125 |
132 |
133 |
134 |
135 | );
136 | };
137 |
--------------------------------------------------------------------------------
/src/shared/navbar/drawer/Drawer.tsx:
--------------------------------------------------------------------------------
1 | import { FC, useRef } from "react";
2 |
3 | import {
4 | Box,
5 | Button,
6 | Drawer,
7 | DrawerBody,
8 | DrawerHeader,
9 | DrawerOverlay,
10 | DrawerContent,
11 | DrawerCloseButton,
12 | useDisclosure,
13 | IconButton,
14 | StyleProps,
15 | Flex,
16 | VStack,
17 | useColorModeValue,
18 | } from "@chakra-ui/react";
19 |
20 | import { ColorModeButton } from "shared/color-mode-button/ColorModeButton";
21 | import { AboutPageId, WorkPageId } from "utils/useScroll";
22 | import { MenuIcon } from "utils/Icons";
23 | import { Socials } from "shared/socials/Socials";
24 | import { onResumeOpen } from "utils/Functions";
25 |
26 | interface Props extends StyleProps {
27 | onSectionClick: (section: string) => void;
28 | currentPage: string;
29 | }
30 |
31 | export const MenuDrawer: FC = ({ onSectionClick, currentPage, ...props }) => {
32 | const { isOpen, onOpen, onClose } = useDisclosure();
33 | const btnRef = useRef(null);
34 | const navItemColor = useColorModeValue("gray.800", "white");
35 |
36 | return (
37 |
38 | }
47 | px="0"
48 | />
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
80 |
99 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 | );
119 | };
120 |
--------------------------------------------------------------------------------