Init
This commit is contained in:
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
12
Dockerfile
Normal file
12
Dockerfile
Normal file
@@ -0,0 +1,12 @@
|
||||
FROM node:22.18.0-alpine as build
|
||||
|
||||
WORKDIR /usr/app
|
||||
COPY . /usr/app
|
||||
RUN npm i
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:1.23.1-alpine
|
||||
RUN rm -rf /usr/share/nginx/html/*
|
||||
|
||||
COPY --from=build /usr/app/dist /usr/share/nginx/html
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
29
eslint.config.js
Normal file
29
eslint.config.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import js from '@eslint/js'
|
||||
import globals from 'globals'
|
||||
import reactHooks from 'eslint-plugin-react-hooks'
|
||||
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||
import { defineConfig, globalIgnores } from 'eslint/config'
|
||||
|
||||
export default defineConfig([
|
||||
globalIgnores(['dist']),
|
||||
{
|
||||
files: ['**/*.{js,jsx}'],
|
||||
extends: [
|
||||
js.configs.recommended,
|
||||
reactHooks.configs['recommended-latest'],
|
||||
reactRefresh.configs.vite,
|
||||
],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2020,
|
||||
globals: globals.browser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
ecmaFeatures: { jsx: true },
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
|
||||
},
|
||||
},
|
||||
])
|
||||
13
index.html
Normal file
13
index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + React</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
2038
package-lock.json
generated
Normal file
2038
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
29
package.json
Normal file
29
package.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "portfolio",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react-router-dom": "^7.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.33.0",
|
||||
"@types/react": "^19.1.10",
|
||||
"@types/react-dom": "^19.1.7",
|
||||
"@vitejs/plugin-react": "^5.0.1",
|
||||
"eslint": "^9.33.0",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.20",
|
||||
"globals": "^16.3.0",
|
||||
"sass": "^1.90.0",
|
||||
"vite": "^7.1.3"
|
||||
}
|
||||
}
|
||||
BIN
public/bsuir.png
Normal file
BIN
public/bsuir.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
BIN
public/server.jpg
Normal file
BIN
public/server.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 468 KiB |
78
src/About.jsx
Normal file
78
src/About.jsx
Normal file
@@ -0,0 +1,78 @@
|
||||
import "./About.scss";
|
||||
|
||||
export default function About() {
|
||||
return (
|
||||
<div class="about-main">
|
||||
<article class="section">
|
||||
<h3 class="section__title">Experiences</h3>
|
||||
<br />
|
||||
<h4>Finmarket Soft (2021 - Present)</h4>
|
||||
|
||||
<p>
|
||||
Product company. Forex broker user cabinet development.
|
||||
Payment system integrations,
|
||||
maintenance of finance operations processing flow.
|
||||
API development.
|
||||
Trading platform implementations (MT4, MT5, TT),
|
||||
API and database optimization and etc
|
||||
</p>
|
||||
<br />
|
||||
<h4>Skills</h4>
|
||||
|
||||
<ul class="section__list">
|
||||
<li class="section__list-item">.NET Core</li>
|
||||
<li class="section__list-item">Entity Framework</li>
|
||||
<li class="section__list-item">Docker</li>
|
||||
<li class="section__list-item">Kubernets</li>
|
||||
<li class="section__list-item">Ceph</li>
|
||||
<li class="section__list-item">Gitlab CI/CD</li>
|
||||
<li class="section__list-item">Networking</li>
|
||||
</ul>
|
||||
</article>
|
||||
<br />
|
||||
<article class="section">
|
||||
<h3 class="section__title">Education</h3>
|
||||
<div class="image-with-text">
|
||||
<img class="section__img" src="/bsuir.png" width="100"/>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
<strong>Belarusian State University of Informatics and Radioelectronics (2021 - 2025)</strong>
|
||||
</p>
|
||||
<p>
|
||||
Computing systems and networks.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
<br />
|
||||
<article class="section">
|
||||
<h3 class="section__title">Hobbies</h3>
|
||||
<div class="image-with-text">
|
||||
<img class="main-img" src="/server.jpg" height="100" width="140"/>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
<strong>HomeLab</strong>
|
||||
</p>
|
||||
|
||||
<ul class="section__list">
|
||||
<li class="section__list-item">Bare metal server (HP Proliant DL380 Gen9) administrator</li>
|
||||
<li class="section__list-item">40 TB Torrent seed</li>
|
||||
<li class="section__list-item">Domain owner</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<strong>Other</strong>
|
||||
</p>
|
||||
|
||||
<ul class="section__list">
|
||||
<li class="section__list-item">Drums</li>
|
||||
<li class="section__list-item">Drawing</li>
|
||||
</ul>
|
||||
</article>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
36
src/About.scss
Normal file
36
src/About.scss
Normal file
@@ -0,0 +1,36 @@
|
||||
@use '_colors';
|
||||
|
||||
.main {
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 20px;
|
||||
|
||||
.image-with-text {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__list {
|
||||
padding-left: 17px;
|
||||
margin: 0;
|
||||
list-style: "- ";
|
||||
}
|
||||
|
||||
&__title {
|
||||
color: colors.$color-heading;
|
||||
margin: 0 0 5px 0;
|
||||
}
|
||||
|
||||
strong {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
29
src/App.jsx
Normal file
29
src/App.jsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
|
||||
import Navbar from './Navbar';
|
||||
import Homelab from './Homelab';
|
||||
import About from './About';
|
||||
import Sidebar from "./Sidebar";
|
||||
import Footer from './Footer';
|
||||
import "./App.scss";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<Router>
|
||||
<div className="app-container">
|
||||
<Navbar />
|
||||
<div className="wrapper">
|
||||
<div className='content'>
|
||||
<Routes>
|
||||
<Route path="/" element={<About />} />
|
||||
<Route path="/homelab" element={<Homelab />} />
|
||||
</Routes>
|
||||
</div>
|
||||
<div className="sidebar">
|
||||
<Sidebar />
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
42
src/App.scss
Normal file
42
src/App.scss
Normal file
@@ -0,0 +1,42 @@
|
||||
@use '_colors';
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body, #root {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Центральный «островок» */
|
||||
.app-container {
|
||||
width: 1024px;
|
||||
min-height: 100vh; /* на всю высоту окна */
|
||||
margin: 0 auto; /* центрирование по горизонтали */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: colors.$color-white; /* цвет островка, можно поменять */
|
||||
box-shadow: 0 0 10px rgba(0,0,0,0.1); /* легкая тень для отделения от белого фона */
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Consolas, sans-serif;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
display: flex;
|
||||
min-height: 87vh;
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
background-color: colors.$color-white;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
padding: 20px;
|
||||
}
|
||||
9
src/Footer.jsx
Normal file
9
src/Footer.jsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import "./Footer.scss";
|
||||
|
||||
export default function Footer() {
|
||||
return (
|
||||
<footer className="footer">
|
||||
© {new Date().getFullYear()} Peabody28 Network
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
13
src/Footer.scss
Normal file
13
src/Footer.scss
Normal file
@@ -0,0 +1,13 @@
|
||||
@use '_colors';
|
||||
|
||||
.footer {
|
||||
font-size: 10px;
|
||||
margin-top: 20px;
|
||||
padding: 10px;
|
||||
border-top: 1px solid colors.$color-border;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
align-items: center;
|
||||
height: 3vh;
|
||||
}
|
||||
48
src/Homelab.jsx
Normal file
48
src/Homelab.jsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import "./Homelab.scss";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<article className="section">
|
||||
<h4>Begin</h4>
|
||||
|
||||
<p>
|
||||
When I moved from the dorm to my first rented apartment,
|
||||
there was a static IP address. I decided that it could be used,
|
||||
and sometimes I started leaving my home computer turned on to take files from it.
|
||||
</p>
|
||||
<br />
|
||||
<h4>First server</h4>
|
||||
|
||||
<p>
|
||||
Later, I built a separate tower server for this, with Ubuntu
|
||||
running on it and my pet projects, file server, and Torrent running.
|
||||
Later, I installed a hypervisor (Proxmox) and delegated some services to separate machines.
|
||||
</p>
|
||||
<br />
|
||||
<h4>Networks and Security</h4>
|
||||
|
||||
<p>
|
||||
Almost at the same time, I started dealing with networks and decided that my virtual machines and home network
|
||||
It needs to be secured. I have configured OpenVPN to access my home network. When I got Mikrotik, life
|
||||
became much more fun, I switched to the simplicity of WireGuard, set up a firewall and created separate networks for different purposes.
|
||||
</p>
|
||||
<br />
|
||||
<h4>Enterprise Quality</h4>
|
||||
|
||||
<p>
|
||||
When I started to run into disk storage, I decided to take a serious server to meet my
|
||||
upgrade requirements, disk storage and memory. I currently have one HP Proliant DL380 Gen9 machine.
|
||||
with 96 GB of RAM and 10TB of disk storage.
|
||||
</p>
|
||||
<br />
|
||||
<h4>Storage and Services</h4>
|
||||
|
||||
<p>
|
||||
My storage is organized with Ceph,
|
||||
this allows me to easily change the disk configuration without RAID.
|
||||
All my applications are deployed in Kubernetes
|
||||
</p>
|
||||
|
||||
</article>
|
||||
);
|
||||
}
|
||||
0
src/Homelab.scss
Normal file
0
src/Homelab.scss
Normal file
19
src/Navbar.jsx
Normal file
19
src/Navbar.jsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
import "./Navbar.scss";
|
||||
|
||||
export default function Navbar() {
|
||||
return (
|
||||
<header className="header">
|
||||
<div className="header__top">
|
||||
<p>Backend Developer</p>
|
||||
<p>Maksim Harbacheuski</p>
|
||||
</div>
|
||||
<nav className="header__nav">
|
||||
<ul className="header__nav-list">
|
||||
<li className="header__nav-list-item"><Link to="/" className="text-blue-600 hover:underline">About</Link></li>
|
||||
<li className="header__nav-list-item active"><Link to="/homelab" className="text-blue-600 hover:underline">Homelab</Link></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
44
src/Navbar.scss
Normal file
44
src/Navbar.scss
Normal file
@@ -0,0 +1,44 @@
|
||||
@use '_colors';
|
||||
|
||||
.header {
|
||||
height: 7vh;
|
||||
&__top {
|
||||
padding: 5px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background-color: colors.$color-primary;
|
||||
|
||||
p {
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
color: colors.$color-white;
|
||||
}
|
||||
}
|
||||
|
||||
&__nav {
|
||||
background-color: colors.$color-secondary;
|
||||
padding: 10px;
|
||||
|
||||
&-list {
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
&-item {
|
||||
font-weight: bold;
|
||||
|
||||
a {
|
||||
color: colors.$color-white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.active a {
|
||||
color: #2c2c2c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
52
src/Sidebar.jsx
Normal file
52
src/Sidebar.jsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import "./Sidebar.scss";
|
||||
|
||||
export default function Sidebar() {
|
||||
return (
|
||||
<div>
|
||||
<div class="sidebar-item">
|
||||
<div class="sidebar-item-top island-top">
|
||||
<strong class="island-top-text">Facts</strong>
|
||||
</div>
|
||||
<div class="sidebar-item-content">
|
||||
<div class="sidebar-item-content__block">
|
||||
<ul>
|
||||
<li>21 years old</li>
|
||||
<li>Higher education (systems engineer)</li>
|
||||
<li>In programming since 12 years old</li>
|
||||
<li>40 TB torrent seed</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-item">
|
||||
<div class="sidebar-item-top island-top">
|
||||
<strong class="island-top-text">Links</strong>
|
||||
</div>
|
||||
<div class="sidebar-item-content">
|
||||
<div class="sidebar-item-content__block">
|
||||
<strong>Contact</strong>
|
||||
|
||||
<ul>
|
||||
<li><a href="www.linkedin.com/in/peabody28">LinkedIn</a></li>
|
||||
<li><a href="mailto:gorbachewski.m@gmail.com">E-mail</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="sidebar-item-content__block">
|
||||
<strong>Publications</strong>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://habr.com/ru/users/peabody28/">Habr</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="sidebar-item-content__block">
|
||||
<strong>Git Repos</strong>
|
||||
<ul>
|
||||
<li><a href="https://github.com/peabody28">GitHub</a></li>
|
||||
<li><a href="https://gitlab.com/peabody28">GitLab</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
93
src/Sidebar.scss
Normal file
93
src/Sidebar.scss
Normal file
@@ -0,0 +1,93 @@
|
||||
@use '_colors';
|
||||
|
||||
.sidebar {
|
||||
width: 200px;
|
||||
font-size: 14px;
|
||||
|
||||
&-item {
|
||||
background-color: colors.$color-right-sidebar;
|
||||
border-radius: 5px 5px 0 0;
|
||||
padding-bottom: 3px;
|
||||
margin-bottom: 25px;
|
||||
|
||||
&-top {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
&-content {
|
||||
padding: 3px;
|
||||
background-color: colors.$color-white;
|
||||
margin: 3px 3px 0 3px;
|
||||
|
||||
&__block {
|
||||
margin-bottom: 10px;
|
||||
|
||||
ul {
|
||||
margin-top: 10px;
|
||||
padding-left: 17px;
|
||||
list-style: "- ";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.links {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: colors.$color-link;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 20px;
|
||||
|
||||
.image-with-text {
|
||||
margin-top: 10px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__list {
|
||||
padding-left: 17px;
|
||||
margin: 0;
|
||||
|
||||
list-style: "- ";
|
||||
}
|
||||
|
||||
&__title {
|
||||
color: colors.$color-heading;
|
||||
margin: 0 0 5px 0;
|
||||
}
|
||||
|
||||
strong {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.island-top {
|
||||
height: 20px;
|
||||
border-radius: 5px 5px 0 0;
|
||||
background-color: colors.$color-primary;
|
||||
|
||||
&-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
color: colors.$color-white;
|
||||
padding-left: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
}
|
||||
9
src/_colors.scss
Normal file
9
src/_colors.scss
Normal file
@@ -0,0 +1,9 @@
|
||||
$color-primary: #01649C;
|
||||
$color-secondary: #FFCC66;
|
||||
$color-heading: #cc6600;
|
||||
$color-highlight: #ffffcc;
|
||||
$color-right-sidebar: #EEEECC;
|
||||
$color-link: #003399;
|
||||
$color-border: #ccc;
|
||||
$color-white: #ffffff;
|
||||
$color-grey: grey;
|
||||
9
src/main.jsx
Normal file
9
src/main.jsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import App from './App.jsx'
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
)
|
||||
7
vite.config.js
Normal file
7
vite.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
})
|
||||
Reference in New Issue
Block a user