diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx
index a7d7e74..678fd44 100644
--- a/src/components/layout/Layout.tsx
+++ b/src/components/layout/Layout.tsx
@@ -1,23 +1,23 @@
-import React from 'react';
-import { Box, Center, HStack, Link, Text, VStack } from '@chakra-ui/react';
+import { ReactNode } from 'react';
+import { Box, Center, HStack, Icon, Link, Spacer, VStack } from '@chakra-ui/react';
+import { FiExternalLink } from 'react-icons/fi';
import NavLink from './NavLink';
-const Layout = (props: { children: React.ReactNode }) => (
-
+const Layout = (props: { children: ReactNode }) => (
+
-
+
home
cv
+
+
+ source code
+
+
{props.children}
-
- Source code of this website is available at{' '}
-
- GitHub
-
-
);
diff --git a/src/i18n.ts b/src/i18n.ts
index e87ccae..f96f7e6 100644
--- a/src/i18n.ts
+++ b/src/i18n.ts
@@ -8,6 +8,7 @@ import soft_skills from './pages/cv/data/soft_skills';
import summary from './pages/cv/data/summary';
import info from './pages/cv/data/info';
import tech_skills from './pages/cv/data/tech_skills';
+import publications from './pages/cv/data/publications';
i18n.use(initReactI18next).init({
resources: {
@@ -36,6 +37,11 @@ i18n.use(initReactI18next).init({
content: projects.en,
},
+ publications: {
+ title: 'Publications',
+ content: publications.en,
+ },
+
tech_skills: {
title: 'Technical skills',
languages: 'Programming languages',
@@ -98,6 +104,11 @@ i18n.use(initReactI18next).init({
content: education.ru,
},
+ publications: {
+ title: 'Публикации',
+ content: publications.ru,
+ },
+
languages: {
title: 'Языки',
content: languages.ru,
diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx
index 68ea36a..746c5df 100644
--- a/src/pages/Home.tsx
+++ b/src/pages/Home.tsx
@@ -1,5 +1,4 @@
-import { Link as RouteLink } from 'react-router-dom';
-import { Text, Heading, Link, Box } from '@chakra-ui/react';
+import { Text, Heading, Link, Box, ListItem, UnorderedList } from '@chakra-ui/react';
import Layout from '../components/layout/Layout';
const Home = () => (
@@ -12,8 +11,8 @@ const Home = () => (
{' '}
here.
-
- Who?
+
+ About me
@@ -24,19 +23,38 @@ const Home = () => (
My real name is Vladislav Safonov, I am a software developer. In 2023, I finished my
bachelor's degree at{' '}
- Innopolis University.
+
+ Innopolis University
+
+ .
-
- So?
-
- Originally this site is meant to hold my{' '}
-
- CV
- {' '}
- written in React.
+ By the way, I made my thesis publicly available at{' '}
+
+ ResearchGate
+
+ .
- Probably, I will add more stuff here later, we'll see.
+
+ Links
+
+
+
+
+ telegram
+
+
+
+
+ telegram channel (ru)
+
+
+
+
+ github profile
+
+
+
);
diff --git a/src/pages/cv/CVDocument.tsx b/src/pages/cv/CVDocument.tsx
index b1d8fb7..ce0a7e5 100644
--- a/src/pages/cv/CVDocument.tsx
+++ b/src/pages/cv/CVDocument.tsx
@@ -32,6 +32,7 @@ import type { LanguageProficiency } from './data/languages';
import type { WorkEntryId, WorkExperience } from './data/work';
import type { Education, EducationId } from './data/education';
import type { ProgrammingLanguageId, TechSkillId } from './data/tech_skills';
+import { Publication, PublicationId } from './data/publications';
const CVDocument = () => {
const [allTags, setTags] = useState>(new Set(['Frontend', 'Backend']));
@@ -58,7 +59,7 @@ const CVDocument = () => {
const tagsContextValue = useMemo(() => ({ tags: allTags, pushTag }), [pushTag, allTags]);
return (
-
+
{
align="center"
spacing="0"
>
-
+
{t('info.cv_name')}
@@ -159,7 +164,7 @@ const CVDocument = () => {
).map(([id, project]) => (
-
+
{project.name}
@@ -174,6 +179,28 @@ const CVDocument = () => {
))}
+
+
+ {Object.entries(
+ t('sections.publications.content', { returnObjects: true }) as Record<
+ PublicationId,
+ Publication
+ >,
+ ).map(([id, publication]) => (
+
+
+
+
+ {publication.name}
+
+
+ {publication.type}
+ {publication.date}
+
+
+ ))}
+
+
diff --git a/src/pages/cv/components/tags/Tag.tsx b/src/pages/cv/components/tags/Tag.tsx
index ee89474..baa5cee 100644
--- a/src/pages/cv/components/tags/Tag.tsx
+++ b/src/pages/cv/components/tags/Tag.tsx
@@ -44,6 +44,7 @@ const Tag = ({
fontWeight={isSelected ? 'bold' : 'normal'}
color={isSelected ? 'blue.800' : undefined}
textDecoration="underline dotted 1px"
+ textAlign="center"
as={RouteLink}
to={target}
>
diff --git a/src/pages/cv/data/education.ts b/src/pages/cv/data/education.ts
index b5a3cd1..6b05adf 100644
--- a/src/pages/cv/data/education.ts
+++ b/src/pages/cv/data/education.ts
@@ -14,7 +14,7 @@ const education = merge({
iu: {
specialty: 'Computer science, Bachelor',
organization: 'Innopolis University',
- period: '2021 — 2023',
+ period: '2019 — 2023',
},
},
ru: {
diff --git a/src/pages/cv/data/publications.ts b/src/pages/cv/data/publications.ts
new file mode 100644
index 0000000..ecf2722
--- /dev/null
+++ b/src/pages/cv/data/publications.ts
@@ -0,0 +1,31 @@
+import merge from './merge';
+
+export interface Publication {
+ name: string;
+ type: string;
+ date: string;
+ url: string;
+}
+
+const publication_ids = ['kiosk'] as const;
+export type PublicationId = (typeof publication_ids)[number];
+
+const publications = merge({
+ en: {
+ kiosk: {
+ name: 'Development of software for an interactive information kiosk',
+ url: 'https://dx.doi.org/10.13140/RG.2.2.24800.25609',
+ type: "Bachelor's Thesis",
+ date: 'July 2023',
+ },
+ },
+ ru: {
+ kiosk: {
+ name: 'Разработка программного обеспечения для информационного киоска',
+ type: 'Бакалаврская работа',
+ date: 'Июль 2023',
+ },
+ },
+});
+
+export default publications;
diff --git a/src/pages/cv/data/tech_skills.ts b/src/pages/cv/data/tech_skills.ts
index a8f5289..919e74f 100644
--- a/src/pages/cv/data/tech_skills.ts
+++ b/src/pages/cv/data/tech_skills.ts
@@ -9,8 +9,8 @@ export type TechSkillId = (typeof tech_skill_ids)[number];
const tech_skills = merge({
en: {
languages: {
- python: 'Python: , pandas, numpy',
js: 'JS: TypeScript, , , Vite',
+ python: 'Python: , pandas, numpy',
csharp: 'C#: WPF, WinForms',
},
other: {