diff --git a/.gitignore b/.gitignore index e04bbd4..488e9a2 100644 --- a/.gitignore +++ b/.gitignore @@ -68,4 +68,4 @@ yarn-error.log # Yarn Integrity file .yarn-integrity -static/images/**/*.png \ No newline at end of file +static/seo-images/**/*.png \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c7e2671..0000000 --- a/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -language: node_js - -node_js: - - 16 - -script: - - npm run build - -deploy: - provider: pages - skip_cleanup: true - github_token: $GITHUB_TOKEN - keep_history: true - local_dir: ./public - repo: devagrawal09/devagrawal09.github.io - target_branch: master - fqdn: devagr.me - verbose: true - on: - branch: master diff --git a/.vscode/settings.json b/.vscode/settings.json index 9bd9eb1..89fc6e9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,28 +1,12 @@ { "workbench.colorCustomizations": { - "activityBar.activeBackground": "#fa1b49", - "activityBar.activeBorder": "#155e02", - "activityBar.background": "#fa1b49", - "activityBar.foreground": "#e7e7e7", - "activityBar.inactiveForeground": "#e7e7e799", - "activityBarBadge.background": "#155e02", - "activityBarBadge.foreground": "#e7e7e7", - "statusBar.background": "#dd0531", - "statusBar.foreground": "#e7e7e7", - "statusBarItem.hoverBackground": "#fa1b49", - "titleBar.activeBackground": "#dd0531", - "titleBar.activeForeground": "#e7e7e7", - "titleBar.inactiveBackground": "#dd053199", - "titleBar.inactiveForeground": "#e7e7e799", - "sash.hoverBorder": "#fa1b49", - "statusBarItem.remoteBackground": "#dd0531", - "statusBarItem.remoteForeground": "#e7e7e7" + "activityBar.activeBorder": "#155e02" }, "peacock.color": "#dd0531", "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "[typescriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" @@ -40,6 +24,7 @@ "hackathons", "ITSA", "leadershape", + "Microservices", "noreferrer", "revolutionuc", "revuc", diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..3717b31 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1 @@ +Do whatever diff --git a/appearances.md b/appearances.md new file mode 100644 index 0000000..a389523 --- /dev/null +++ b/appearances.md @@ -0,0 +1,41 @@ +# Appearances + +## Conferences + +- Meet The Web Framework From The Future (Frontend Nation, Virtual, June 2025) +- Sync engine's best friend: fine-grained rendering (Local First Conf, Berlin, Germany, May 2025) +- [Building Asynchronous UIs Without The Hassle](https://youtu.be/N1wSVaUdV_U) (Stir Trek, Columbus, OH, May 2025) +- [Building Asynchronous UIs Without The Hassle](https://youtu.be/pX5r_jTLbvw?si=qjTPBQkyb-zRP96R) (Codemash, Sandusky, OH, Jan 2025) +- [Harnessing Events for Reactive and AI-powered Frontends](https://edasummit.com/videos/harnessing-events-for-reactive-and-ai-powered-frontends/) (EDA Summit, Virtual, Dec 2024) +- [Deploying Stateful Realtime Services To The Edge](https://www.youtube.com/live/_cCmh-FrYeM?si=05mwvnxDxbZ_EAtx&t=2133) (Commit Your Code Conference, Dallas, TX, Dec 2024) +- Meet the Web Framework from the Future (Dev Innovation Summit, Santa Clara, CA, Nov 2024) +- [Build your own React Metaframework](https://youtu.be/4V_Wz_k35C8?si=wvar4Ra5i-aO6e6q) (React Rally, Salt Lake City, UT, Aug 2024) +- [Streams, not Waterfalls - Improving Page Load and Core Web Vitals](https://youtu.be/GrJVK6ci--s?si=nKoDMyK05RC2uwk9) (Stir Trek, Columbus, OH, May 2024) +- Meet Your New BFF: Backend to Frontend without the Duct Tape (Codemash, Sandusky, OH, Jan 2024) +- Workshop - Build an end to end Next JS app with Next auth, postgres realtime functionality (Codemash, Sandusky, OH, Jan 2024) +- [Workshop - From Todo App to B2B SaaS with Next.js and Clerk](https://gitnation.com/contents/from-todo-app-to-b2b-saas-with-nextjs-and-clerk) (React Summit US, Jersey City, NJ, Dec 2023) +- [Beyond the Login Page: Authentication in Next.js](https://youtu.be/44b2U0uGQ0k?si=zTFY-NBByjZw_OFq) (Next.js Conf, San Francisco, CA, Oct 2023) +- Meet Your New BFF: Fullstack without Duct Tape (APIWorld, Santa Clara, CA, Oct 2023) +- [Meet Your New BFF: Fullstack without Duct Tape](https://youtu.be/vAKwSEzj7sY?si=FkU5xBr9bzXO2vsQ) (Javascript and Friends, Columbus, OH, Aug 2023) + +## Podcasts + +- [Building Async UIs without the hassle with Dev Agrawal](https://podrocket.logrocket.com/building-async-uis-without-the-hassle-dev-agrawal) (PodRocket, Virtual, Feb 2025) +- [Solid.js IS REALLY FAST! Concept breakdown with Dev Agrawal](https://youtu.be/TwpcWoZCQ_4?si=MJuNkZ1t1XenVDVO) (The Programming Podcast, Virtual, Jan 2025) +- [Realtime Frameworks](https://www.youtube.com/live/q8AlF3QcR2M?si=hdyr5Gu8ie0Lcsbx) (AJC and the Web Devs, Virtual, Dec 2024) +- [Nitro, Vinxi, and RSCs](https://egghead.io/nitro-vinxi-and-rscs-whats-good-with-dev-agrawal~s577t) (What's Good (Egghead.io), Virtual, Sep 2024) +- [Build your own metaframework with Vinxi](https://www.youtube.com/live/2m9ErnaDy6s?si=o5XAnyr0XzDzXFXD) (Learn With Jason, Virtual, Jul 2024) +- [What's New in React 19 (and What That Means for You)](https://youtu.be/8GuvVaEWjzk?si=9sf5hn8ArtPzz9Os) (Scrimba Podcast, Virtual, Jun 2024) +- [Local-First Application Development is Back?](https://youtu.be/0bYeHVAk_EM?si=m3UiQnxbcTHazy_1) (Modern Web Podcast, Virtual, May 2024) +- [The State of React (and Should You Still Learn It in 2024)](https://youtu.be/nD1V18VBNcw?si=tnvwbyyJB7irxqMd) (Scrimba Podcast, Virtual, Feb 2024) +- [From College Student to Speaking at Conferences](https://www.linkedin.com/posts/taylordesseyn_from-college-student-to-speaking-at-conferences-activity-7163192438377926657-VOoy) (Guidance Counselor - 2.0, Virtual, Feb 2024) +- [I got CAUGHT rolling my own auth..](https://youtu.be/xjcvlddL398?si=A1T0qZWvm8CdsDkZ) (Backend Banter, Virtual, Jan 2024) +- [Clerk, Authentication, Web Dev, All the Things](https://youtu.be/vlxkTAzNm5Y?si=vWuoMMUoyJvFElCU) (Nicky T Live, Virtual, Sep 2023) + +## Meetups + +- [Sign-in Sessions, The most powerful authentication tool](https://youtu.be/MYIIuF1ELxM?si=rn5XyB49pgfYLUK2) (Certified Fresh Events, Virtual, Sep 2023) +- [Intro to modern Cloud services](https://youtu.be/EyGMpEgmRMo?si=lELS8TY1BBP-H-8f) (ACM@UC, Cincinnati, OH, Nov 2022) +- Workshop - React Dojo (ITSA + CECH Tribunal, Cincinnati, OH, Nov 2021 - Mar 2022) +- [Abstraction in Programming](https://youtu.be/cdssceyEbSU?si=jWUl8zleCNookuNv) (ACM@UC + ITSA, Cincinnati, OH, Oct 2021) +- [Docker Intro Session](https://www.youtube.com/live/7c8AuQ0Nljs?si=Dak20j06WtR96Nf5) (ACM@UC, Virtual, Mar 2020) diff --git a/gatsby-node.ts b/gatsby-node.ts index d74fab8..a44e2e5 100644 --- a/gatsby-node.ts +++ b/gatsby-node.ts @@ -1,11 +1,5 @@ -import { IExperience } from "./src/data/showcase/experiences/type.d" -/** - * Implement Gatsby's Node APIs in this file. - * - * See: https://www.gatsbyjs.org/docs/node-apis/ - */ - import { mergeWithBackground } from "./src/images/merge-images" +import { IExperience } from "./src/data/showcase/experiences/type.d" import type { GatsbyNode } from "gatsby" import type { IProject } from "./src/data/showcase/projects/type.d" @@ -23,7 +17,7 @@ const generateImageForProject = async (project: IProject) => { console.log(`Generating og image for project ${project.name}`) - const output = `${cwd}/static/images/projects/${project.id}.png` + const output = `${cwd}/static/seo-images/projects/${project.id}.png` return mergeWithBackground(project.image, output) } @@ -36,7 +30,7 @@ const generateImageForArticle = async (article: IArticle) => { console.log(`Generating og image for article ${article.frontmatter.title}`) - const output = `${cwd}/static/images/blog/${article.frontmatter.id}.png` + const output = `${cwd}/static/seo-images/blog/${article.frontmatter.id}.png` return mergeWithBackground(article.frontmatter.image, output) } @@ -45,14 +39,7 @@ export const createPages: GatsbyNode["createPages"] = async ({ graphql, actions: { createPage }, }) => { - const { - data: { - experiencesYaml: { experiences }, - projectsYaml: { projects }, - featuresYaml: { features }, - toolsYaml: { tools }, - }, - } = await graphql<{ + const { data: data1 } = await graphql<{ experiencesYaml: { experiences: IExperience[] } projectsYaml: { projects: IProject[] } featuresYaml: { features: IFeature[] } @@ -134,12 +121,7 @@ export const createPages: GatsbyNode["createPages"] = async ({ } `) - const { - data: { - allMarkdownRemark: { nodes: articles }, - tagsYaml: { tags }, - }, - } = await graphql<{ + const { data: data2 } = await graphql<{ allMarkdownRemark: { nodes: IArticle[] } tagsYaml: { tags: ITag[] } }>(` @@ -176,6 +158,18 @@ export const createPages: GatsbyNode["createPages"] = async ({ } `) + const { + experiencesYaml: { experiences }, + projectsYaml: { projects }, + featuresYaml: { features }, + toolsYaml: { tools }, + } = data1! + + const { + allMarkdownRemark: { nodes: articles }, + tagsYaml: { tags }, + } = data2! + projects.forEach(async project => { const path = `showcase/projects/${project.id}` createPage({ @@ -205,11 +199,7 @@ export const createPages: GatsbyNode["createPages"] = async ({ } export const onPreBuild: GatsbyNode["onPreBuild"] = async ({ graphql }) => { - const { - data: { - projectsYaml: { projects }, - }, - } = await graphql<{ + const { data: data3 } = await graphql<{ projectsYaml: { projects: IProject[] } }>(` query ProjectsQuery { @@ -229,10 +219,10 @@ export const onPreBuild: GatsbyNode["onPreBuild"] = async ({ graphql }) => { `) const { - data: { - allMarkdownRemark: { nodes: articles }, - }, - } = await graphql<{ + projectsYaml: { projects }, + } = data3! + + const { data: data4 } = await graphql<{ allMarkdownRemark: { nodes: IArticle[] } }>(` query BlogQuery { @@ -253,7 +243,10 @@ export const onPreBuild: GatsbyNode["onPreBuild"] = async ({ graphql }) => { } `) - // const generateProjectImages = [] + const { + allMarkdownRemark: { nodes: articles }, + } = data4! + const generateProjectImages = projects.map(generateImageForProject) const generateArticleImages = articles.map(generateImageForArticle) diff --git a/package-lock.json b/package-lock.json index 8bbd5dd..4840f39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,9 @@ "version": "0.1.0", "license": "MIT", "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.1.2", + "@fortawesome/free-solid-svg-icons": "^6.1.2", + "@fortawesome/react-fontawesome": "^0.2.0", "bootstrap": "^4.6.1", "canvas": "^2.9.1", "devicon": "^2.12.0", @@ -1919,6 +1922,62 @@ "node": ">= 4" } }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.1.2.tgz", + "integrity": "sha512-wBaAPGz1Awxg05e0PBRkDRuTsy4B3dpBm+zreTTyd9TH4uUM27cAL4xWyWR0rLJCrRwzVsQ4hF3FvM6rqydKPA==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.1.2.tgz", + "integrity": "sha512-853G/Htp0BOdXnPoeCPTjFrVwyrJHpe8MhjB/DYE9XjwhnNDfuBCd3aKc2YUYbEfHEcBws4UAA0kA9dymZKGjA==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.1.2.tgz", + "integrity": "sha512-lTgZz+cMpzjkHmCwOG3E1ilUZrnINYdqMmrkv30EC3XbRsGlbIOL8H9LaNp5SV4g0pNJDfQ4EdTWWaMvdwyLiQ==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz", + "integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, "node_modules/@gatsbyjs/parcel-namer-relative-to-cwd": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@gatsbyjs/parcel-namer-relative-to-cwd/-/parcel-namer-relative-to-cwd-1.1.0.tgz", @@ -4210,6 +4269,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@parcel/packager-js/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@parcel/packager-raw": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/@parcel/packager-raw/-/packager-raw-2.6.0.tgz", @@ -6668,6 +6738,17 @@ "node": ">=8" } }, + "node_modules/boxen/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -10205,6 +10286,17 @@ "node": ">=8" } }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -23451,9 +23543,11 @@ } }, "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -26433,9 +26527,43 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" } } }, + "@fortawesome/fontawesome-common-types": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.1.2.tgz", + "integrity": "sha512-wBaAPGz1Awxg05e0PBRkDRuTsy4B3dpBm+zreTTyd9TH4uUM27cAL4xWyWR0rLJCrRwzVsQ4hF3FvM6rqydKPA==" + }, + "@fortawesome/fontawesome-svg-core": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.1.2.tgz", + "integrity": "sha512-853G/Htp0BOdXnPoeCPTjFrVwyrJHpe8MhjB/DYE9XjwhnNDfuBCd3aKc2YUYbEfHEcBws4UAA0kA9dymZKGjA==", + "requires": { + "@fortawesome/fontawesome-common-types": "6.1.2" + } + }, + "@fortawesome/free-solid-svg-icons": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.1.2.tgz", + "integrity": "sha512-lTgZz+cMpzjkHmCwOG3E1ilUZrnINYdqMmrkv30EC3XbRsGlbIOL8H9LaNp5SV4g0pNJDfQ4EdTWWaMvdwyLiQ==", + "requires": { + "@fortawesome/fontawesome-common-types": "6.1.2" + } + }, + "@fortawesome/react-fontawesome": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz", + "integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==", + "requires": { + "prop-types": "^15.8.1" + } + }, "@gatsbyjs/parcel-namer-relative-to-cwd": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@gatsbyjs/parcel-namer-relative-to-cwd/-/parcel-namer-relative-to-cwd-1.1.0.tgz", @@ -28145,6 +28273,11 @@ "requires": { "type-fest": "^0.20.2" } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" } } }, @@ -29967,6 +30100,11 @@ "requires": { "has-flag": "^4.0.0" } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" } } }, @@ -32388,6 +32526,11 @@ "has-flag": "^4.0.0" } }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -42628,9 +42771,11 @@ } }, "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "optional": true, + "peer": true }, "type-is": { "version": "1.6.18", diff --git a/package.json b/package.json index 422a369..aa06bf1 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,9 @@ "version": "0.1.0", "author": "Kyle Mathews ", "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.1.2", + "@fortawesome/free-solid-svg-icons": "^6.1.2", + "@fortawesome/react-fontawesome": "^0.2.0", "bootstrap": "^4.6.1", "canvas": "^2.9.1", "devicon": "^2.12.0", diff --git a/resume.md b/resume.md new file mode 100644 index 0000000..fc29015 --- /dev/null +++ b/resume.md @@ -0,0 +1,164 @@ +# Dev Agrawal + +[GitHub](https://github.com/devagrawal09) . +[LinkedIn](https://www.linkedin.com/in/dev-agr) . +[Website](https://devagr.me) . +[Twitter](https://twitter.com/devagrawal09) . +[YouTube](https://youtube.com/@devagr) + +## Summary + +I build and teach how to build awesome fullstack applications. + +**8 years of experience** building products end-to-end, working directly with stakeholders and product owners. + +**2 years** creating educational content and speaking at tech conferences and podcasts about development and architecture. + +## Technical Skills + +**Languages:** TypeScript, Python, C#, Java, PHP, HTML and CSS + +**Web:** React, Solidjs, Angular, Vue, Svelte, Express, Next, Socket.io + +**Architecture:** Event Sourcing, CQRS, Microservices, Domain-Driven Design + +**Cross platform:** Ionic, React Native, Electron, PWA + +**Tools:** Cloud (Heroku, AWS, Azure, Netlify, Cloudflare, Vercel, Firebase), Database (SQL, MongoDB, Redis), DevOps (GitHub, Travis), SysAdmin (Linux, Docker, Nginx, Ansible) + +## Work Experience + +### Software Engineer (Xolvio) (Apr 2025 - Current) + +- Building a machine learning platform to help analysts run quantum algorithms +- Working with cutting edge Event Sourcing, GraphQL, and AI technologies +- Used **React Router**, **Apollo GraphQL**, **KurrentDB**, **Emmett**, and **Google Cloud** + +### Software Engineer (SmartData) (Apr 2024 - Apr 2025) + +- Built an **AI powered** project management assistant to accelerate internal processes +- Built a **next gen member application** for a healthcare company +- Implemented critical improvements for performance, developer experience, and cost efficiency +- Collaborated with the product, design, quality assurance, infrastructure, and security teams +- Used **Tanstack**, **Remix**, **React**, **Azure**, and **Okta** + +### Developer Advocate (Clerk.com) (May 2023 - Feb 2024) + +- Helped **establish Clerk in the community** during the hockey stick **growth period** (5x managed users, 3x downloads, 2x company size, Series A and B) +- **Engaged and provided support** to the Discord community of 8k members and Twitter community of 14k followers +- **Solidified Clerk's presence** at 5 conferences through **talks**, **workshops**, **demos**, and **product walkthroughs** +- **Curated feedback and requests** from the community to help **prioritize work** for the engineering team +- Built starter kits and demos on **Next.js**, **React**, **TailwindCSS**, and **Vercel** + +### Senior Software Developer (UC IT Solutions Center) (Jan 2020 – Aug 2020, Jan 2021 – Dec 2022) + +- **Led the development and operation** of the **Ohio Sentencing Data Platform** in collaboration with the **Ohio Supreme Court** and **10+ counties across Ohio** +- Led the work on a **suite of applications** used by **UC Corrections Institute** and **Department of Youth Services**, and developed the new version of the **primary case tracking application** +- **Identified and triaged project requirements** in collaboration with key stakeholders +- Used **Nodejs**, **Express**, **React**, **PostgreSQL**, **MongoDB**, and **Linux** + +### Research Assistant (University of Cincinnati) (Sep 2018 – Dec 2019) + +- Worked on a research project **funded by NSF and Mozilla** with a team of professors and masters students +- **Built an access control model** for smart-homes that supports **automatic emergency detection**, **escalation**, and **response** +- **Published a paper** for the **ACM International Conference** on Enhancing Smart Home Security + +### Web Developer (TorpedoShoes) (May 2019 – Aug 2019) + +- **Built an internal platform** using **MeteorJS** for tracking manufacturing lines, quality control, and reporting to **replace existing paper report system** used by **8 manufacturing units** + +### Web Developer (HealthyLovedOnes) (Apr 2018 – Jul 2018) + +- **Developed a web application** using **MeteorJS** for caregivers and people in need to connect with each other +- **Built a platform** for **job search**, **advertisement**, **communication**, and **payment** for caregivers + +### Web Developer (Bharat Vikas Parishad) (Feb 2017 – May 2017) + +- **Built a web application** for Bharat Vikas Parishad (Shiva Branch, Varanasi) for **management of over 50 members** using **PHP** and **Bootstrap** + +## Open Source + +- **Solid.js**, core team member (Dec 2024 - Current) +- **Solid-socket**, author (Oct 2024 - Current) +- **Solid-events**, author (Oct 2024 - Current) +- **Tanstack Start**, maintainer (Jun 2024 - Current) +- **Crossws**, contributor (Nov 2024 - Current) + +## Projects + +### Momentum DevCon App (Lead Developer) +- Application for **conference attendees** to view and **bookmark sessions**, **provide feedback**, and **connect with other attendees** +- Responsive **mobile-first** web application with **server rendering**, **optimistic UI**, **event sourcing**, and **CQRS** +- Built with SolidStart, Drizzle, Postgres, Vercel + +### Hackathon Suite (Lead Developer) + +- **Suite of applications** to aid hackathon organizing with **marketing**, **judging**, **registration**, **hacker matching**, and **discord management** +- Service-based backend **leveraging cloud services** (AWS, Heroku, Netlify, Cloudflare) +- **Frontends** built with Jekyll, React, and Angular + +### Ohio Sentencing Data Platform (Senior Developer) + +- Collaboration with the **Ohio Supreme Court** to **record and analyze data** about criminal sentencing cases +- **Custom built engine** to generate **complex forms** with **real-time capabilities**, **analyzable data outputs**, and **docx exports** based on JSON schemas +- **Integration with legacy systems** to pull data + +### Devtranet (Senior Developer) + +- **Networking platform** for engineers, investors, and entrepreneurs. +- **Discovering events**, **posting blogs**, **showcasing projects**, **finding jobs**, and **social media** +- **Full stack Typescript**, Next.js, React, and Tailwind + +### HealthyLovedOnes (Solo Developer) + +- A **job portal** for caregivers and those in need with built in hiring, communication, and payment system +- **Holistic caregiver profiles** based on professional and personal skills +- Mobile-ready **full stack application** built with Meteor + +## Appearances (Conferences, Podcasts, Meetups) + +- **Talk:** [Building Asynchronous UIs Without The Hassle (Codemash, Sandusky, OH, Jan 2025)](https://youtu.be/pX5r_jTLbvw?si=qjTPBQkyb-zRP96R) +- **Talk:** [Harnessing Events for Reactive and AI-powered Frontends (EDA Summit, Virtual, Dec 2024)](https://edasummit.com/videos/harnessing-events-for-reactive-and-ai-powered-frontends/) +- **Talk:** [Deploying Stateful Realtime Services To The Edge](https://www.youtube.com/live/_cCmh-FrYeM?si=05mwvnxDxbZ_EAtx&t=2133) (Commit Your Code Conference, Dallas, TX, Dec 2024) +- **Talk:** [Build your own React Metaframework](https://youtu.be/4V_Wz_k35C8?si=wvar4Ra5i-aO6e6q) (React Rally, Salt Lake City, UT, Aug 2024) +- **Podcast:** [What's New in React 19 (and What That Means for You)](https://youtu.be/8GuvVaEWjzk?si=9sf5hn8ArtPzz9Os) (Scrimba Podcast, Virtual, Jun 2024) +- **Talk:** [Streams, not Waterfalls - Improving Page Load and Core Web Vitals](https://youtu.be/GrJVK6ci--s?si=nKoDMyK05RC2uwk9) (Stir Trek, Columbus, OH, May 2024) +- **Workshop:** [From Todo App to B2B SaaS with Next.js and Clerk](https://gitnation.com/contents/from-todo-app-to-b2b-saas-with-nextjs-and-clerk) (React Summit US, Jersey City, NJ, Dec 2023) +- **Talk:** [Beyond the Login Page: Authentication in Next.js](https://youtu.be/44b2U0uGQ0k?si=zTFY-NBByjZw_OFq) (Next.js Conf, San Francisco, CA, Oct 2023) + +[Complete list](https://github.com/devagrawal09/portfolio/blob/master/appearances.md) + +## Education + +### Bachelor’s Degree – University of Cincinnati (Aug 2018 – May 2023) + +- BS in Information Technology, Software Development track (GPA 3.5) +- Minor in Psychology +- University Honors Program + +## Community + +### Organizer of Momentum Developer Conference (Feb 2023 - Current) + +- Member of steering committee of the biggest tech conference in Cincinnati (500+ registrations) +- Built an app for attendees and speakers to keep track of schedule, network, and provide feedback + +### Organizer of RevolutionUC And MakeUC (Sep 2019 – Mar 2023) + +- Organizer for UC’s largest hackathons +- Developing and managing the hackathon website, server, database, and the various online services + +### President of IT Student Association (Apr 2021 – Apr 2022) + +- President for UC’s largest student organization for IT students +- Providing weekly educational and networking opportunities to enthusiastic students + +### Executive Member of ACM@UC (May 2019 – Apr 2021) + +- Managing and updating the organization’s website +- Plan and record biweekly tech talks and workshops + +### Executive Member of The UC Rotaract Club (Oct 2018 – Oct 2021) + +- Hosting on-campus events and off-campus volunteering projects +- Collaborating with the Rotary Club for networking and professional development events diff --git a/src/components/portfolio/project-card.tsx b/src/components/portfolio/project-card.tsx index 4b80c10..852be60 100644 --- a/src/components/portfolio/project-card.tsx +++ b/src/components/portfolio/project-card.tsx @@ -1,5 +1,4 @@ import React from "react" -import { Link } from "gatsby" import { GatsbyImage, getImage } from "gatsby-plugin-image" import { Card, Row, Col } from "react-bootstrap" import { ToolBadge } from "./tool-badge" @@ -8,6 +7,7 @@ import { FeatureBadge } from "./feature-badge" import type { IProject } from "../../data/showcase/projects/type" import type { IFeature } from "../../data/tech/features/type" import type { ITool } from "../../data/tech/tools/type" +import { Link } from "@gatsbyjs/reach-router" interface CardProps { project: IProject @@ -66,7 +66,7 @@ export const ProjectCard = ({ {project.image && ( diff --git a/src/data/blog/articles/isomorphic.md b/src/data/blog/articles/isomorphic.md index 5c77f30..eec6f0c 100644 --- a/src/data/blog/articles/isomorphic.md +++ b/src/data/blog/articles/isomorphic.md @@ -2,7 +2,7 @@ id: isomorphic title: "Isomorphic Code" date: "05-31-2022" -featured: 2 +featured: 3 image: images/isomorphic.png tags: [technology, software_development] --- diff --git a/src/data/blog/articles/junior.md b/src/data/blog/articles/junior.md index 2d1faaf..36ab80e 100644 --- a/src/data/blog/articles/junior.md +++ b/src/data/blog/articles/junior.md @@ -1,8 +1,7 @@ --- id: junior title: "Year in Review - Junior" -date: "06-11-2021" -featured: 3 +date: "06-11-2022" tags: [honors, year_in_review] --- diff --git a/src/data/blog/articles/senior.md b/src/data/blog/articles/senior.md new file mode 100644 index 0000000..8fd6efc --- /dev/null +++ b/src/data/blog/articles/senior.md @@ -0,0 +1,101 @@ +--- +id: senior +title: "Year in Review - Senior" +date: "07-23-2023" +tags: [year_in_review] +featured: 1 +--- + +*“I had everything, then I had nothing.”* + +In the past year, I found myself uttering this overly dramatic sentence to describe areas of my life to myself and close friends. + +Obviously, I didn’t actually lose ***everything***. Broadly speaking, my life has certainly leveled up quite a bit since I wrote the last year-in-review. I have a +new job +as a Developer Advocate in a rapidly growing startup, I am +making content +about things I enjoy, I am +traveling to conferences +and meeting +people that I look up +to and enjoy chatting with, and I’m earning a decent enough paycheck to keep my mom and debt happy. I even +graduated college +and acquired work authorization in the US! Objectively speaking, I have more things now that I did 2 years ago. + +**Then why do I feel like I have lost more than I have gained?** + +### Craft, Crack, Crash + +In the last year-in-review, I decided the theme of the upcoming year to be *Craft*. I wanted to spend some time carefully crafting my brand, my content, my skills, and my network. + +Where did I get this idea from? Why did I decide the theme to be “craft” and not something else? + +I can sit here and say that for the last 4 years I have been reflecting on how my year went and logically deciding what the next step should be to come up with the theme for the upcoming year. That would be a lie. Maybe there is a subconscious part of my brain that actually is doing that calculation and helping me decide the theme, I wouldn’t be surprised if that were the case. + +But I mostly feel like I look into a crystal ball to see what the upcoming year might be like, what I expect myself to be doing, and pick a theme based on that. + +It seems like last year when I looked into the crystal ball, things were foggy and unclear, and all I saw out of it was an engraving with three letters - *cra...*, and then I made up the rest and decided on *craft*. + +I wish there was a way to rewind the clock back a year so that I can take a better look at what the crystal ball was trying to tell me. Was it actually trying to show me the things I have *crafted*? Was it an indicator of the *cracks* forming in my life? Or was it a warning that things are going to *crash*? + +What if it was all three? + +### The Cracks + +The cracks in my life had already started to show when I started writing the last year-in-review. I had low energy and motivation, missed the first couple deadlines, then hastily wrote it past due date and sent an apologetic letter to my amazing advisor Ashley for not finishing the year in review early enough. I wasn’t very happy with what I had written, but I published it anyways because I couldn’t be bothered with it. I was tired. + +I took some time recently to read back all my year-in-reviews, and apparently I did a pretty good job of structuring and formulating my thoughts last year, even while lacking the energy and motivation to do so. However, the cracks in my life subtly reveal themselves in this review if you know what to look for. + +I had started to grow unhappy. Unhappy with my academics, with my job, with my relationship, and with my living conditions. This was causing more frustration and exhaustion than I would have cared to admit at that time. Needless to say, the feeling of “my life is perfect” that I had a couple years ago was almost gone - I just hadn’t noticed it yet. + +I made attempts at fixing stuff - I tried to move out of my apartment and live at a new place with new people. I started applying to new jobs, and even asked my employer at that time to accommodate my requests. I tried fixing my relationship and make more room to enjoy each others’ company instead of getting annoyed by each others’ presence. All of my attempts failed, and led to the inevitable crash. + +### The Crash + +In December, I decided to take the winter holidays to travel back to India and go on a vacation with my family. I had a great time - got to reconnect with my family and some old friends, met my brother’s newborn for the first time and realized that babies are kinda cute, and took some amazing photos enjoying snow on the top of the mighty Himalayas. For the most part I was just enjoying the moment of break from my usual life, and I wasn’t spending too much time thinking about the fact that I had just resigned from my job and broke up with my girlfriend. + +Financially I was in a decent enough position that not having a job for a few months would not be a big deal - I was pretty confident that I would have a job by the time I graduated college. However, any idea I had of experiencing “the perfect life” crashed and crumbled, as the two biggest pillars that it stood on couldn’t bear the cracks that had formed over the year. + +While I came back from that vacation in January with a fresh motivation to start crafting again, the crash caught up with me very quickly. I was feeling unmotivated, wasting most of my time doomscrolling and looking for those little dopamine hits, procrastinating and missing basically every single deadline. I had never felt this low and unmotivated in my life. Even my last breakup in 2020, which I expected to have serious consequences on my mental health, did not come close to what I was going through a few months ago, and still am at the time of writing this. + +For the longest time, I was unwilling to accept that something was wrong and needed to be fixed. I kept chugging along, making promises that I couldn’t keep, setting expectations I couldn’t meet, and pretending to do things I wasn’t actually doing. + +Finally, a couple weeks ago, I decided to stop everything else and ask some serious questions about what had happened to me. I spent an entire night trying to remember and note down every significant event from the last 5 years, and how one event led to another, in an attempt to pinpoint the source of the cracks and the crash. Weirdly, the conclusion was both satisfying and unsatisfying at the same time. + +### It was... inevitable? + +Free will is an illusion. We are just a collection of terribly-designed bio-electrical machines capable of remembering and communicating ideas. Actions and decisions are purely based on past events and experiences instead of some internal choice making process that many people believe we possess and label as “free will”. + +Subscribing to this deterministic ideology comes with some nice perks - the entire reason I am able to reconstruct the past and track my mental state through time is because that’s how I believe the world works. It gives me insight into why people do the things they do, and leverage that information for everyone’s benefit. This is why I study psychology - it reveals how determinism manifests within people, similar to how physics reveals the determinism of objects. It’s also a great sympathy building tool - at no point can I ever really blame someone for what they did, because I am fully aware that there are deterministic reasons that led to it. We can only learn from what has already happened and hope that we are better prepared for the next time. + +But determinism is a double edged sword - it’s not that difficult to slip into nihilism from here. Do we have any control over our lives at all? If I am simply a cog in the grand cosmic machine, can I do something that I wouldn’t already be doing? Do I have the power to hold things together when fate is hell-bent on pulling them apart? + +Maybe I was afraid of asking myself these questions, which is why I couldn’t accept that something was wrong and needed to be fixed. Maybe I was afraid of coming to the realization that there is nothing to pinpoint - it was one small thing after another that slowly caused those cracks, things that were natural, organic, and inevitable. My experience of “the perfect life” was never going to be permanent, instead it was a naïve portrayal of one short phase of my life when I felt very happy and satisfied with everything, a phase that would slowly slip away without me noticing, and I would just be left watching it happen and experiencing the consequences. + +The general frustration with life and feelings of burnout seemed to form a feedback loop - I started to grow a little unhappy about things, which led to loss of energy and rise in frustration, which impacted my ability to cope with them and led to making more mistakes, which lead to even more unhappiness, and eventually to the inevitable crash. After the dust had settled, all I was left with were ashes, which I continued to carry around for months, without ever fully healing from the burnout. + +### The Craft + +So far I have painted a pretty bleak picture of my life over the last year. And it certainly was at times. This is why I am very surprised at how much of my initial promise of *crafting* I was still able to keep up. + +Content creation has been an absolute boon for me. I had zero expectations of ever getting even slightly famous or recognized in the industry. I had zero expectations of unlocking opportunities I didn’t know existed. I just wanted to look at a camera and rant about microservices for a bit. But as I dove into the world of content creation, I started to see more and more opportunities, and I tried to grab as many of them as I could. This is a legitimate industry now and I am excited to see how far I can push myself and what kind of content I can craft. + +My venture into content creation led me to discover Developer Relations - an industry closely tied to content creation but with very specific goals. I decided to pursue a career in DevRel as an opportunity to see what I can learn about this fascinating new industry. This means that my career as a Software Developer has been put on hold and moved to the back burner for the time being. I am unsure if this was the best decision, and there are times when I wish that I still had my old job, or some other job that allowed me to explore the complexities and intricacies of developing software systems at scale. But, that will have to wait. I first need to explore this new position that I have crafted for myself. + +I never thought of myself as someone who is excited to meet and talk to people. But throughout the year the benefits of professional networking and making industry connections have presented themselves to me like an angel visiting me in my dreams and granting my wishes. Soon enough, I found myself enjoying communities and industry events and random meetups. I also realized that to take the best advantage of these opportunities, I am in serious need of a mindset shift. I cannot be my usual shy and introverted self anymore - I have to actually learn how to make myself more approachable, more trustworthy, and most of all, a good and fun person to be around. I started crafting something that I always thought was immutable - my personality. + +I have also taken my love for organizing events to the next level - by helping organize a pretty large tech conference, along with volunteering at others, and helping out with local meetups. I am starting to recognize the special role of these events in our industry, and I want to help craft events that have a meaningful long term impact on everyone. + +### Recover + +I don't think this time I need to look into a crystal ball to figure out what I need to be doing. It's pretty obvious - *recover*. Recover from the crash, fill in the cracks with something stronger than whatever was holding it together before, and get back to a state of mind where I am free to craft whatever I want to without burning myself out. A lot of people are counting on me, and rooting for me, and I am not letting them down again. I need to get my act together push forward. + +But recovering is not enough - it's not like I was in a great state even 2 years ago. Yes I was happy, but there were still things that I was doing wrong, things that led to the cracks in the first place. I hope I am able to identify these issues and do my best to ensure they don't ruin my life ever again. As a wise man once said, + +
+ +_Sometimes the best you can do is to help yourself._ + +
+ +_Cheers, and take care!_ diff --git a/src/data/blog/articles/serverless.md b/src/data/blog/articles/serverless.md index 07ce202..fa98d47 100644 --- a/src/data/blog/articles/serverless.md +++ b/src/data/blog/articles/serverless.md @@ -1,12 +1,14 @@ --- id: serverless title: "Serverless Deployment" -date: "06-15-2022" -featured: 1 +date: "06-16-2022" +featured: 2 image: images/serverless.png tags: [technology, software_development] --- +

Image sourced from Hexaware

+ This infamous depiction of serverless has been circulating around for years now. According to this image, Serverless Functions, also called "Functions as a Service", is way to write an application with a focus on business logic and not worrying about infrastructure or runtime. ## I'm new to serverless, how does this work? @@ -25,7 +27,7 @@ app.get(`/`, async (req, res) => { res.json({ cats }) }) -app.listen(3000) +app.listen(process.env.PORT) ``` To have a similar application on a serverless platform like AWS Lambda, your code would look like this - @@ -54,18 +56,64 @@ functions: method: get ``` -This can now be deployed to Lambda using the AWS cli. Based on the configuration file, when a trigger event happens, a new container will spin up and execute this function. +

+ Serverless Framework Configuration +

+ +This can now be deployed to Lambda using the AWS CLI (or something vendor-agnostic like the serverless framework). Based on the configuration file, when a trigger event happens, a new container will spin up and execute this function. You just wrote some code and deployed it without thinking about any infrastructure or runtime! ## Execution On Demand -While on the surface the code looks similar, your cannot simply throw out express, setup lambda routes and call it a day. - -Well, technically you can, but you'll end up with a very unoptimized and wasteful mess, followed by losing trust in all cloud services and going back to buying racks and switches. +When you deploy traditional apps, you (or your trusty Continuous Delivery service) will spin up a container, start your application process inside the container, establish a network connection, and send an alert to your slack channel. This application will now wait for network requests and react to them as told. All this while, it's consuming memory and processing power, even when it does not receive any requests. -With traditional apps, you (or your trusty orchestration service) will spin up a container, start your application process inside the container, establish a network connection, and send an alert to your slack channel. This application will now wait for network requests and react to them as told. All this while, it's consuming memory and processing power, even when it does not receive any requests. +Deployment flow in a traditional app In comparison, when you deploy a serverless function, a service like Lambda will only bill you for the time your function is actually running, which only happens when it's triggered. When there is a trigger event, Lambda will find the corresponding function for that trigger, then either spin up a new container and load the function in it (cold start) or find an existing container that has the function already loaded in memory (hot start), and execute the function. The container will then either stay on and wait for more requests, or die out. -So you can start to notice some differences here. If you receive 1 request every second, you will only have 1 running function every second. However, if you get a thousand requests at the same time, Lambda will run a thousand containers with the function. So this approach is extremely elastic. You will use and pay for only the exact resources that you use. If you have multiple functions, each function is deployed as a separate Lambda, so you also will only be using the resources required to run that one function for any trigger. +Deployment flow in a traditional app + +So you can start to notice some differences here. If you receive 1 request every second, you will only have 1 running function every second. However, if you get a thousand requests at the same time, Lambda will run a thousand containers with the function. So this approach is extremely elastic. You will use and pay for only the exact resources that you use. If you have multiple functions, each function is deployed as a separate Lambda, so you also will only be using the resources required to run that one function. + +## So it's always cheaper? + +Not really. + +For a base unit of computation (like an hour of server usage), you will pay more to the serverless service than you would for a virtual server. + +
+
+ AWS Lambda costs around $0.06 for a full hour of execution with 1 GB of memory (calculated per ms of use).
+ AWS EC2 can cost between $0.008 to $0.01 per hour for an instance with 1 GB of memory. +

+ Sources: + EC2 Pricing, + Lambda Pricing +

+
+
+ +The difference lies in how much computation you are using. With a virtual server, you are paying for every second the server is alive, regardless of whether your code is running in it. In comparison, a serverless function will only cost you the computation of the function itself. + +It's optimized for elasticity, so it's only feasible in scenarios where you need elasticity. If you have inconsistent or unpredictable usage, serverless is a nice fire-and-forget deployment method where you app will scale up and down automatically as needed. + +

+Deployment flow in a traditional app +

+ +If you have some consistent patterns in usage, and you don't mind having to manage containers or servers, serverless is probably not going to be feasible for you. + +

+Deployment flow in a traditional app +

+ +## How do I start then? + +Well, hold your horses. + +There is one other case where you can't simply deploy to serverless. If your application is currently in a state of spaghetti, serverless will cause more pain than harm. + +Since your functions are loaded and executed separate from each other, you can apply a lot of the principles of Microservices here. The functions should be small, independent, and fulfil a single responsibility. I have another post coming up on Microservices, that's where I'll talk more about the purpose and strategy behind Microservices. + +Serverless seems (for now) to be the pinnacle of what cloud technology is hoping to achieve - allowing us, the developers, to write code that serves business functions with minimal management of the infrastructure that the code will run on. diff --git a/src/data/showcase/experiences/data.yaml b/src/data/showcase/experiences/data.yaml index f2f1b61..6fe169b 100644 --- a/src/data/showcase/experiences/data.yaml +++ b/src/data/showcase/experiences/data.yaml @@ -1,4 +1,12 @@ experiences: + - id: itsa + name: Student Organization Leadership + description: Lead one of the largest tech orgs on campus + date: January 2022 + image: ./itsa/logo.png + pageImage: ./itsa/banner.png + page: ./itsa/article.md + - id: roundtable name: Student Leader Round Table description: The student leader illuminati diff --git a/src/data/showcase/experiences/itsa/article.md b/src/data/showcase/experiences/itsa/article.md index e509db5..156a5d8 100644 --- a/src/data/showcase/experiences/itsa/article.md +++ b/src/data/showcase/experiences/itsa/article.md @@ -1,17 +1,13 @@ -But obviously, I couldn't have done it alone. Running an organization also meant leading an organizations, -which I was not good at. I still took the jump and held an election to get more executive members, -and then selected some people to be committee chairs. But I could not follow through on a lot -of things, especially sharing my passion and enthusiasm for hosting events and creating -a community. Many times I'd just reach out to others on the team for certain tasks, and -have to act as a kind of boss ordering someone to work on something. I did not want to do that, -but I couldn't come up with a better way to get everyone on the same page and collaboratively -organize an activity and get everything done on time. I also ended up doing pretty much -everything by myself, because it seemed a much faster way to finish tasks. +Having experienced a touch of organizational leadership and hosting events through ACM@UC and RevolutionUC, I decided to increase the challenge and really test my abilities as an organization leader. I was also interested in fostering a student community similar to what I had experience in the computer science space but in the information technology space. -While this gave me a lot of freedom to develop and implement -new solutions and automations, it also required me to lead the team and not do it alone. +And ITSA was the perfect opportunity for this. Not only was ITSA the primary student organization in the IT community, it was also almost dead and anyone who was interested in sustaining ITSA had already graduated. This meant I got to use an existing recognized brand name but still start from scratch in terms of ideas and activities. -As you might expect the same thing happened where I was not a capable enough leader -and ended up doing most of the work myself, because I could not share my passion and skills -with everyone. While I would love to attribute this to the members' lack of interest, -as a leader I am always accountable for anything that happens in the team to some extent. +My vision for the ITSA was simply this - _The go-to club for tech enthusiasts at UC_. This meant hosting events that are educational and provide networking opportunities, exposing students to the industry, and fostering a community where people with mutual interests can share ideas and form groups. + +For the Fall 2021 semester, we did events almost every week on wednesdays, which ranged from simple ice-breakers and get-to-knows to workshops on programming and web development, to informational sessions on research or data analysis from professionals. We collaborated with the Civic Tech Research Lab to host a session on research projects and methodologies, and invited speakers from companies like SmartData, Brooksource, and Skilled Inc. to share their professional wisdom. We also hosted an exam review session and study group before the final exams week to help students get a better handle on the course material. + +For the Spring semester, we decided to slow down the pace and host events every other month. We toured the CyrusOne data center, and the IT Solutions Center, to help students learn about industry teams and operations. We also sponsored students to attend the Momentum Developer Conference and React Miami Conference, both of which were huge learning and networking opportunities for the students. + +We were also recognized as the primary community of IT students by multiple university departments, and our executives as representatives of the IT student body as a whole. We were contacted by the School of IT and the Cincinnati Innovation District to help organize networking events that would be most useful to the students. We were also contacted by ELCE to provide feedback to changes to the EEP program from the perspective of a student. We also met with recruiters and company executives to help them meet more students to hire through sponsored events. + +This experience was a gold mine of personal and professional development for me. Each event involved a lot of marketing and logistics work, coordinating with speakers, members, and other organizers, and coming up with ideas or content. I also met a lot of good people in the industry who are going to be a great help to my professional life. This has been a great experience in leadership and community building for me. diff --git a/src/data/showcase/experiences/itsa/banner.png b/src/data/showcase/experiences/itsa/banner.png new file mode 100644 index 0000000..b532334 Binary files /dev/null and b/src/data/showcase/experiences/itsa/banner.png differ diff --git a/src/data/showcase/experiences/itsa/logo.png b/src/data/showcase/experiences/itsa/logo.png new file mode 100644 index 0000000..486a0b1 Binary files /dev/null and b/src/data/showcase/experiences/itsa/logo.png differ diff --git a/src/data/showcase/experiences/leadershape/article.md b/src/data/showcase/experiences/leadershape/article.md index d7645a1..cf492b2 100644 --- a/src/data/showcase/experiences/leadershape/article.md +++ b/src/data/showcase/experiences/leadershape/article.md @@ -3,7 +3,7 @@ One of the five competencies of the University Honors Program is Leadership. Lea The approach taken by Leadershape to make us understand the building blocks of a leader was interesting and effective. They take a brief definition of what constitutes a leader, break it apart into pieces, and expand each piece over the course of an entire day so that we have a complete picture. Each day brought insight into a new dimension of life, forcing us to think about things in ways we never thought existed. The key takeaway was as simple as putting all the pieces gained throughout the course of the week together (which is much easier said than done). Perhaps the most interesting day for me was the day we were talking about the term "Vision". One of the most compelling attributes of a good leader is ambition, and only a person with an ambition mission can become a good leader. A Vision to realize, a mission to complete, these are great motivators. They drive a person and their actions like nothing else can. A leader needs to be driven towards a goal, only then can he inspire others to follow him on his campaign.
-I found this particularly interesting because I have always considered myself to be a very ambitious person. I often think about where I could be 5-10 years in the future, and those scenarios are sometimes not very realistic. But on this day, we had to think about a specific personal vision that we always have wanted to see realized. So unlike the other occasions when I used to dream about my future, this one had to be a little more realistic, specific and organized, so that I can easily convey it. This was followed by an activity, which made us write a news article that would be published when our vision would be realized, and the news article would describe the achievement. [Here is the article I wrote](/leadershape-article.jpeg). +I found this particularly interesting because I have always considered myself to be a very ambitious person. I often think about where I could be 5-10 years in the future, and those scenarios are sometimes not very realistic. But on this day, we had to think about a specific personal vision that we always have wanted to see realized. So unlike the other occasions when I used to dream about my future, this one had to be a little more realistic, specific and organized, so that I can easily convey it. This was followed by an activity, which made us write a news article that would be published when our vision would be realized, and the news article would describe the achievement. [Here is the article I wrote](/images/experiences/leadershape/leadershape-article.jpeg). Aside from the main objective, one important aspect of the whole experience was getting to know more like-minded people and talking about ideas, thoughts and feelings. On the very first day, we were told that to truly develop self, we need to stretch out of our comfort zone and try out new things, until those new things become our comfort zone. For me, this is exactly what happened throughout the week. diff --git a/src/data/showcase/projects/hackathon.md b/src/data/showcase/projects/hackathon.md index 6d8ee1c..d6fbc72 100644 --- a/src/data/showcase/projects/hackathon.md +++ b/src/data/showcase/projects/hackathon.md @@ -18,13 +18,13 @@ This project is composed of: - An emails server to process templates designed in HTML and SCSS and produce email templates. Built using Express and HEML. - A modular monolith API server, built with NestJS and Postgres. - + ## Architecture Deployment diagram - + ## My Role diff --git a/src/pages/blog/index.tsx b/src/pages/blog/index.tsx index 64f313a..b1f40fd 100644 --- a/src/pages/blog/index.tsx +++ b/src/pages/blog/index.tsx @@ -41,8 +41,8 @@ export const query = graphql` ` const ArticleCard: FC< - { article: IArticle; allTags: ITag[] } & HTMLAttributes -> = ({ article, allTags, ...props }) => { + { article: IArticle; allTags: ITag[]; image?: boolean } & HTMLAttributes +> = ({ article, allTags, image, ...props }) => { const tags = allTags.filter(tag => article.frontmatter.tags?.includes(tag.id)) return ( @@ -75,7 +75,7 @@ const ArticleCard: FC< {tags.map(tag => ( ))} - {article.frontmatter.image && ( + {article.frontmatter.image && image && ( { article={first} allTags={allTags} className="featured-article-card" + image /> diff --git a/src/pages/contact.js b/src/pages/contact.js index 83d95ed..69f258a 100644 --- a/src/pages/contact.js +++ b/src/pages/contact.js @@ -44,9 +44,20 @@ const ContactPage = ({ location }) => ( Social media ftw!
- Twitter
- Facebook
- Instagram + + Twitter + {" "} +
+ + Facebook + {" "} +
+ + Instagram +

diff --git a/src/pages/index.d.ts b/src/pages/index.d.ts new file mode 100644 index 0000000..1ea2b53 --- /dev/null +++ b/src/pages/index.d.ts @@ -0,0 +1 @@ +declare module "*.jpg" diff --git a/src/pages/index.js b/src/pages/index.js deleted file mode 100644 index 1be3f40..0000000 --- a/src/pages/index.js +++ /dev/null @@ -1,14 +0,0 @@ -import React from "react" -import Layout from "../components/layout" - -const IndexPage = ({ location }) => ( - -
-
-

Welcome to my site!

-
-
-
-) - -export default IndexPage diff --git a/src/pages/index.tsx b/src/pages/index.tsx new file mode 100644 index 0000000..72bd774 --- /dev/null +++ b/src/pages/index.tsx @@ -0,0 +1,59 @@ +import { Link } from "@gatsbyjs/reach-router" +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" +import { faAward, faCode, faNewspaper } from "@fortawesome/free-solid-svg-icons" + +import React from "react" +import Layout from "../components/layout" +import profileImg from "./profile.jpg" + +const IndexPage = ({ location }) => ( + +
+
+
+
+ profile +
+
+

Welcome!

+

+ I am a software developer and an aspiring software architect and + content creator. +

+ +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+
+
+
+
+) + +export default IndexPage diff --git a/static/profile.jpg b/src/pages/profile.jpg similarity index 100% rename from static/profile.jpg rename to src/pages/profile.jpg diff --git a/src/pages/resume.pdf b/src/pages/resume.pdf index 2b15bc7..0b9f9a4 100644 Binary files a/src/pages/resume.pdf and b/src/pages/resume.pdf differ diff --git a/src/styles/global.css b/src/styles/global.css index 2f1a63f..da1083e 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -325,3 +325,15 @@ p { .text-justify-p p { text-align: justify; } + +.landing { + text-shadow: 0 0 5rem rgba(0, 0, 0, 1); +} + +.landing h1 { + font-size: 5rem; +} + +.landing p { + font-size: 1.5rem; +} diff --git a/src/templates/article-page.tsx b/src/templates/article-page.tsx index b20d2ec..ac49dcf 100644 --- a/src/templates/article-page.tsx +++ b/src/templates/article-page.tsx @@ -27,7 +27,7 @@ const ArticlePageTemplate = ({ pageContext }) => { path={path} image={ article.frontmatter.image - ? `/images/blog/${article.frontmatter.id}.png` + ? `/seo-images/blog/${article.frontmatter.id}.png` : undefined } > diff --git a/src/templates/experience-page.tsx b/src/templates/experience-page.tsx index f3b8466..05387ed 100644 --- a/src/templates/experience-page.tsx +++ b/src/templates/experience-page.tsx @@ -9,22 +9,20 @@ const ExperiencePageTemplate = ({ pageContext }) => { const experience: IExperience = pageContext.experience const __html = experience.page?.childMarkdownRemark.html - const image = experience.pageImage ? getSrc(experience.pageImage) : `` + const image = experience.pageImage return ( <>
- + {image && ( + + )}
diff --git a/src/templates/project-page.tsx b/src/templates/project-page.tsx index fa23ebc..ece98c7 100644 --- a/src/templates/project-page.tsx +++ b/src/templates/project-page.tsx @@ -23,7 +23,9 @@ const ProjectPageTemplate = ({ pageContext }) => { title={project.name} description={project.description} path={path} - image={project.image ? `/images/projects/${project.id}.png` : undefined} + image={ + project.image ? `/seo-images/projects/${project.id}.png` : undefined + } >
diff --git a/static/images/blog/serverless/consistent-execution.png b/static/images/blog/serverless/consistent-execution.png new file mode 100644 index 0000000..c7d8fca Binary files /dev/null and b/static/images/blog/serverless/consistent-execution.png differ diff --git a/static/images/blog/serverless/execution-time.png b/static/images/blog/serverless/execution-time.png new file mode 100644 index 0000000..9156a9a Binary files /dev/null and b/static/images/blog/serverless/execution-time.png differ diff --git a/static/images/blog/serverless/serverless-deploy.png b/static/images/blog/serverless/serverless-deploy.png new file mode 100644 index 0000000..3c37d99 Binary files /dev/null and b/static/images/blog/serverless/serverless-deploy.png differ diff --git a/static/images/blog/serverless/traditional-deploy.png b/static/images/blog/serverless/traditional-deploy.png new file mode 100644 index 0000000..bf75c13 Binary files /dev/null and b/static/images/blog/serverless/traditional-deploy.png differ diff --git a/static/leadershape-article.jpeg b/static/images/experiences/leadershape/leadershape-article.jpeg similarity index 100% rename from static/leadershape-article.jpeg rename to static/images/experiences/leadershape/leadershape-article.jpeg diff --git a/static/images/experiences/revolutionuc/architecture.png b/static/images/experiences/revolutionuc/architecture.png new file mode 100644 index 0000000..af52180 Binary files /dev/null and b/static/images/experiences/revolutionuc/architecture.png differ diff --git a/static/images/experiences/revolutionuc/teams.png b/static/images/experiences/revolutionuc/teams.png new file mode 100644 index 0000000..41e25f9 Binary files /dev/null and b/static/images/experiences/revolutionuc/teams.png differ diff --git a/static/images/experiences/revolutionuc/trello.png b/static/images/experiences/revolutionuc/trello.png new file mode 100644 index 0000000..5d7a7e3 Binary files /dev/null and b/static/images/experiences/revolutionuc/trello.png differ diff --git a/static/hackathon-deployment.png b/static/images/projects/hackathon/deployment.png similarity index 100% rename from static/hackathon-deployment.png rename to static/images/projects/hackathon/deployment.png diff --git a/static/hackathon-web.jpg b/static/images/projects/hackathon/web.jpg similarity index 100% rename from static/hackathon-web.jpg rename to static/images/projects/hackathon/web.jpg diff --git a/static/images/blog/index.html b/static/seo-images/blog/index.html similarity index 100% rename from static/images/blog/index.html rename to static/seo-images/blog/index.html diff --git a/static/images/experiences/index.html b/static/seo-images/experiences/index.html similarity index 100% rename from static/images/experiences/index.html rename to static/seo-images/experiences/index.html diff --git a/static/images/projects/index.html b/static/seo-images/projects/index.html similarity index 100% rename from static/images/projects/index.html rename to static/seo-images/projects/index.html