rename terminal theme to web, make it the default, drop the mobile home screen, and rebuild the web shell as a light/dark glassmorphism layout
This commit is contained in:
parent
32d622f80e
commit
d947ecfb1a
21 changed files with 1707 additions and 2978 deletions
386
src/app/components/WebLayout.tsx
Normal file
386
src/app/components/WebLayout.tsx
Normal file
|
|
@ -0,0 +1,386 @@
|
|||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import type { ReactNode } from "react";
|
||||
import JokerLogo from "./JokerLogo";
|
||||
import ServiceButton from "./ServiceButton";
|
||||
import ContributionHeatmap from "./ContributionHeatmap";
|
||||
import Clock from "./Clock";
|
||||
import { useTheme } from "./useTheme";
|
||||
import { useColorScheme } from "./useColorScheme";
|
||||
import { socials, codingProjects, techProjects, friends } from "../data";
|
||||
|
||||
const NAV = [
|
||||
{ id: "overview", label: "Overview" },
|
||||
{ id: "services", label: "Services" },
|
||||
{ id: "activity", label: "Activity" },
|
||||
{ id: "projects", label: "Projects" },
|
||||
{ id: "hardware", label: "Hardware" },
|
||||
{ id: "friends", label: "Friends" },
|
||||
];
|
||||
|
||||
function Section({
|
||||
id,
|
||||
eyebrow,
|
||||
title,
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
id?: string;
|
||||
eyebrow: string;
|
||||
title: string;
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<section id={id} className={"web-section glass" + (className ? ` ${className}` : "")}>
|
||||
<header className="web-section-head">
|
||||
<span className="web-eyebrow">{eyebrow}</span>
|
||||
<h2 className="web-section-title">{title}</h2>
|
||||
</header>
|
||||
{children}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function Socials() {
|
||||
return (
|
||||
<div className="social-buttons">
|
||||
{socials.map((s) => (
|
||||
<a
|
||||
key={s.name}
|
||||
href={s.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="social-button"
|
||||
>
|
||||
<Image src={s.icon} alt={s.name} width={16} height={16} className="social-icon" />
|
||||
<span className="social-label">{s.name}</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Services() {
|
||||
return (
|
||||
<div className="services-buttons services-main">
|
||||
<ServiceButton
|
||||
url="https://proxmox.dvorakmortonxd.dev/"
|
||||
className="proxmox"
|
||||
icon="🖥️"
|
||||
name="Proxmox"
|
||||
desc="Server Management"
|
||||
access="private"
|
||||
disabled
|
||||
/>
|
||||
<ServiceButton
|
||||
url="https://ai.dvorakmortonxd.dev/"
|
||||
className="ai"
|
||||
icon="🦾"
|
||||
name="Llama.cpp"
|
||||
desc="Local AI Server"
|
||||
access="on_request"
|
||||
/>
|
||||
<ServiceButton
|
||||
url="https://jelly.dvorakmortonxd.dev/"
|
||||
className="jellyfin"
|
||||
icon="🎬"
|
||||
name="Jellyfin"
|
||||
desc="Local Media Server"
|
||||
access="on_request"
|
||||
/>
|
||||
<ServiceButton
|
||||
url="https://discord.gg/vyvhk7d8bX"
|
||||
checkUrl="minecraft://mc.dvorakmortonxd.dev:25565"
|
||||
className="pterodactyl"
|
||||
icon="🎮"
|
||||
name="SMP"
|
||||
desc="My Survival Minecraft Server"
|
||||
access="on_request"
|
||||
/>
|
||||
<ServiceButton
|
||||
url="https://navidrome.dvorakmortonxd.dev/"
|
||||
className="funkwhale"
|
||||
icon="🎸"
|
||||
name="Navidrome"
|
||||
desc="Music Streaming"
|
||||
access="private"
|
||||
/>
|
||||
<ServiceButton
|
||||
url="https://git.dvorakmortonxd.dev"
|
||||
className="gitdxd"
|
||||
icon="🐙"
|
||||
name="GitDXD"
|
||||
desc="Best Git Hosting OAT"
|
||||
access="public"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Gym() {
|
||||
const lifts = [
|
||||
{ icon: "/squat.svg", label: "SQUAT", weight: "125kg", date: "5.1.2025" },
|
||||
{ icon: "/bench.svg", label: "BENCH", weight: "111kg", date: "29.5.2026" },
|
||||
{ icon: "/deadlift.svg", label: "DEADLIFT", weight: "165kg", date: "17.12.2024" },
|
||||
];
|
||||
return (
|
||||
<div className="gym-grid">
|
||||
{lifts.map((l) => (
|
||||
<div key={l.label} className="gym-item">
|
||||
<Image src={l.icon} alt={l.label} width={48} height={48} className="gym-icon" />
|
||||
<div className="gym-label">{l.label}</div>
|
||||
<div className="gym-weight">{l.weight}</div>
|
||||
<div className="gym-date">{l.date}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function FeatureShot({
|
||||
src,
|
||||
alt,
|
||||
width,
|
||||
height,
|
||||
}: {
|
||||
src: string;
|
||||
alt: string;
|
||||
width: number;
|
||||
height: number;
|
||||
}) {
|
||||
return (
|
||||
<div className="web-shot">
|
||||
<Image
|
||||
src={src}
|
||||
alt={alt}
|
||||
width={width}
|
||||
height={height}
|
||||
style={{ width: "100%", height: "auto", display: "block" }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function WebLayout() {
|
||||
const { toggle } = useTheme();
|
||||
const { scheme, toggle: toggleScheme } = useColorScheme();
|
||||
const dark = scheme === "dark";
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="web-bg" aria-hidden="true" />
|
||||
|
||||
<div className="web-root">
|
||||
<aside className="web-sidebar glass">
|
||||
<div className="web-brand">
|
||||
<JokerLogo />
|
||||
<div className="web-brand-text">
|
||||
<span className="web-brand-name">dvorakmortonxd.dev</span>
|
||||
<span className="web-brand-tag">I use gentoo btw</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav className="web-nav" aria-label="Sections">
|
||||
{NAV.map((n) => (
|
||||
<a key={n.id} href={`#${n.id}`}>
|
||||
{n.label}
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<div className="web-controls">
|
||||
<button
|
||||
type="button"
|
||||
className="web-ctl"
|
||||
onClick={toggleScheme}
|
||||
aria-pressed={dark}
|
||||
title="Toggle light / dark mode"
|
||||
>
|
||||
<span className="web-ctl-icon" aria-hidden="true">
|
||||
{dark ? "☾" : "☀"}
|
||||
</span>
|
||||
<span className="web-ctl-label">{dark ? "Dark" : "Light"}</span>
|
||||
<span className={"web-switch" + (dark ? " on" : "")} aria-hidden="true">
|
||||
<span className="web-switch-knob" />
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="web-ctl web-ctl-desktop"
|
||||
onClick={toggle}
|
||||
title="Switch to the desktop theme"
|
||||
>
|
||||
<span className="web-ctl-icon" aria-hidden="true">
|
||||
❖
|
||||
</span>
|
||||
<span className="web-ctl-label">Desktop</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="web-side-foot">
|
||||
<Clock className="web-clock" />
|
||||
<a href="mailto:dvorak@dvorakmortonxd.dev">dvorak@dvorakmortonxd.dev</a>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main className="web-main">
|
||||
<header id="overview" className="web-hero glass">
|
||||
<span className="web-eyebrow">README.MD</span>
|
||||
<h1 className="web-title">$ whoami</h1>
|
||||
<p className="web-lead">
|
||||
Welcome to my personal website! Here I show off my projects and the hardware I
|
||||
own, as well as my self-hosted services.
|
||||
<span className="cursor-blink" />
|
||||
</p>
|
||||
<div className="web-hero-actions">
|
||||
<a className="web-pill" href="#projects">
|
||||
View projects
|
||||
</a>
|
||||
<a className="web-pill ghost" href="#services">
|
||||
Self-hosted services
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div className="web-tiles">
|
||||
<article id="now" className="web-tile glass">
|
||||
<h3 className="web-tile-title">now.txt</h3>
|
||||
<p className="web-tile-text">
|
||||
I'm currently hosting an SMP (dm me on discord). Also I'm pretty much
|
||||
cooking daily, because im bulking through out the non-summer seasons. And me
|
||||
and my pal <a href="https://skopec.dev">Pepa</a> are working on an education
|
||||
app so we can study more efficiently, It's called{" "}
|
||||
<a href="https://git.dvorakmortonxd.dev/edu/maturita.c">maturita.c</a>!
|
||||
</p>
|
||||
</article>
|
||||
|
||||
<article className="web-tile glass">
|
||||
<h3 className="web-tile-title">gym_sbd.db</h3>
|
||||
<Gym />
|
||||
</article>
|
||||
|
||||
<article className="web-tile glass">
|
||||
<h3 className="web-tile-title">socials.js</h3>
|
||||
<Socials />
|
||||
<div className="mail-contact">
|
||||
mail if u ever wanna contact me:{" "}
|
||||
<a href="mailto:dvorak@dvorakmortonxd.dev">dvorak@dvorakmortonxd.dev</a>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<Section id="services" eyebrow="SELF-HOSTED" title="Services">
|
||||
<Services />
|
||||
</Section>
|
||||
|
||||
<Section id="activity" eyebrow="GITDXD.GIT" title="Contribution activity">
|
||||
<ContributionHeatmap />
|
||||
</Section>
|
||||
|
||||
<Section id="projects" eyebrow="PROJECTS.DOCX" title="Things I've worked on">
|
||||
<div className="project-grid">
|
||||
{codingProjects.map((project, idx) => (
|
||||
<a
|
||||
key={idx}
|
||||
href={project.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="project-card"
|
||||
>
|
||||
<div
|
||||
className="project-image"
|
||||
style={{ backgroundImage: `url(${project.img})` }}
|
||||
/>
|
||||
<h4 className="project-title">{project.title}</h4>
|
||||
<p className="project-desc">{project.desc}</p>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<Section id="hardware" eyebrow="TECH_LIST.JSON" title="Hardware I own">
|
||||
<div className="project-grid">
|
||||
{techProjects.map((project) => (
|
||||
<div key={project.title} className="project-card">
|
||||
<div
|
||||
className="project-image"
|
||||
style={{ backgroundImage: `url(${project.image})` }}
|
||||
/>
|
||||
<h4 className="project-title">{project.title}</h4>
|
||||
<p className="project-desc">{project.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<div className="web-split">
|
||||
<Section eyebrow="REVIVAL.INC" title="Revival Inc." className="web-feature">
|
||||
<FeatureShot
|
||||
src="/revivalinc.webp"
|
||||
alt="Revival Inc. thumbnail"
|
||||
width={768}
|
||||
height={576}
|
||||
/>
|
||||
<p className="web-feature-text">
|
||||
A game I made for the game jam "Mini Jame Gam #55", the theme was
|
||||
Necromancy and the special item was Milk, the game also includes a tutorial so
|
||||
if you wanna try it do it. Check it out at{" "}
|
||||
<a href="https://martin-dv.itch.io/revival-inc">itch.io</a> or play{" "}
|
||||
<a href="https://dvorakmortonxd.dev/revival-inc">here</a>.
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
<Section eyebrow="RUSTYWOLF.RS" title="Introducing RustyWolf" className="web-feature">
|
||||
<FeatureShot
|
||||
src="/RustyWolfPreview.webp"
|
||||
alt="RustyWolf Browser Preview"
|
||||
width={1280}
|
||||
height={720}
|
||||
/>
|
||||
<p className="web-feature-text">
|
||||
A lightweight browser made in Rust with WebKitGTK. It's the successor to my
|
||||
previous project Venturesome, aiming to provide a fast and minimalist browsing
|
||||
experience — perfect for old machines that struggle with modern browsers.
|
||||
Check it out on{" "}
|
||||
<a href="https://git.dvorakmortonxd.dev/dvorakmortonxd/RustyWolf">GitDXD</a>.
|
||||
</p>
|
||||
</Section>
|
||||
</div>
|
||||
|
||||
<Section id="friends" eyebrow="FRIENDS.TSX" title="Friend's websites and projects">
|
||||
<div className="services-buttons">
|
||||
{friends.map((friend, idx) => (
|
||||
<ServiceButton
|
||||
key={idx}
|
||||
url={friend.realUrl || friend.url}
|
||||
className="friend"
|
||||
icon={
|
||||
<Image
|
||||
src={friend.img}
|
||||
alt={friend.name}
|
||||
width={68}
|
||||
height={68}
|
||||
className="friend-icon"
|
||||
style={{ borderRadius: "50%" }}
|
||||
/>
|
||||
}
|
||||
name={friend.name}
|
||||
desc={friend.desc}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<footer className="web-footer glass">
|
||||
<span className="web-footer-label">v2.2.0</span>
|
||||
© 2025-2026 Martin Dvořák. All rights reserved (not really I dont care, just
|
||||
follow the GPL3.0 License)
|
||||
</footer>
|
||||
</main>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue