This commit is contained in:
Keroosha 2023-06-13 21:51:47 +03:00
parent 4f2bc74ed2
commit fe1b5b2f4e
16 changed files with 629 additions and 124 deletions

View File

@ -0,0 +1,13 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/modules.xml
/projectSettingsUpdater.xml
/.idea.keroosha-landing.iml
/contentModel.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -0,0 +1,58 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<HTMLCodeStyleSettings>
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
<option name="HTML_ENFORCE_QUOTES" value="true" />
</HTMLCodeStyleSettings>
<JSCodeStyleSettings version="0">
<option name="FORCE_SEMICOLON_STYLE" value="true" />
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
<option name="FORCE_QUOTE_STYlE" value="true" />
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
<option name="SPACES_WITHIN_IMPORTS" value="true" />
</JSCodeStyleSettings>
<TypeScriptCodeStyleSettings version="0">
<option name="FORCE_SEMICOLON_STYLE" value="true" />
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
<option name="FORCE_QUOTE_STYlE" value="true" />
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
<option name="SPACES_WITHIN_IMPORTS" value="true" />
</TypeScriptCodeStyleSettings>
<VueCodeStyleSettings>
<option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
<option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
</VueCodeStyleSettings>
<codeStyleSettings language="HTML">
<option name="SOFT_MARGINS" value="120" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="SOFT_MARGINS" value="120" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="TypeScript">
<option name="SOFT_MARGINS" value="120" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="Vue">
<option name="SOFT_MARGINS" value="120" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<includedPredefinedLibrary name="Node.js Core" />
</component>
</project>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PrettierConfiguration">
<option name="myConfigurationMode" value="AUTOMATIC" />
<option name="myRunOnSave" value="true" />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

3
.prettierrc.json Normal file
View File

@ -0,0 +1,3 @@
{
"printWidth": 120
}

28
package-lock.json generated
View File

@ -8,6 +8,7 @@
"name": "keroosha-landing", "name": "keroosha-landing",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "6.4.0",
"@types/node": "20.3.1", "@types/node": "20.3.1",
"@types/react": "18.2.12", "@types/react": "18.2.12",
"@types/react-dom": "18.2.5", "@types/react-dom": "18.2.5",
@ -18,6 +19,9 @@
"react-dom": "18.2.0", "react-dom": "18.2.0",
"tailwindcss": "3.3.2", "tailwindcss": "3.3.2",
"typescript": "5.1.3" "typescript": "5.1.3"
},
"devDependencies": {
"prettier": "2.8.8"
} }
}, },
"node_modules/@alloc/quick-lru": { "node_modules/@alloc/quick-lru": {
@ -31,6 +35,15 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/@fortawesome/fontawesome-free": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.4.0.tgz",
"integrity": "sha512-0NyytTlPJwB/BF5LtRV8rrABDbe3TdTXqNB3PdZ+UUUZAEIrdOJdmABqKjt4AXwIoJNaRVVZEXxpNrqvE1GAYQ==",
"hasInstallScript": true,
"engines": {
"node": ">=6"
}
},
"node_modules/@jridgewell/gen-mapping": { "node_modules/@jridgewell/gen-mapping": {
"version": "0.3.3", "version": "0.3.3",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
@ -1118,6 +1131,21 @@
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
}, },
"node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/queue-microtask": { "node_modules/queue-microtask": {
"version": "1.2.3", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",

View File

@ -8,7 +8,11 @@
"start": "next start", "start": "next start",
"lint": "next lint" "lint": "next lint"
}, },
"devDependencies": {
"prettier": "2.8.8"
},
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "6.4.0",
"@types/node": "20.3.1", "@types/node": "20.3.1",
"@types/react": "18.2.12", "@types/react": "18.2.12",
"@types/react-dom": "18.2.5", "@types/react-dom": "18.2.5",

View File

@ -1,27 +1,305 @@
@import "@fortawesome/fontawesome-free/css/fontawesome.css";
@import "@fortawesome/fontawesome-free/css/brands.css";
@import "@fortawesome/fontawesome-free/css/solid.css";
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
:root { /* https://github.com/cat-street/deus-ex-ebook/blob/master/deusexpad.css */
--foreground-rgb: 0, 0, 0; .page {
--background-start-rgb: 214, 219, 220; font-family: 'Open Sans', sans-serif;
--background-end-rgb: 255, 255, 255; color: #fff;
padding: 2vh 7vw;
position: relative;
background-color: black;
} }
@media (prefers-color-scheme: dark) { .ebook {
:root { position: relative;
--foreground-rgb: 255, 255, 255; background-color: #161515;
--background-start-rgb: 0, 0, 0; border-radius: 20px;
--background-end-rgb: 0, 0, 0; border-bottom: 5px ridge #b2c2c2; /* accidental nice effect */
} min-height: 600px;
min-width: 300px;
max-width: 1400px;
overflow: hidden;
margin: auto;
} }
body { /* Decorations and top icons */
color: rgb(var(--foreground-rgb));
background: linear-gradient( .ebook__side-gradient {
to bottom, position: absolute;
transparent, }
rgb(var(--background-end-rgb))
) .ebook__side-gradient_top,
rgb(var(--background-start-rgb)); .ebook__side-gradient_bottom {
height: 100px;
width: 100%;
}
.ebook__side-gradient_top {
background-image: linear-gradient(#133333, #161515);
border-top-left-radius: 20px;
border-top-right-radius: 20px;
}
.ebook__side-gradient_bottom {
bottom: 0;
background-image: linear-gradient(#161515, #133333);
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
}
.ebook__side-gradient_left,
.ebook__side-gradient_right {
height: 100%;
width: 100px;
}
.ebook__side-gradient_left {
background-image: linear-gradient(to right, #133333, #161515);
}
.ebook__side-gradient_right {
right: 0;
background-image: linear-gradient(to left, #133333, #161515);
}
.ebook__corner-gradient {
height: 100px;
width: 100px;
position: absolute;
}
.ebook__corner-gradient_top-left {
top: 0;
left: 0;
background-image: radial-gradient(farthest-side at 100% 100%, #161515, #133333);
border-top-left-radius: 20px;
}
.ebook__corner-gradient_top-right {
top: 0;
right: 0;
background-image: radial-gradient(farthest-side at 0% 100%, #161515, #133333);
border-top-right-radius: 20px;
}
.ebook__corner-gradient_bottom-left {
bottom: 0;
left: 0;
background-image: radial-gradient(farthest-side at 100% 0%, #161515, #133333);
border-bottom-left-radius: 20px;
}
.ebook__corner-gradient_bottom-right {
bottom: 0;
right: 0;
background-image: radial-gradient(farthest-side at 0% 0%, #161515, #133333);
border-bottom-right-radius: 20px;
}
.ebook__dots-background {
position: absolute;
width: calc(100% - 30px);
height: 100%;
background-image: radial-gradient(#153939 3%, transparent 3%);
background-size: 100px 100px;
}
.ebook__vertical-borders {
position: absolute;
border-left: 1px solid #a6c9c9;
border-right: 1px solid #a6c9c9;
right: 25px;
left: 25px;
top: 25px;
bottom: 25px;
}
.ebook__icons {
position: absolute;
width: 100%;
display: flex;
justify-content: space-between;
box-sizing: border-box;
padding: 2rem 3rem 0;
font-size: 1.2rem !important;
}
.ebook__icon_book {
font-size: 2rem !important;
}
.ebook__flare {
opacity: .05;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: -55%;
background-color: #fff;
transform: skewX(-10deg);
}
/* Content */
.ebook__content {
position: relative;
margin: 100px;
font-size: 1.2rem;
text-shadow: 0 0 1rem #14c1c1, 0 0 1rem #189494, 0 0 1rem #134848;
}
.article {
transition: opacity .3s;
}
.article__title {
font-family: 'Ubuntu', sans-serif;
text-transform: uppercase;
font-size: 1.2rem;
margin: 0 0 2.4rem;
text-align: center;
}
.article__subtitle {
font-style: italic;
margin: 0 0 2rem;
}
.article__subtitle_no-margin-bottom {
margin-bottom: 0;
}
.article__image {
width: 25%;
float: right;
border-radius: 1rem;
margin: 0 0 1rem 2rem;
opacity: .5;
transition: opacity .2s, box-shadow .2s;
cursor: pointer;
}
.article__image:hover {
opacity: 1;
box-shadow: 0 0 .5rem #14c1c1, 0 0 .5rem #189494, 0 0 .5rem #134848;
}
.article__text {
text-align: justify;
margin: 0 0 1rem;
line-height: 2rem;
}
.navigation {
text-align: center;
font-size: 1.5rem;
}
.navigation__list {
list-style: none;
padding: 0;
}
.navigation__item {
display: inline;
padding: 0 .1rem;
}
.navigation__link {
text-decoration: none;
color: #fff;
}
.lightbox {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 1;
background-color: rgba(0, 0, 0, .75);
display: flex;
justify-content: center;
align-items: center;
padding: 40px;
cursor: pointer;
}
.lightbox__item {
max-width: 95%;
max-height: 95%;
}
.lightbox_hidden {
visibility: hidden;
}
@media screen and (max-width: 992px) {
.page {
padding: 2vh 1vw;
}
.ebook__content {
font-size: 1rem;
margin: 80px;
}
.article__title {
font-size: 1rem;
margin-bottom: 2rem;
}
.article__subtitle {
margin-bottom: 1.6rem;
}
.article__text {
margin-bottom: 1.6rem;
line-height: 1.6rem;
}
.ebook__icons {
font-size: .7rem !important;
}
.ebook__icon_book {
font-size: 1.75rem !important;
}
.article__image {
width: 50%;
opacity: .8;
box-shadow: 0 0 .5rem #14c1c1, 0 0 .5rem #189494, 0 0 .5rem #134848;
}
}
@media screen and (max-width: 576px) {
.ebook__content {
font-size: .8rem;
margin: 60px;
}
.article__title {
font-size: .8rem;
margin-bottom: 1.6rem;
}
.article__subtitle {
margin-bottom: 1rem;
}
.article__text {
margin-bottom: 1rem;
line-height: 1rem;
}
.article__image {
width: 100%;
opacity: .8;
box-shadow: 0 0 .5rem #14c1c1, 0 0 .5rem #189494, 0 0 .5rem #134848;
}
} }

View File

@ -1,113 +1,65 @@
import Image from 'next/image' import { DxBook, DxBookPage, DxBookPageIconsProps, DxIcon, DxParagraph } from "@/components";
import React, { FC, PropsWithChildren } from "react";
import { EmailLink, HhLink, IconLink, LinkTargetBlank, SpbDotNetLink } from "@/components/links";
const FlexList: FC<PropsWithChildren> = ({ children }) => <div className="flex flex-col">{children}</div>;
const left: DxBookPageIconsProps["left"] = [
<IconLink href={"https://keroosha.t.me"} className={"fa-brands fa-telegram"} />,
<IconLink href={"https://github.com/Keroosha"} className={"fa-brands fa-github"} />,
<IconLink href={"https://www.last.fm/user/ykpon777"} className={"fa-brands fa-lastfm-square"} />,
<IconLink href={"https://steamcommunity.com/id/keroosha"} className={"fa-brands fa-steam"} />,
];
const right: DxBookPageIconsProps["right"] = [];
const SkillzLine: FC<PropsWithChildren & { className: string }> = ({ className, children }) => (
<div className={"flex m-1"}>
<DxIcon className={"w-14 " + className} />
<span>{children}</span>
</div>
);
const Block: FC<PropsWithChildren & { title: string }> = ({ children, title }) => (
<div className={"mb-5"}>
<DxParagraph>{title}</DxParagraph>
<FlexList>{children}</FlexList>
</div>
);
export default function Home() { export default function Home() {
return ( return (
<main className="flex min-h-screen flex-col items-center justify-between p-24"> <DxBook className={"min-h-screen"} iconsProps={{ left, right }}>
<div className="z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex"> <DxBookPage
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30"> title={"Whoami: Keroosha"}
Get started by editing&nbsp; subTitle={".NET Developer, Meme Lord, Gun Owner, Music Nerd, SysOps and Anime"}
<code className="font-mono font-bold">src/app/page.tsx</code> >
</p> <Block title={"Key Skills:"}>
<div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none"> <SkillzLine className={"fa-solid fa-server"}>.NET (C#/FSharp)</SkillzLine>
<a <SkillzLine className={"fa-solid fa-database"}>PostgreSQL</SkillzLine>
className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0" <SkillzLine className={"fa-solid fa-diagram-project"}>GraphQL</SkillzLine>
href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app" <SkillzLine className={"fa-solid fa-users"}>OAuth2 (Idserver4/KeyCloak)</SkillzLine>
target="_blank" <SkillzLine className={"fa-brands fa-linux"}>GNU/Linux</SkillzLine>
rel="noopener noreferrer" <SkillzLine className={"fa-brands fa-node-js"}>Node.JS</SkillzLine>
> <SkillzLine className={"fa-brands fa-docker"}>Docker</SkillzLine>
By{' '} <SkillzLine className={"fa-brands fa-react"}>React</SkillzLine>
<Image </Block>
src="/vercel.svg"
alt="Vercel Logo"
className="dark:invert"
width={100}
height={24}
priority
/>
</a>
</div>
</div>
<div className="relative flex place-items-center before:absolute before:h-[300px] before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 before:lg:h-[360px]"> <Block title="Talks:">
<Image <SpbDotNetLink />
className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert" </Block>
src="/next.svg"
alt="Next.js Logo"
width={180}
height={37}
priority
/>
</div>
<div className="mb-32 grid text-center lg:mb-0 lg:grid-cols-4 lg:text-left"> <Block title="Admin at:">
<a <LinkTargetBlank href={"https://t.me/DotNetRuChat"}>Dotnet RU Chat</LinkTargetBlank>
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app" <LinkTargetBlank href={"https://t.me/netscapedidnothingwrong"}>Web 1.0</LinkTargetBlank>
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30" <LinkTargetBlank href={"https://t.me/pokupkabitka"}>Супер быстрая покупка битка</LinkTargetBlank>
target="_blank" </Block>
rel="noopener noreferrer"
>
<h2 className={`mb-3 text-2xl font-semibold`}>
Docs{' '}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
Find in-depth information about Next.js features and API.
</p>
</a>
<a <Block title={"Hire Me:"}>
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app" <HhLink />
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800 hover:dark:bg-opacity-30" <EmailLink />
target="_blank" </Block>
rel="noopener noreferrer" </DxBookPage>
> </DxBook>
<h2 className={`mb-3 text-2xl font-semibold`}> );
Learn{' '}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
Learn about Next.js in an interactive course with&nbsp;quizzes!
</p>
</a>
<a
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
target="_blank"
rel="noopener noreferrer"
>
<h2 className={`mb-3 text-2xl font-semibold`}>
Templates{' '}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
Explore the Next.js 13 playground.
</p>
</a>
<a
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
target="_blank"
rel="noopener noreferrer"
>
<h2 className={`mb-3 text-2xl font-semibold`}>
Deploy{' '}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
Instantly deploy your Next.js site to a shareable URL with Vercel.
</p>
</a>
</div>
</main>
)
} }

101
src/components/index.tsx Normal file
View File

@ -0,0 +1,101 @@
import React, { FC, PropsWithChildren } from "react";
type RNode = PropsWithChildren["children"];
type DivProps = React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
type IProps = React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
type ImgProps = React.DetailedHTMLProps<React.HTMLAttributes<HTMLImageElement>, HTMLImageElement>;
type PProps = React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>;
export type DxBookProps = DivProps & { iconsProps?: DxBookPageIconsProps };
export type DxBookPageProps = PropsWithChildren & { title: string; subTitle: string };
export type DxBookPageIconsProps = { left?: RNode; right?: RNode };
const DxBookPageDecoration = () => (
<>
<div className="ebook__side-gradient ebook__side-gradient_top"></div>
<div className="ebook__side-gradient ebook__side-gradient_left"></div>
<div className="ebook__side-gradient ebook__side-gradient_right"></div>
<div className="ebook__side-gradient ebook__side-gradient_bottom"></div>
<div className="ebook__corner-gradient ebook__corner-gradient_top-left"></div>
<div className="ebook__corner-gradient ebook__corner-gradient_top-right"></div>
<div className="ebook__corner-gradient ebook__corner-gradient_bottom-left"></div>
<div className="ebook__corner-gradient ebook__corner-gradient_bottom-right"></div>
<div className="ebook__dots-background"></div>
<div className="ebook__vertical-borders"></div>
</>
);
const DxBookPageIcons: FC<DxBookPageIconsProps> = ({ left, right }) => (
<>
<div className="ebook__icons">
<div>{left}</div>
<div>{right}</div>
</div>
</>
);
const DxNavigationStub: FC<PropsWithChildren> = () => (
<nav className="navigation">
<ul className="navigation__list">
<li className="navigation__item">
<a className="navigation__link" href="#">
</a>
</li>
<li className="navigation__item">
<a className="navigation__link" href="#">
</a>
</li>
<li className="navigation__item">
<a className="navigation__link" href="#">
</a>
</li>
</ul>
</nav>
);
export const DxBookPage: FC<DxBookPageProps> = ({ children, subTitle, title }) => (
<section className={"ebook__content"}>
<article className={"article"}>
<header>
<h1 className="article__title">{title}</h1>
<p className="article__subtitle">{subTitle}</p>
</header>
{children}
</article>
</section>
);
export const DxParagraph: FC<PProps> = ({ children, ...rest }) => (
<p {...rest} className={`article__text ${rest.className}`}>
{children}
</p>
);
export const DxIcon: FC<IProps> = ({ children, ...rest }) => (
<i {...rest} className={`ebook__icon ebook__icon_book ${rest.className}`} aria-hidden="true">
{children}
</i>
);
export const DxImage: FC<ImgProps> = ({ ...props }) => (
<img {...props} className={`article__image ${props.className}`} />
);
export const DxBook: FC<DxBookProps> = ({ children, iconsProps, ...rest }) => {
return (
<div {...rest} className={`page ${rest.className}`}>
<section className={"ebook"}>
<DxBookPageDecoration />
<DxBookPageIcons {...(iconsProps ?? {})} />
{/*<div className="ebook__flare" />*/}
{children}
</section>
<div className={"mt-10"}>
<a href={"https://github.com/cat-street/deus-ex-ebook/"}>Theme by cat-street</a>
</div>
</div>
);
};

32
src/components/links.tsx Normal file
View File

@ -0,0 +1,32 @@
import React, { FC, HTMLAttributes, PropsWithChildren } from "react";
import { DxIcon } from "@/components/index";
export const LinkTargetBlank: FC<PropsWithChildren & { href: string }> = ({ href, children }) => (
<a href={href} target={"_blank"} className={"ml-3 underline"}>
{children}
</a>
);
export const HhLink = () => (
<LinkTargetBlank href={"https://spb.hh.ru/resume/a07f1925ff04f3eeba0039ed1f324c55545037"}>
CV at hh.ru
</LinkTargetBlank>
);
export const EmailLink = () => (
<a href={"mailto:mr.dead.toast@gmail.com"} className={"ml-3 underline"}>
Email
</a>
);
export const IconLink: FC<{ href: string; className: HTMLAttributes<any>["className"] }> = ({ href, className }) => (
<a href={href} target={"_blank"} className={"mr-3"}>
<DxIcon className={className} />
</a>
);
export const SpbDotNetLink = () => (
<LinkTargetBlank href={"https://github.com/DotNetRu/BrandBook/wiki/Kirill-Poletaev"}>
On SpbDotNet community
</LinkTargetBlank>
);

View File