about page content + integrate mdx
This commit is contained in:
6
.idea/misc.xml
generated
Normal file
6
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptSettings">
|
||||||
|
<option name="languageLevel" value="FLOW" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
1776
package-lock.json
generated
1776
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -38,6 +38,7 @@
|
|||||||
"@babel/preset-env": "^7.29.0",
|
"@babel/preset-env": "^7.29.0",
|
||||||
"@babel/preset-react": "^7.28.5",
|
"@babel/preset-react": "^7.28.5",
|
||||||
"@babel/preset-typescript": "^7.28.5",
|
"@babel/preset-typescript": "^7.28.5",
|
||||||
|
"@mdx-js/loader": "^3.1.1",
|
||||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.6.2",
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.6.2",
|
||||||
"@svgr/webpack": "^8.1.0",
|
"@svgr/webpack": "^8.1.0",
|
||||||
"@testing-library/dom": "^10.4.1",
|
"@testing-library/dom": "^10.4.1",
|
||||||
@@ -45,6 +46,7 @@
|
|||||||
"@testing-library/react": "^16.3.2",
|
"@testing-library/react": "^16.3.2",
|
||||||
"@testing-library/user-event": "^14.6.1",
|
"@testing-library/user-event": "^14.6.1",
|
||||||
"@types/jest": "^30.0.0",
|
"@types/jest": "^30.0.0",
|
||||||
|
"@types/mdx": "^2.0.13",
|
||||||
"@types/node": "^25.3.3",
|
"@types/node": "^25.3.3",
|
||||||
"@types/react": "^19.2.14",
|
"@types/react": "^19.2.14",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
@@ -71,7 +73,8 @@
|
|||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"webpack": "^5.105.4",
|
"webpack": "^5.105.4",
|
||||||
"webpack-cli": "^6.0.1",
|
"webpack-cli": "^6.0.1",
|
||||||
"webpack-dev-server": "^5.2.3"
|
"webpack-dev-server": "^5.2.3",
|
||||||
|
"webpack-manifest-plugin": "^6.0.1"
|
||||||
},
|
},
|
||||||
"babel": {
|
"babel": {
|
||||||
"presets": [
|
"presets": [
|
||||||
|
|||||||
94
src/about/About.mdx
Normal file
94
src/about/About.mdx
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
import openingImage from "../img/IMG_20240725_175449_803.jpg";
|
||||||
|
import rainbow from "../img/IMG-0186.jpg";
|
||||||
|
import japanese from "../img/IMG_20230531_000224_01.jpg";
|
||||||
|
import computers from "../img/IMG_3071.jpg";
|
||||||
|
import mobo from "../img/2025-10-03-02-20-50-077.jpg";
|
||||||
|
import suit from "../img/military.jpg";
|
||||||
|
import nutrivend from "../img/nutrivend.jpeg";
|
||||||
|
|
||||||
|
<img src={openingImage} alt="Tymur Arsentiev" className="self"/>
|
||||||
|
|
||||||
|
# Welcome to my blog and personal website!
|
||||||
|
|
||||||
|
For the longest time, I never had a personal website to show my skills.
|
||||||
|
Project after project, I have over 4 years under my belt, but I've never considered making a portfolio.
|
||||||
|
Since early 2026, I've begun working on one. My website styles blend together an abstract UI while retaining functional simplicity on UX.
|
||||||
|
Website development is my favorite hobby, and is naturally my favorite type of software engineering.
|
||||||
|
|
||||||
|
My goals are the following:
|
||||||
|
|
||||||
|
- Journaling my thoughts (originally done on [Medium](https://medium.com/@tymur.arsent)
|
||||||
|
and [Substack](https://substack.com/@timsnodocmartins))
|
||||||
|
- Merging my unique fashion sense with my website design skills
|
||||||
|
- Cultivating my personal brand by documenting unique coding challenges
|
||||||
|
|
||||||
|
|
||||||
|
## Fashion Rebel
|
||||||
|
|
||||||
|
<div className="clothing">
|
||||||
|
<img src={rainbow} alt="Rainbow colored clothing"/>
|
||||||
|
<img src={japanese} alt="Purple shirt with Japanese text"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
I am a fashion rebel at heart; just like my websites, the goal of my fashion is to stand out.
|
||||||
|
I'm more of a shirt/jacket person more than anything, and I tend to keep my pants simple.
|
||||||
|
I'm a sucker for flashy colors and abstract designs, so I'm always out buying, looking for inspiration.
|
||||||
|
|
||||||
|
I'm originally from Chicago, but I go to Georgia Tech in Atlanta. But I like Atlanta more for fashion.
|
||||||
|
Whenever I can, I like to go thrifting near Ponce De Leon or Little Five Points.
|
||||||
|
Chicago has few boutiques, mostly only name brand clothing. It's gotten so bad recently that I've been doing all my shopping on [Ebay](https://www.ebay.com/usr/tymur999).
|
||||||
|
I like Ebay because it's like a collector's website. I've been a collector all my life, so you could say that I collect clothing.
|
||||||
|
I also sell stuff on there, so be sure to check out my listings.
|
||||||
|
|
||||||
|
Why do I talk about fashion? That's because my fashion hobby inspired me to start this website.
|
||||||
|
I'd like to think my taste in wearing outfits has been a huge asset in finding a modern design that works for this site.
|
||||||
|
|
||||||
|
## Self-Hosting Champion
|
||||||
|
|
||||||
|
<div className="computers">
|
||||||
|
<img src={computers} alt="Surrounded by computers"/>
|
||||||
|
<img src={mobo} alt="Surrounded by computers"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
As a rebel, I greatly value my independence.
|
||||||
|
I don't like how big tech companies operate by encroaching on my data,
|
||||||
|
so I've been self-hosting nearly all the software I use.
|
||||||
|
|
||||||
|
This website is hosted on my Kubernetes cluster, run at home.
|
||||||
|
Here are some other software I self-host on it:
|
||||||
|
- [Gitea, for VCS operations and CI/CD solution](https://gitea.tymur999.com)
|
||||||
|
- [Nextcloud, for private cloud and file+calendar+task synchronization](https://nextcloud.tymur999.com)
|
||||||
|
- Postfix, for private email solution and custom domain
|
||||||
|
|
||||||
|
### That alone means I have my own self-hosted version of Google Drive, Gmail, and Github.
|
||||||
|
|
||||||
|
I take pride in my Kubernetes cluster as Kubernetes knowledge is invaluable at nearly all software companies.
|
||||||
|
I like managing the software at every step of the deployment pipeline, besides writing the actual code.
|
||||||
|
|
||||||
|
If you couldn't tell, I'm very DIY-ey. I build every computer and server from scratch.
|
||||||
|
The cluster runs on a 28-core dual Intel Xeon server, which is my most impressive build.
|
||||||
|
Otherwise, All my computers run on Arch Linux, which is built from scratch.
|
||||||
|
Not to mention, my Linux experience spans nearly my entire life. I got my first Raspberry Pi in 2013.
|
||||||
|
And now I daily drive Arch Linux, if that says anything about my Linux experience.
|
||||||
|
|
||||||
|
## Savvy Entrepreneur
|
||||||
|
|
||||||
|
<div className="clothing">
|
||||||
|
<img src={suit} alt="Surrounded by computers"/>
|
||||||
|
<img src={nutrivend} alt="Surrounded by computers"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
At heart, I'm always self-employed. Always looking to hustle or solve a challenge to earn money.
|
||||||
|
I've been a part of two startups, Nutrivend and Kiwoon Learning, both of which I worked as CTO.
|
||||||
|
|
||||||
|
At Kiwoon Learning, around 2023, I made a stock market simulator backend in C# and built a frontend in React.
|
||||||
|
The goal of the app was to teach high school students how to invest in stocks.
|
||||||
|
Through coding the app, I learned how to stop being so perfectionist.
|
||||||
|
My perfectionism led to delays in releases, and I learned to value my time much more.
|
||||||
|
However, the simulator turned out to be one of the most advanced on the market, especially for high school students.
|
||||||
|
|
||||||
|
At Nutrivend, I built a full-stack web application using Next.js.
|
||||||
|
The app featured a quiz system that filtered people into different categories of supplements based on their
|
||||||
|
fitness goals and health. I helped my friend Woosik integrate Stripe so he could easily accept payments
|
||||||
|
and manage his supplement orders and supply.
|
||||||
|
Here, I used my Kubernetes experience to deploy the app on my cluster and keep uptime as close to 24/7 as possible.
|
||||||
@@ -1,40 +1,14 @@
|
|||||||
import "./about.scss";
|
import "./about.scss";
|
||||||
import openingImage from "../img/IMG_20240725_175449_803.jpg";
|
import {PropsWithChildren} from "react";
|
||||||
import rainbow from "../img/IMG-0186.jpg";
|
import About from "./About.mdx";
|
||||||
import japanese from "../img/IMG_20230531_000224_01.jpg";
|
|
||||||
import type {PropsWithChildren} from "react";
|
|
||||||
|
|
||||||
export default function AboutPage() {
|
export default function AboutPage() {
|
||||||
return <main className="about-page">
|
return <main className="about-page">
|
||||||
<div className="edge"/>
|
<div className="edge"/>
|
||||||
<section className="about-container">
|
<section className="about-container">
|
||||||
<img src={openingImage} alt="Tymur Arsentiev" className="self"/>
|
<About components={{
|
||||||
<h1 className="title">Welcome to my blog and personal website!</h1>
|
'a': ExternalLink,
|
||||||
<p>
|
}}/>
|
||||||
For the longest time, I never had a personal website to show my skills.
|
|
||||||
I'm a longtime coder, project after project, but have never considered making a place to share my thoughts.
|
|
||||||
After a while, I was inspired by my <ExternalLink href="https://medium.com/@tymur.arsent">Medium</ExternalLink> and
|
|
||||||
<ExternalLink href="https://substack.com/@timsnodocmartins">Substack</ExternalLink> account to begin journaling my thoughts on my own.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
I like to take pride in my uniqueness as a web developer.
|
|
||||||
I don't go for trends, I consider myself <i>the trendsetter.</i>
|
|
||||||
My website design was definitely influenced by my fashion sense.
|
|
||||||
</p>
|
|
||||||
<h2>Fashion Rebel</h2>
|
|
||||||
<div className="clothing">
|
|
||||||
<img src={rainbow} alt="Rainbow colored clothing"/>
|
|
||||||
<img src={japanese} alt="Purple shirt with Japanese text"/>
|
|
||||||
</div>
|
|
||||||
<p>
|
|
||||||
Clothes shopping is a great knack of mine. I'm skilled in finding all kinds of weird clothes to wear.
|
|
||||||
I like doing stuff that makes me stand out, as you can see from the gallery.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
My store of choice is <ExternalLink href="https://www.ebay.com/usr/tymur999">Ebay</ExternalLink>, where I love thrifting out-of-this-world outfits for a low price.
|
|
||||||
EBay is a place for me to liquidate my assets, which is random items around the house.
|
|
||||||
My favorite thing about Ebay is that they have almost every clothing brand, typically at reduced prices due to use.
|
|
||||||
</p>
|
|
||||||
</section>
|
</section>
|
||||||
<div className="edge"/>
|
<div className="edge"/>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
@use "../nav/nav.scss";
|
@use "../nav/nav.scss";
|
||||||
|
$paragraph: 20px;
|
||||||
|
$max-width: 600px;
|
||||||
|
|
||||||
.about-page {
|
.about-page {
|
||||||
color: white;
|
color: white;
|
||||||
@@ -24,24 +26,28 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-family: Neuton;
|
font-family: Neuton;
|
||||||
|
line-height: 40px;
|
||||||
|
|
||||||
img:not(.self) {
|
img:not(.self) {
|
||||||
border: 2px white solid;
|
border: 2px white solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
text-indent: 2 * nav.$padding;
|
text-indent: 30px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
max-width: 600px;
|
max-width: $max-width;
|
||||||
line-height: 40px;
|
font-size: $paragraph;
|
||||||
font-size: 20px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 40px;
|
font-size: $paragraph * 2;
|
||||||
}
|
}
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 30px;
|
font-size: $paragraph * 1.5;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
font-size: $paragraph * 1.1;
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +56,7 @@
|
|||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.clothing {
|
.clothing, .computers {
|
||||||
margin: 15px 0;
|
margin: 15px 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -61,6 +67,27 @@
|
|||||||
width: 33%;
|
width: 33%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.computers {
|
||||||
|
// select second
|
||||||
|
img:not(:first-child) {
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.external-link {
|
.external-link {
|
||||||
text-decoration: underline !important;
|
text-decoration: underline !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
font-size: $paragraph;
|
||||||
|
max-width: $max-width;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
BIN
src/img/2025-10-03-02-20-50-077.jpg
Normal file
BIN
src/img/2025-10-03-02-20-50-077.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 817 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.9 MiB |
BIN
src/img/IMG_3071.jpg
Executable file
BIN
src/img/IMG_3071.jpg
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
BIN
src/img/IMG_3095.jpg
Executable file
BIN
src/img/IMG_3095.jpg
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 5.6 MiB |
BIN
src/img/military.jpg
Executable file
BIN
src/img/military.jpg
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
BIN
src/img/nutrivend.jpeg
Executable file
BIN
src/img/nutrivend.jpeg
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
14
src/index.d.ts
vendored
14
src/index.d.ts
vendored
@@ -5,6 +5,20 @@ declare namespace NodeJS {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module '*.mdx' {
|
||||||
|
import {MDXProps} from "mdx/types";
|
||||||
|
|
||||||
|
let MDXComponent: (props: MDXProps) => JSX.Element;
|
||||||
|
export default MDXComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.md' {
|
||||||
|
import {MDXProps} from "mdx/types";
|
||||||
|
|
||||||
|
let MDXComponent: (props: MDXProps) => JSX.Element;
|
||||||
|
export default MDXComponent;
|
||||||
|
}
|
||||||
|
|
||||||
declare module '*.avif' {
|
declare module '*.avif' {
|
||||||
const src: string;
|
const src: string;
|
||||||
export default src;
|
export default src;
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import HtmlWebpackPlugin from "html-webpack-plugin";
|
|||||||
import MiniCssExtractPlugin from "mini-css-extract-plugin";
|
import MiniCssExtractPlugin from "mini-css-extract-plugin";
|
||||||
import ReactRefreshWebpackPlugin from "@pmmmwh/react-refresh-webpack-plugin";
|
import ReactRefreshWebpackPlugin from "@pmmmwh/react-refresh-webpack-plugin";
|
||||||
import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin";
|
import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin";
|
||||||
|
import {WebpackManifestPlugin} from "webpack-manifest-plugin";
|
||||||
import TerserPlugin from "terser-webpack-plugin";
|
import TerserPlugin from "terser-webpack-plugin";
|
||||||
|
import {Options} from '@mdx-js/loader';
|
||||||
import "webpack-dev-server";
|
import "webpack-dev-server";
|
||||||
|
|
||||||
const isProduction = process.env.NODE_ENV === "production";
|
const isProduction = process.env.NODE_ENV === "production";
|
||||||
@@ -34,7 +36,7 @@ const config: webpack.Configuration = {
|
|||||||
oneOf: [
|
oneOf: [
|
||||||
// Image assets
|
// Image assets
|
||||||
{
|
{
|
||||||
test: [/\.avif$/, /\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/, '/\.pdf$/'],
|
test: [/\.(avif|bmp|.gif|jpe?g|png|pdf)$/],
|
||||||
type: "asset",
|
type: "asset",
|
||||||
parser: {
|
parser: {
|
||||||
dataUrlCondition: {
|
dataUrlCondition: {
|
||||||
@@ -82,10 +84,35 @@ const config: webpack.Configuration = {
|
|||||||
],
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
!isProduction && "react-refresh/babel",
|
!isProduction && "react-refresh/babel",
|
||||||
].filter(Boolean),
|
],
|
||||||
cacheDirectory: true,
|
cacheDirectory: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{ // mdx.js integration
|
||||||
|
test: /\.mdx?$/,
|
||||||
|
include: path.resolve(import.meta.dirname, "src"),
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: "babel-loader",
|
||||||
|
options: {
|
||||||
|
presets: [
|
||||||
|
"@babel/preset-env",
|
||||||
|
["@babel/preset-react", { runtime: "automatic" }],
|
||||||
|
"@babel/preset-typescript",
|
||||||
|
],
|
||||||
|
plugins: [
|
||||||
|
!isProduction && "react-refresh/babel",
|
||||||
|
],
|
||||||
|
cacheDirectory: true,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
loader: "@mdx-js/loader",
|
||||||
|
options: <Options> {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
// CSS Loader
|
// CSS Loader
|
||||||
{
|
{
|
||||||
test: /\.css$/,
|
test: /\.css$/,
|
||||||
@@ -114,20 +141,22 @@ const config: webpack.Configuration = {
|
|||||||
template: path.resolve(import.meta.dirname, "public/index.html"),
|
template: path.resolve(import.meta.dirname, "public/index.html"),
|
||||||
inject: true,
|
inject: true,
|
||||||
}),
|
}),
|
||||||
|
new WebpackManifestPlugin({
|
||||||
|
fileName: "manifest.json",
|
||||||
|
publicPath: "/"
|
||||||
|
}),
|
||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
"process.env": JSON.stringify(process.env),
|
"process.env": JSON.stringify(process.env),
|
||||||
}),
|
}),
|
||||||
new ForkTsCheckerWebpackPlugin({
|
new ForkTsCheckerWebpackPlugin({
|
||||||
async: !isProduction,
|
async: !isProduction,
|
||||||
}),
|
}),
|
||||||
isProduction
|
isProduction && new MiniCssExtractPlugin({
|
||||||
&& new MiniCssExtractPlugin({
|
|
||||||
filename: "static/css/[name].[contenthash:8].css",
|
filename: "static/css/[name].[contenthash:8].css",
|
||||||
chunkFilename: "static/css/[name].[contenthash:8].chunk.css",
|
chunkFilename: "static/css/[name].[contenthash:8].chunk.css",
|
||||||
}),
|
}),
|
||||||
!isProduction
|
!isProduction && new ReactRefreshWebpackPlugin(),
|
||||||
&& new ReactRefreshWebpackPlugin(),
|
],
|
||||||
].filter(Boolean),
|
|
||||||
devServer: {
|
devServer: {
|
||||||
historyApiFallback: true,
|
historyApiFallback: true,
|
||||||
port: 3000,
|
port: 3000,
|
||||||
|
|||||||
Reference in New Issue
Block a user