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-react": "^7.28.5",
|
||||
"@babel/preset-typescript": "^7.28.5",
|
||||
"@mdx-js/loader": "^3.1.1",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.6.2",
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"@testing-library/dom": "^10.4.1",
|
||||
@@ -45,6 +46,7 @@
|
||||
"@testing-library/react": "^16.3.2",
|
||||
"@testing-library/user-event": "^14.6.1",
|
||||
"@types/jest": "^30.0.0",
|
||||
"@types/mdx": "^2.0.13",
|
||||
"@types/node": "^25.3.3",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
@@ -71,7 +73,8 @@
|
||||
"typescript": "^5.9.3",
|
||||
"webpack": "^5.105.4",
|
||||
"webpack-cli": "^6.0.1",
|
||||
"webpack-dev-server": "^5.2.3"
|
||||
"webpack-dev-server": "^5.2.3",
|
||||
"webpack-manifest-plugin": "^6.0.1"
|
||||
},
|
||||
"babel": {
|
||||
"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 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 type {PropsWithChildren} from "react";
|
||||
import {PropsWithChildren} from "react";
|
||||
import About from "./About.mdx";
|
||||
|
||||
export default function AboutPage() {
|
||||
return <main className="about-page">
|
||||
<div className="edge"/>
|
||||
<section className="about-container">
|
||||
<img src={openingImage} alt="Tymur Arsentiev" className="self"/>
|
||||
<h1 className="title">Welcome to my blog and personal website!</h1>
|
||||
<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>
|
||||
<About components={{
|
||||
'a': ExternalLink,
|
||||
}}/>
|
||||
</section>
|
||||
<div className="edge"/>
|
||||
</main>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
@use "../nav/nav.scss";
|
||||
$paragraph: 20px;
|
||||
$max-width: 600px;
|
||||
|
||||
.about-page {
|
||||
color: white;
|
||||
@@ -24,24 +26,28 @@
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
font-family: Neuton;
|
||||
line-height: 40px;
|
||||
|
||||
img:not(.self) {
|
||||
border: 2px white solid;
|
||||
}
|
||||
|
||||
p {
|
||||
text-indent: 2 * nav.$padding;
|
||||
text-indent: 30px;
|
||||
margin: 10px;
|
||||
max-width: 600px;
|
||||
line-height: 40px;
|
||||
font-size: 20px;
|
||||
max-width: $max-width;
|
||||
font-size: $paragraph;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 40px;
|
||||
font-size: $paragraph * 2;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
.clothing {
|
||||
.clothing, .computers {
|
||||
margin: 15px 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -61,6 +67,27 @@
|
||||
width: 33%;
|
||||
}
|
||||
|
||||
.computers {
|
||||
// select second
|
||||
img:not(:first-child) {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.external-link {
|
||||
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' {
|
||||
const src: string;
|
||||
export default src;
|
||||
|
||||
@@ -4,7 +4,9 @@ import HtmlWebpackPlugin from "html-webpack-plugin";
|
||||
import MiniCssExtractPlugin from "mini-css-extract-plugin";
|
||||
import ReactRefreshWebpackPlugin from "@pmmmwh/react-refresh-webpack-plugin";
|
||||
import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin";
|
||||
import {WebpackManifestPlugin} from "webpack-manifest-plugin";
|
||||
import TerserPlugin from "terser-webpack-plugin";
|
||||
import {Options} from '@mdx-js/loader';
|
||||
import "webpack-dev-server";
|
||||
|
||||
const isProduction = process.env.NODE_ENV === "production";
|
||||
@@ -34,7 +36,7 @@ const config: webpack.Configuration = {
|
||||
oneOf: [
|
||||
// Image assets
|
||||
{
|
||||
test: [/\.avif$/, /\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/, '/\.pdf$/'],
|
||||
test: [/\.(avif|bmp|.gif|jpe?g|png|pdf)$/],
|
||||
type: "asset",
|
||||
parser: {
|
||||
dataUrlCondition: {
|
||||
@@ -82,10 +84,35 @@ const config: webpack.Configuration = {
|
||||
],
|
||||
plugins: [
|
||||
!isProduction && "react-refresh/babel",
|
||||
].filter(Boolean),
|
||||
],
|
||||
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
|
||||
{
|
||||
test: /\.css$/,
|
||||
@@ -114,20 +141,22 @@ const config: webpack.Configuration = {
|
||||
template: path.resolve(import.meta.dirname, "public/index.html"),
|
||||
inject: true,
|
||||
}),
|
||||
new WebpackManifestPlugin({
|
||||
fileName: "manifest.json",
|
||||
publicPath: "/"
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
"process.env": JSON.stringify(process.env),
|
||||
}),
|
||||
new ForkTsCheckerWebpackPlugin({
|
||||
async: !isProduction,
|
||||
}),
|
||||
isProduction
|
||||
&& new MiniCssExtractPlugin({
|
||||
isProduction && new MiniCssExtractPlugin({
|
||||
filename: "static/css/[name].[contenthash:8].css",
|
||||
chunkFilename: "static/css/[name].[contenthash:8].chunk.css",
|
||||
}),
|
||||
!isProduction
|
||||
&& new ReactRefreshWebpackPlugin(),
|
||||
].filter(Boolean),
|
||||
!isProduction && new ReactRefreshWebpackPlugin(),
|
||||
],
|
||||
devServer: {
|
||||
historyApiFallback: true,
|
||||
port: 3000,
|
||||
|
||||
Reference in New Issue
Block a user