diff --git a/components/Button.stories.tsx b/components/Button.stories.tsx
deleted file mode 100644
index a24a18b..0000000
--- a/components/Button.stories.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import { storiesOf } from "@storybook/react";
-import Button from "./Button";
-
-storiesOf("Button", module).add("with text", () => {
- return ;
-});
-
-storiesOf("Button", module).add("with emoji", () => {
- return ;
-});
\ No newline at end of file
diff --git a/components/Button.tsx b/components/Button.tsx
deleted file mode 100644
index a8a3ad2..0000000
--- a/components/Button.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import * as React from 'react';
-
-type Props = {
- text: string;
-};
-
-export default ({ text }: Props) => ;
diff --git a/components/Footer.tsx b/components/Footer.tsx
new file mode 100644
index 0000000..3e6b4ac
--- /dev/null
+++ b/components/Footer.tsx
@@ -0,0 +1,14 @@
+import * as React from 'react';
+
+type Props = {};
+
+export default ({}: Props) => (
+
+);
diff --git a/components/atom/Button.stories.tsx b/components/atom/Button.stories.tsx
new file mode 100644
index 0000000..d1956ae
--- /dev/null
+++ b/components/atom/Button.stories.tsx
@@ -0,0 +1,10 @@
+import { storiesOf } from '@storybook/react';
+import Button from './Button';
+
+storiesOf('Design System/Atoms/Button', module).add('with text', () => {
+ return ;
+});
+
+storiesOf('Design System/Atoms/Button', module).add('with emoji', () => {
+ return ;
+});
diff --git a/components/atom/Button.tsx b/components/atom/Button.tsx
new file mode 100644
index 0000000..d93ae45
--- /dev/null
+++ b/components/atom/Button.tsx
@@ -0,0 +1,11 @@
+import * as React from 'react';
+
+type Props = {
+ text: string;
+};
+
+export default ({ text }: Props) => (
+
+);
diff --git a/components/personal-card/PersonalCard.stories.tsx b/components/personal-card/PersonalCard.stories.tsx
new file mode 100644
index 0000000..42c5367
--- /dev/null
+++ b/components/personal-card/PersonalCard.stories.tsx
@@ -0,0 +1,6 @@
+import { storiesOf } from '@storybook/react';
+import PersonalCard from './PersonalCard';
+
+storiesOf('Components/Personal Card', module).add('with emoji', () => {
+ return ;
+});
diff --git a/components/personal-card/PersonalCard.tsx b/components/personal-card/PersonalCard.tsx
new file mode 100644
index 0000000..2c4005c
--- /dev/null
+++ b/components/personal-card/PersonalCard.tsx
@@ -0,0 +1,16 @@
+import * as React from 'react';
+import Avatar from './elements/Avatar';
+import Contacts from './elements/Contacts';
+import Description from './elements/Description';
+import Title from './elements/Title';
+
+type Props = {};
+
+export default ({}: Props) => (
+
+);
diff --git a/components/personal-card/elements/Avatar.tsx b/components/personal-card/elements/Avatar.tsx
new file mode 100644
index 0000000..d8bea81
--- /dev/null
+++ b/components/personal-card/elements/Avatar.tsx
@@ -0,0 +1,9 @@
+import * as React from 'react';
+
+type Props = {
+ imgUrl: string;
+};
+
+export default ({ imgUrl }: Props) => (
+
+);
diff --git a/components/personal-card/elements/Contacts.tsx b/components/personal-card/elements/Contacts.tsx
new file mode 100644
index 0000000..6b137f6
--- /dev/null
+++ b/components/personal-card/elements/Contacts.tsx
@@ -0,0 +1,30 @@
+import * as React from 'react';
+import { Contact, ContactType } from '../../../src/contacts/contacts';
+
+import ContactsButtons from './ContactsButtons';
+
+type Props = {};
+const contactMe: Contact[] = [
+ { id: 'fido_node', type: 'tg' },
+ { id: 'aleksandr.mihailov@pm.me', type: 'mail' }
+];
+
+const socialButtons: Contact[] = [
+ { id: 'fido_node', type: 'twitter' },
+ { id: 'michey', type: 'github' },
+ { id: 'alex-mihailov-870448187', type: 'linkedin' },
+ { id: 'fido_node', type: 'twitch' }
+];
+
+export default ({}: Props) => (
+ <>
+
+ Contact me via:
+
+
+
+ Social buttons:
+
+
+ >
+);
diff --git a/components/personal-card/elements/ContactsButtons.tsx b/components/personal-card/elements/ContactsButtons.tsx
new file mode 100644
index 0000000..c4b5799
--- /dev/null
+++ b/components/personal-card/elements/ContactsButtons.tsx
@@ -0,0 +1,43 @@
+import * as React from 'react';
+import '@fortawesome/fontawesome-svg-core';
+import { faEnvelope } from '@fortawesome/free-solid-svg-icons';
+import {
+ faTelegram,
+ faTwitter,
+ faGithub,
+ faLinkedin,
+ faTwitch
+} from '@fortawesome/free-brands-svg-icons';
+
+import { IconDefinition, IconName, IconPrefix } from '@fortawesome/fontawesome-svg-core';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Contact, contactToLink, ContactType } from '../../../src/contacts/contacts';
+
+type Props = {
+ contacts: Contact[];
+};
+
+const typeToIcon: { [key in ContactType]: [IconDefinition, string?] } = {
+ tg: [faTelegram],
+ mail: [faEnvelope],
+ twitter: [faTwitter],
+ github: [faGithub],
+ linkedin: [faLinkedin],
+ twitch: [faTwitch]
+};
+
+const ContactComp = ({ id, type }: Contact) => {
+ const iconDescr = typeToIcon[type];
+ return (
+
+
+
+ );
+};
+
+export default ({ contacts }: Props) => (
+ {contacts.map((c) => ContactComp(c))}
+);
diff --git a/components/personal-card/elements/Description.tsx b/components/personal-card/elements/Description.tsx
new file mode 100644
index 0000000..8f77653
--- /dev/null
+++ b/components/personal-card/elements/Description.tsx
@@ -0,0 +1,21 @@
+import * as React from 'react';
+import Link from './Link';
+
+type Props = {};
+
+export default ({}: Props) => (
+
+ Full stack engineer
+
+ FP-curious | λ-affected Wanna be rustacean 🦀 and/or secops guy 🔒
+
+
+ Now @SamsungNEXT (
+ Whisk product team). Previously{' '}
+ @VisualThreat.
+
+
+ Work with: Scala, TypeScript, Java, MongoDB, MySQL, Thrift, gRPC
+
+
+);
diff --git a/components/personal-card/elements/Link.tsx b/components/personal-card/elements/Link.tsx
new file mode 100644
index 0000000..774121b
--- /dev/null
+++ b/components/personal-card/elements/Link.tsx
@@ -0,0 +1,12 @@
+import * as React from 'react';
+
+type Props = {
+ href: string;
+ children: string;
+};
+
+export default ({ href, children }: Props) => (
+
+ {children}
+
+);
diff --git a/components/personal-card/elements/Title.tsx b/components/personal-card/elements/Title.tsx
new file mode 100644
index 0000000..9f18cee
--- /dev/null
+++ b/components/personal-card/elements/Title.tsx
@@ -0,0 +1,9 @@
+import * as React from 'react';
+
+type Props = {};
+
+export default ({}: Props) => (
+
+ {'Alex Mihailov'}
+
+);
diff --git a/package.json b/package.json
index fe66f9a..5f96af7 100644
--- a/package.json
+++ b/package.json
@@ -7,16 +7,21 @@
"export": "next build && next export",
"build": "next build",
"start": "next start",
- "storybook": "start-storybook -p 6006",
+ "storybook": "start-storybook -s ./public -p 6006 ",
"build-storybook": "build-storybook"
},
"dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^1.2.35",
+ "@fortawesome/free-brands-svg-icons": "^5.15.3",
+ "@fortawesome/free-solid-svg-icons": "^5.15.3",
+ "@fortawesome/react-fontawesome": "^0.1.14",
"next": "^10.1.0",
"react": "17.0.1",
"react-dom": "17.0.1"
},
"devDependencies": {
"@babel/core": "^7.13.16",
+ "@fortawesome/fontawesome-free": "^5.15.3",
"@storybook/addon-actions": "^6.2.0",
"@storybook/addon-essentials": "^6.2.0",
"@storybook/addon-links": "^6.2.0",
diff --git a/pages/index.tsx b/pages/index.tsx
index ce8ecd7..35cc3fa 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -1,7 +1,14 @@
-import * as React from "react";
+import * as React from 'react';
+import Footer from '../components/Footer';
+import PersonalCard from '../components/personal-card/PersonalCard';
const Home = () => {
- return Welcome to My Next App!
;
+ return (
+
+ );
};
-export default Home;
\ No newline at end of file
+export default Home;
diff --git a/public/avatar.jpg b/public/avatar.jpg
new file mode 100644
index 0000000..b79976a
Binary files /dev/null and b/public/avatar.jpg differ
diff --git a/src/contacts/contacts.ts b/src/contacts/contacts.ts
new file mode 100644
index 0000000..c02d046
--- /dev/null
+++ b/src/contacts/contacts.ts
@@ -0,0 +1,23 @@
+import Contacts from '../../components/personal-card/elements/Contacts';
+
+export type ContactType = 'tg' | 'mail' | 'twitter' | 'github' | 'linkedin' | 'twitch';
+
+export interface Contact {
+ id: string;
+ type: ContactType;
+}
+
+type MapType = { [key in ContactType]: (id: string) => string };
+
+const typeToFormer: MapType = {
+ tg: (id) => `https://t.me/${id}`,
+ mail: (id) => `mailto:${id}`,
+ twitter: (id) => `https://twitter.com/${id}`,
+ github: (id) => `https://github.com/${id}`,
+ linkedin: (id) => `https://linkedin.com/in/${id}`,
+ twitch: (id) => `https://www.twitch.tv/${id}`
+};
+
+export function contactToLink(contact: Contact): string {
+ return typeToFormer[contact.type](contact.id);
+}
diff --git a/tsconfig.json b/tsconfig.json
index 26a5296..80e21be 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,11 +1,7 @@
{
"compilerOptions": {
"target": "es5",
- "lib": [
- "dom",
- "dom.iterable",
- "esnext"
- ],
+ "lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
@@ -18,13 +14,7 @@
"isolatedModules": true,
"jsx": "preserve"
},
- "include": [
- "next-env.d.ts",
- "**/*.ts",
- "**/*.tsx"
- ],
- "exclude": [
- "node_modules"
- ],
- "baseUrl": "./",
-}
\ No newline at end of file
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules"],
+ "baseUrl": "./"
+}
diff --git a/yarn.lock b/yarn.lock
index fb410aa..e46b1b4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1212,6 +1212,44 @@
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46"
integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==
+"@fortawesome/fontawesome-common-types@^0.2.35":
+ version "0.2.35"
+ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz#01dd3d054da07a00b764d78748df20daf2b317e9"
+ integrity sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw==
+
+"@fortawesome/fontawesome-free@^5.15.3":
+ version "5.15.3"
+ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.3.tgz#c36ffa64a2a239bf948541a97b6ae8d729e09a9a"
+ integrity sha512-rFnSUN/QOtnOAgqFRooTA3H57JLDm0QEG/jPdk+tLQNL/eWd+Aok8g3qCI+Q1xuDPWpGW/i9JySpJVsq8Q0s9w==
+
+"@fortawesome/fontawesome-svg-core@^1.2.35":
+ version "1.2.35"
+ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz#85aea8c25645fcec88d35f2eb1045c38d3e65cff"
+ integrity sha512-uLEXifXIL7hnh2sNZQrIJWNol7cTVIzwI+4qcBIq9QWaZqUblm0IDrtSqbNg+3SQf8SMGHkiSigD++rHmCHjBg==
+ dependencies:
+ "@fortawesome/fontawesome-common-types" "^0.2.35"
+
+"@fortawesome/free-brands-svg-icons@^5.15.3":
+ version "5.15.3"
+ resolved "https://registry.yarnpkg.com/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.15.3.tgz#bec2821d23b9c667be1d192a6c5bfb2667e588eb"
+ integrity sha512-1hirPcbjj72ZJtFvdnXGPbAbpn3Ox6mH3g5STbANFp3vGSiE5u5ingAKV06mK6ZVqNYxUPlh4DlTnaIvLtF2kw==
+ dependencies:
+ "@fortawesome/fontawesome-common-types" "^0.2.35"
+
+"@fortawesome/free-solid-svg-icons@^5.15.3":
+ version "5.15.3"
+ resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz#52eebe354f60dc77e0bde934ffc5c75ffd04f9d8"
+ integrity sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q==
+ dependencies:
+ "@fortawesome/fontawesome-common-types" "^0.2.35"
+
+"@fortawesome/react-fontawesome@^0.1.14":
+ version "0.1.14"
+ resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz#bf28875c3935b69ce2dc620e1060b217a47f64ca"
+ integrity sha512-4wqNb0gRLVaBm/h+lGe8UfPPivcbuJ6ecI4hIgW0LjI7kzpYB9FkN0L9apbVzg+lsBdcTf0AlBtODjcSX5mmKA==
+ dependencies:
+ prop-types "^15.7.2"
+
"@fullhuman/postcss-purgecss@^3.1.3":
version "3.1.3"
resolved "https://registry.yarnpkg.com/@fullhuman/postcss-purgecss/-/postcss-purgecss-3.1.3.tgz#47af7b87c9bfb3de4bc94a38f875b928fffdf339"