Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 84 additions & 86 deletions apps/app/content/cv/cv.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import Chip from '@mui/material/Chip';
import Typography from '@mui/material/Typography';
import { SkillBadge } from "@n8v/app/components/elements/shields-io/variants/skill-badge";
import { Connect } from "@n8v/app/components/elements/shields-io/variants/connect";
import { CvSectionDivider } from "@n8v/app/components/fragments/cv-section-divider";
import Grid from '@mui/material/Unstable_Grid2';
import Link from '@mui/material/Link';

import PermIdentity from "./images/perm_identity.svg";
import Cake from "./images/cake.svg";
import Gender from "./images/gender.svg";
import Github from "./images/github.svg";
import LinkedIn from "./images/linkedin.svg";
Expand All @@ -27,6 +27,12 @@ import Mail from "./images/mail.svg";
import Markdown from "./images/markdown.svg";
import Phone from "./images/phone.svg";

export const Constants = {
logoLinkedIn:
"data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iIzBBNjZDMiIgdmlld0JveD0iMCAwIDE2IDE2Ij4KPHBhdGggZD0iTTAgMS4xNDZDMCAuNTEzLjUyNiAwIDEuMTc1IDBoMTMuNjVDMTUuNDc0IDAgMTYgLjUxMyAxNiAxLjE0NnYxMy43MDhjMCAuNjMzLS41MjYgMS4xNDYtMS4xNzUgMS4xNDZIMS4xNzVDLjUyNiAxNiAwIDE1LjQ4NyAwIDE0Ljg1NHptNC45NDMgMTIuMjQ4VjYuMTY5SDIuNTQydjcuMjI1em0tMS4yLTguMjEyYy44MzcgMCAxLjM1OC0uNTU0IDEuMzU4LTEuMjQ4LS4wMTUtLjcwOS0uNTItMS4yNDgtMS4zNDItMS4yNDhTMi40IDMuMjI2IDIuNCAzLjkzNGMwIC42OTQuNTIxIDEuMjQ4IDEuMzI3IDEuMjQ4em00LjkwOCA4LjIxMlY5LjM1OWMwLS4yMTYuMDE2LS40MzIuMDgtLjU4Ni4xNzMtLjQzMS41NjgtLjg3OCAxLjIzMi0uODc4Ljg2OSAwIDEuMjE2LjY2MiAxLjIxNiAxLjYzNHYzLjg2NWgyLjQwMVY5LjI1YzAtMi4yMi0xLjE4NC0zLjI1Mi0yLjc2NC0zLjI1Mi0xLjI3NCAwLTEuODQ1LjctMi4xNjUgMS4xOTN2LjAyNWgtLjAxNmwuMDE2LS4wMjVWNi4xNjloLTIuNGMuMDMuNjc4IDAgNy4yMjUgMCA3LjIyNXoiLz4KPC9zdmc+Cg==",
yearsOfExperience: new Date().getFullYear() - 2018,
};

<Box
sx={{
zIndex: -1,
Expand Down Expand Up @@ -62,7 +68,7 @@ import Phone from "./images/phone.svg";

<Divider
mt={8}
css={{
sx={{
width: "66%",
}}
>
Expand All @@ -72,11 +78,11 @@ import Phone from "./images/phone.svg";
</Stack>

<Typography pt={1} variant="body1" gutterBottom textAlign="center">
Open minded developer with 4+ years of comprehensive expertise in Web App
Development with willingness to learn and master Full-stack Development. I
take great care in the code quality, readability, automator, architecture of
the things I build. I'm also an open-source enthusiast and love to collaborate
with open-source community.
Open minded Full-stack developer with {Constants.yearsOfExperience}+ years of
comprehensive expertise in Web App Development with willingness to learn and
master Gen AI development. I take great care in the code quality, readability,
automator, architecture of the things I build. I'm also an open-source
enthusiast and love to collaborate with open-source community.
</Typography>

<Typography mt={1} variant="body1" textAlign="center" gutterBottom>
Expand All @@ -94,25 +100,26 @@ import Phone from "./images/phone.svg";
<SkillBadge skill="typescript" />
<SkillBadge skill="javascript" />

<SkillBadge skill="react" />
<SkillBadge skill="redux" logoColor="#764ABC" />
<SkillBadge skill="react" />
<SkillBadge skill="redux" logoColor="#764ABC" />

<SkillBadge skill="sass" />
<SkillBadge skill="css" skillLogo="css3" logoColor="#1572B6" />
<SkillBadge skill="sass" />
<SkillBadge skill="css" skillLogo="css" logoColor="#663399" />

<SkillBadge skill="electron" />
<SkillBadge skill="node.js" skillLogo="nodedotjs" />
<SkillBadge skill="go" />
<SkillBadge skill="elixir" logoColor="#4B275F" />

<SkillBadge skill="node.js" skillLogo="nodedotjs" />
<SkillBadge skill="go" />
<SkillBadge skill="elixir" logoColor="#4B275F" />
<SkillBadge skill="graphql" logoColor="#E10098" />

<SkillBadge skill="graphql" logoColor="#E10098" />
<SkillBadge skill="mongodb" />
<SkillBadge skill="postgres" skillLogo="postgresql" />

<SkillBadge skill="mongodb" />
<SkillBadge skill="postgres" skillLogo="postgresql" />
<SkillBadge skill="docker" />
<SkillBadge skill="kubernetes" />

<SkillBadge skill="docker" />
<SkillBadge skill="kubernetes" />
<SkillBadge skill="electron" />
<SkillBadge skill="langgraph" logoColor="#1C3C3C" />

</Stack>

Expand All @@ -134,47 +141,58 @@ import Phone from "./images/phone.svg";
/>
<Connect
connect="linkedin"
connectColor="#0A66C2"
connectLogo={Constants.logoLinkedIn}
url="https://www.linkedin.com/in/ndthanhdev/"
/>
</Stack>

<Stack
direction="row"
mt={6}
mb={2}
justifyContent="center"
css={{
width: "100%",
}}
>
<Divider
textAlign="center"
css={{
width: "100%",
}}
>
##### Work experience
</Divider>
</Stack>
<CvSectionDivider>##### Work experience</CvSectionDivider>

**McKinsey & Company**

- **Software Engineer II**
_2025 Apr - Present_
- **Software Engineer I**
_2023 Nov - 2025 Apr_
- **Junior Software Engineer**
_2022 Dec - 2023 Nov_

**Zalo**

- **Senior Software Engineer**
_2021 Sep - Present_
_2021 Sep - 2022 Nov_
- **Software Engineer**
_2020 Apr - 2021 Sep_
- **Accociate Software Engineer**
_2019 Jun - 2020 Apr_

**SAP Labs Vietnam**
**SAP**

- **Accociate Software Engineer**
_2019 Jun - 2018 Sep_
- **Intern**
_2018 Jan - 2019 Jun_

##### Projects
<CvSectionDivider>##### Projects</CvSectionDivider>

**MCP Browser Kit**
_A pair of MCP server and browser extension that enables AI assistants to interact with your local browsers_

- Building an open-source Model Context Protocol (MCP) server and browser extension system with TypeScript to bridge AI assistants and web browsers
- Developing cross-browser extensions supporting Chrome, Firefox, Safari, Brave, and Edge with different extension manifest versions (M2/M3)
- Creating seamless browser automation capabilities that allow AI assistants to interact with web pages and perform browser actions

**MLR Acceleration App**
_A smart app that leverages AI to speed up Medical, Legal, and Regulatory (MLR) document reviews_

- Building a modern web app with Next.js to create an easy-to-use interface for MLR processes
- Creating interactive PDF viewing and annotation features for better document review

**Housing Super Apps - Web & Mobile**
_A housing super app that allows users to acquire and maintain their properties_

- Designing and developing cross-platform mobile applications using React Native to deliver seamless user experiences
- Implementing comprehensive authentication flows and user management systems integrated with IAM infrastructure

**Zalo - Web & PC**
_Zalo is a popular cross-platform messaging, video call app and more_
Expand All @@ -186,17 +204,17 @@ _Zalo is a popular cross-platform messaging, video call app and more_
**SAP Analytics Cloud - KPI Plugin**
_Analytics Cloud is a pluggable SaaS BI platform and KPI plugin is builder of KPIs_

- Designing and configurating bundler to publising the project as a Plugin for SAP Analytics Cloud
- Designing and configuring bundler to publishing the project as a Plugin for SAP Analytics Cloud
- Developing and writing test for new features as a part of the plugin

**SAP HANA Cockpit - Analytics Builder**
_Analytics Builder is a graphical SQL design studio to enable flexible queries on top of tables_

- Implementing Grunt task to transpile & minify that helps speed up project development and improve the load time of the web app
- Developing new and cutomizing existing features using UI5
- Developing new and customizing existing features using UI5

**Open Bucket**
_Open Bucket is an incognito P2P storage system, users are paid etherum if they share their disk space with others_
_Open Bucket is an incognito P2P storage system, users are paid Ethereum if they share their disk space with others_

- Developing Desktop app with React, Redux, Electron
- Developing Daemon, a service on the user's machine that interacts with Tracker and smart contracts, built with NodeJs, web3.js
Expand All @@ -209,7 +227,7 @@ _A combination of e-commerce website and vending machines, these components comm
- Developing a single page web app for admin and customer with Angular 2
- Developing and build a simple vending machine with Arduino and other hardwares

##### Achievements
<CvSectionDivider>##### Achievements</CvSectionDivider>

**Certificate Of Agile Software Development With Scrum**
_Axon Active Vietnam - 2016_
Expand All @@ -220,15 +238,15 @@ _Microsoft Vietnam - 2015_
**2ND Prize App Studio**
_Ton Duc Thang University & Microsoft Vietnam - 2014_

##### Education
<CvSectionDivider>##### Education</CvSectionDivider>

**BSc in Computer Science**
_Ton Duc Thang University, Ho Chi Minh - 2018_

##### Contact info
<CvSectionDivider>##### Contact info</CvSectionDivider>

<Box
css={{
sx={{
display: "grid",
gridTemplateColumns: "20px 1fr 20px 1fr",
gridAutoRows: "auto",
Expand All @@ -241,43 +259,23 @@ _Ton Duc Thang University, Ho Chi Minh - 2018_
<Typography>
{"Nguyễn Duy Thanh"}
</Typography>
<img src={Mail} />
<Typography>
{"[email protected]"}
</Typography>

<img src={Gender} />
<Typography>
{"Male"}
</Typography>

<img src={LocationOn} width="16px" />
<Typography>
{"District 7, Ho Chi Minh, Vietnam"}
</Typography>

<img src={Cake} />
<Typography>
{"1996"}
</Typography>

</Box>

<Stack
direction="row"
mt={6}
mb={2}
justifyContent="center"
css={{
width: "100%",
}}
>
<Divider
css={{
width: "100%",
}}
/>
</Stack>
<img src={Mail} />
<Typography>
{"[email protected]"}
</Typography>

<img src={Gender} />
<Typography>
{"Male"}
</Typography>

<img src={LocationOn} width="16px" />
<Typography>
{"Ho Chi Minh, Vietnam"}
</Typography>
</Box>

<CvSectionDivider />

<Stack
direction="row"
Expand Down
8 changes: 1 addition & 7 deletions apps/app/src/components/elements/shields-io/shields-io.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export const ShieldsIO = React.forwardRef<HTMLElement, ShieldsIO>(
sUrl += leftText ? `${leftText}-` : "-";
sUrl += rightText ? `${rightText}-` : "-";
sUrl += encodeURIComponent(rightBg);
logo && (sUrl += `?logo=${logo}`);

/*
* FIXME: support other extensions
Expand All @@ -65,17 +66,10 @@ export const ShieldsIO = React.forwardRef<HTMLElement, ShieldsIO>(

const url = new URL(sUrl);

logo && url.searchParams.append("logo", logo);
logoColor && url.searchParams.append("logoColor", logoColor);
logoWidth && url.searchParams.append("logoWidth", logoWidth.toString());

// Url.searchParams.set("label", leftText);
leftBg && url.searchParams.append("labelColor", leftBg);

// Url.searchParams.append("color", rightBg);

// RightText && url.searchParams.set("message", rightText);

url.searchParams.append("style", shieldStyle);

return url.toString();
Expand Down
3 changes: 1 addition & 2 deletions apps/app/src/components/fragments/app-drawer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { css } from "@emotion/react";
import CloseIcon from "@mui/icons-material/Close";
import DarkModeIcon from "@mui/icons-material/DarkModeOutlined";
import LightModeIcon from "@mui/icons-material/LightModeOutlined";
Expand Down Expand Up @@ -30,7 +29,7 @@ export const AppDrawer = ({
}: AppDrawerProps) => (
<Drawer anchor="right" css={styles.root} onClose={onClose} open={open}>
<Box css={styles.header}>
<Typography css={css({})} fontWeight="500" variant="body1">
<Typography fontWeight="500" variant="body1">
Settings
</Typography>
<IconButton color="inherit" edge="end" onClick={onClose}>
Expand Down
25 changes: 25 additions & 0 deletions apps/app/src/components/fragments/cv-section-divider/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Divider from "@mui/material/Divider";
import Stack from "@mui/material/Stack";
import { type ReactNode } from "react";

import { styles } from "./styles";

export interface CvSectionDividerProps {
children?: ReactNode;
}

export const CvSectionDivider = ({ children }: CvSectionDividerProps) => {
return (
<Stack
css={styles.stack}
direction="row"
justifyContent="center"
mb={2}
mt={6}
>
<Divider css={styles.divider} textAlign="center">
{children}
</Divider>
</Stack>
);
};
11 changes: 11 additions & 0 deletions apps/app/src/components/fragments/cv-section-divider/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { css } from "@emotion/react";

export const styles = {
divider: css({
width: "100%",
}),

stack: css({
width: "100%",
}),
};
Loading