Skip to content

Commit fea287e

Browse files
committed
feat: enhance CV component with new sections and dynamic experience calculation
1 parent 5b822bd commit fea287e

File tree

7 files changed

+150
-119
lines changed

7 files changed

+150
-119
lines changed

apps/app/content/cv/cv.mdx

Lines changed: 84 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ import Chip from '@mui/material/Chip';
1414
import Typography from '@mui/material/Typography';
1515
import { SkillBadge } from "@n8v/app/components/elements/shields-io/variants/skill-badge";
1616
import { Connect } from "@n8v/app/components/elements/shields-io/variants/connect";
17+
import { CvSectionDivider } from "@n8v/app/components/fragments/cv-section-divider";
1718
import Grid from '@mui/material/Unstable_Grid2';
1819
import Link from '@mui/material/Link';
1920

2021
import PermIdentity from "./images/perm_identity.svg";
21-
import Cake from "./images/cake.svg";
2222
import Gender from "./images/gender.svg";
2323
import Github from "./images/github.svg";
2424
import LinkedIn from "./images/linkedin.svg";
@@ -27,6 +27,12 @@ import Mail from "./images/mail.svg";
2727
import Markdown from "./images/markdown.svg";
2828
import Phone from "./images/phone.svg";
2929

30+
export const Constants = {
31+
logoLinkedIn:
32+
"data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iIzBBNjZDMiIgdmlld0JveD0iMCAwIDE2IDE2Ij4KPHBhdGggZD0iTTAgMS4xNDZDMCAuNTEzLjUyNiAwIDEuMTc1IDBoMTMuNjVDMTUuNDc0IDAgMTYgLjUxMyAxNiAxLjE0NnYxMy43MDhjMCAuNjMzLS41MjYgMS4xNDYtMS4xNzUgMS4xNDZIMS4xNzVDLjUyNiAxNiAwIDE1LjQ4NyAwIDE0Ljg1NHptNC45NDMgMTIuMjQ4VjYuMTY5SDIuNTQydjcuMjI1em0tMS4yLTguMjEyYy44MzcgMCAxLjM1OC0uNTU0IDEuMzU4LTEuMjQ4LS4wMTUtLjcwOS0uNTItMS4yNDgtMS4zNDItMS4yNDhTMi40IDMuMjI2IDIuNCAzLjkzNGMwIC42OTQuNTIxIDEuMjQ4IDEuMzI3IDEuMjQ4em00LjkwOCA4LjIxMlY5LjM1OWMwLS4yMTYuMDE2LS40MzIuMDgtLjU4Ni4xNzMtLjQzMS41NjgtLjg3OCAxLjIzMi0uODc4Ljg2OSAwIDEuMjE2LjY2MiAxLjIxNiAxLjYzNHYzLjg2NWgyLjQwMVY5LjI1YzAtMi4yMi0xLjE4NC0zLjI1Mi0yLjc2NC0zLjI1Mi0xLjI3NCAwLTEuODQ1LjctMi4xNjUgMS4xOTN2LjAyNWgtLjAxNmwuMDE2LS4wMjVWNi4xNjloLTIuNGMuMDMuNjc4IDAgNy4yMjUgMCA3LjIyNXoiLz4KPC9zdmc+Cg==",
33+
yearsOfExperience: new Date().getFullYear() - 2018,
34+
};
35+
3036
<Box
3137
sx={{
3238
zIndex: -1,
@@ -62,7 +68,7 @@ import Phone from "./images/phone.svg";
6268

6369
<Divider
6470
mt={8}
65-
css={{
71+
sx={{
6672
width: "66%",
6773
}}
6874
>
@@ -72,11 +78,11 @@ import Phone from "./images/phone.svg";
7278
</Stack>
7379

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

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

97-
<SkillBadge skill="react" />
98-
<SkillBadge skill="redux" logoColor="#764ABC" />
103+
<SkillBadge skill="react" />
104+
<SkillBadge skill="redux" logoColor="#764ABC" />
99105

100-
<SkillBadge skill="sass" />
101-
<SkillBadge skill="css" skillLogo="css3" logoColor="#1572B6" />
106+
<SkillBadge skill="sass" />
107+
<SkillBadge skill="css" skillLogo="css" logoColor="#663399" />
102108

103-
<SkillBadge skill="electron" />
109+
<SkillBadge skill="node.js" skillLogo="nodedotjs" />
110+
<SkillBadge skill="go" />
111+
<SkillBadge skill="elixir" logoColor="#4B275F" />
104112

105-
<SkillBadge skill="node.js" skillLogo="nodedotjs" />
106-
<SkillBadge skill="go" />
107-
<SkillBadge skill="elixir" logoColor="#4B275F" />
113+
<SkillBadge skill="graphql" logoColor="#E10098" />
108114

109-
<SkillBadge skill="graphql" logoColor="#E10098" />
115+
<SkillBadge skill="mongodb" />
116+
<SkillBadge skill="postgres" skillLogo="postgresql" />
110117

111-
<SkillBadge skill="mongodb" />
112-
<SkillBadge skill="postgres" skillLogo="postgresql" />
118+
<SkillBadge skill="docker" />
119+
<SkillBadge skill="kubernetes" />
113120

114-
<SkillBadge skill="docker" />
115-
<SkillBadge skill="kubernetes" />
121+
<SkillBadge skill="electron" />
122+
<SkillBadge skill="langgraph" logoColor="#1C3C3C" />
116123

117124
</Stack>
118125

@@ -134,47 +141,58 @@ import Phone from "./images/phone.svg";
134141
/>
135142
<Connect
136143
connect="linkedin"
137-
connectColor="#0A66C2"
144+
connectLogo={Constants.logoLinkedIn}
138145
url="https://www.linkedin.com/in/ndthanhdev/"
139146
/>
140147
</Stack>
141148

142-
<Stack
143-
direction="row"
144-
mt={6}
145-
mb={2}
146-
justifyContent="center"
147-
css={{
148-
width: "100%",
149-
}}
150-
>
151-
<Divider
152-
textAlign="center"
153-
css={{
154-
width: "100%",
155-
}}
156-
>
157-
##### Work experience
158-
</Divider>
159-
</Stack>
149+
<CvSectionDivider>##### Work experience</CvSectionDivider>
150+
151+
**McKinsey & Company**
152+
153+
- **Software Engineer II**
154+
_2025 Apr - Present_
155+
- **Software Engineer I**
156+
_2023 Nov - 2025 Apr_
157+
- **Junior Software Engineer**
158+
_2022 Dec - 2023 Nov_
160159

161160
**Zalo**
162161

163162
- **Senior Software Engineer**
164-
_2021 Sep - Present_
163+
_2021 Sep - 2022 Nov_
165164
- **Software Engineer**
166165
_2020 Apr - 2021 Sep_
167166
- **Accociate Software Engineer**
168167
_2019 Jun - 2020 Apr_
169168

170-
**SAP Labs Vietnam**
169+
**SAP**
171170

172171
- **Accociate Software Engineer**
173172
_2019 Jun - 2018 Sep_
174173
- **Intern**
175174
_2018 Jan - 2019 Jun_
176175

177-
##### Projects
176+
<CvSectionDivider>##### Projects</CvSectionDivider>
177+
178+
**MCP Browser Kit**
179+
_A pair of MCP server and browser extension that enables AI assistants to interact with your local browsers_
180+
181+
- Building an open-source Model Context Protocol (MCP) server and browser extension system with TypeScript to bridge AI assistants and web browsers
182+
- Developing cross-browser extensions supporting Chrome, Firefox, Safari, Brave, and Edge with different extension manifest versions (M2/M3)
183+
- Creating seamless browser automation capabilities that allow AI assistants to interact with web pages and perform browser actions
184+
185+
**MLR Acceleration App**
186+
_A smart app that leverages AI to speed up Medical, Legal, and Regulatory (MLR) document reviews_
187+
188+
- Building a modern web app with Next.js to create an easy-to-use interface for MLR processes
189+
- Creating interactive PDF viewing and annotation features for better document review
190+
191+
**Housing Super Apps - Web & Mobile**
192+
_A housing super app that allows users to acquire and maintain their properties_
193+
194+
- Designing and developing cross-platform mobile applications using React Native to deliver seamless user experiences
195+
- Implementing comprehensive authentication flows and user management systems integrated with IAM infrastructure
178196

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

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

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

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

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

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

212-
##### Achievements
230+
<CvSectionDivider>##### Achievements</CvSectionDivider>
213231

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

223-
##### Education
241+
<CvSectionDivider>##### Education</CvSectionDivider>
224242

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

228-
##### Contact info
246+
<CvSectionDivider>##### Contact info</CvSectionDivider>
229247

230248
<Box
231-
css={{
249+
sx={{
232250
display: "grid",
233251
gridTemplateColumns: "20px 1fr 20px 1fr",
234252
gridAutoRows: "auto",
@@ -241,43 +259,23 @@ _Ton Duc Thang University, Ho Chi Minh - 2018_
241259
<Typography>
242260
{"Nguyễn Duy Thanh"}
243261
</Typography>
244-
<img src={Mail} />
245-
<Typography>
246-
{"ndthanhdev@outlook.com"}
247-
</Typography>
248-
249-
<img src={Gender} />
250-
<Typography>
251-
{"Male"}
252-
</Typography>
253-
254-
<img src={LocationOn} width="16px" />
255-
<Typography>
256-
{"District 7, Ho Chi Minh, Vietnam"}
257-
</Typography>
258-
259-
<img src={Cake} />
260-
<Typography>
261-
{"1996"}
262-
</Typography>
263-
264-
</Box>
265-
266-
<Stack
267-
direction="row"
268-
mt={6}
269-
mb={2}
270-
justifyContent="center"
271-
css={{
272-
width: "100%",
273-
}}
274-
>
275-
<Divider
276-
css={{
277-
width: "100%",
278-
}}
279-
/>
280-
</Stack>
262+
<img src={Mail} />
263+
<Typography>
264+
{"ndthanhdev@outlook.com"}
265+
</Typography>
266+
267+
<img src={Gender} />
268+
<Typography>
269+
{"Male"}
270+
</Typography>
271+
272+
<img src={LocationOn} width="16px" />
273+
<Typography>
274+
{"Ho Chi Minh, Vietnam"}
275+
</Typography>
276+
</Box>
277+
278+
<CvSectionDivider />
281279

282280
<Stack
283281
direction="row"

apps/app/src/components/elements/shields-io/shields-io.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export const ShieldsIO = React.forwardRef<HTMLElement, ShieldsIO>(
5757
sUrl += leftText ? `${leftText}-` : "-";
5858
sUrl += rightText ? `${rightText}-` : "-";
5959
sUrl += encodeURIComponent(rightBg);
60+
logo && (sUrl += `?logo=${logo}`);
6061

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

6667
const url = new URL(sUrl);
6768

68-
logo && url.searchParams.append("logo", logo);
6969
logoColor && url.searchParams.append("logoColor", logoColor);
7070
logoWidth && url.searchParams.append("logoWidth", logoWidth.toString());
71-
72-
// Url.searchParams.set("label", leftText);
7371
leftBg && url.searchParams.append("labelColor", leftBg);
7472

75-
// Url.searchParams.append("color", rightBg);
76-
77-
// RightText && url.searchParams.set("message", rightText);
78-
7973
url.searchParams.append("style", shieldStyle);
8074

8175
return url.toString();

apps/app/src/components/fragments/app-drawer/index.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { css } from "@emotion/react";
21
import CloseIcon from "@mui/icons-material/Close";
32
import DarkModeIcon from "@mui/icons-material/DarkModeOutlined";
43
import LightModeIcon from "@mui/icons-material/LightModeOutlined";
@@ -30,7 +29,7 @@ export const AppDrawer = ({
3029
}: AppDrawerProps) => (
3130
<Drawer anchor="right" css={styles.root} onClose={onClose} open={open}>
3231
<Box css={styles.header}>
33-
<Typography css={css({})} fontWeight="500" variant="body1">
32+
<Typography fontWeight="500" variant="body1">
3433
Settings
3534
</Typography>
3635
<IconButton color="inherit" edge="end" onClick={onClose}>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import Divider from "@mui/material/Divider";
2+
import Stack from "@mui/material/Stack";
3+
import React, { type ReactNode } from "react";
4+
5+
import { styles } from "./styles";
6+
7+
export interface CvSectionDividerProps {
8+
children?: ReactNode;
9+
}
10+
11+
export const CvSectionDivider = ({ children }: CvSectionDividerProps) => {
12+
return (
13+
<Stack
14+
css={styles.stack}
15+
direction="row"
16+
justifyContent="center"
17+
mb={2}
18+
mt={6}
19+
>
20+
<Divider css={styles.divider} textAlign="center">
21+
{children}
22+
</Divider>
23+
</Stack>
24+
);
25+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { css } from "@emotion/react";
2+
3+
export const styles = {
4+
divider: css({
5+
width: "100%",
6+
}),
7+
8+
stack: css({
9+
width: "100%",
10+
}),
11+
};

0 commit comments

Comments
 (0)