import { useEffect, useState } from "react"; interface MiniProject { title: string; description: string; image?: string; github?: string; reproduction?: string; why: string; note?: { color: string; content: string; }; } interface Experience { name: string; type: "language" | "service" | "platform" | "real life experience" | "roles"; description: string; image?: string; learned_at?: string; learned_from?: string; learned_because?: string; } function MiniProjectModal({ project, onClose, }: { project: MiniProject; onClose: () => void; }) { return (
e.stopPropagation()} > {/* Close Button */} {/* Image */} {project.image && (
{project.title}
)} {/* Content */}

{project.title}

{project.note && (

{project.note.content}

)}

Description

{project.description}

Why I Made This

{project.why}

{project.reproduction && (

How to Reproduce

                  {project.reproduction}
                
)} {project.github && ( View on GitHub )}
); } function ExperienceModal({ experience, onClose, }: { experience: Experience; onClose: () => void; }) { return (
e.stopPropagation()} > {/* Close Button */} {/* Content */}
{experience.image ? ( {experience.name} ) : ( getTypeIcon(experience.type) )}

{experience.name}

{getTypeIcon(experience.type)}{" "} {experience.type.charAt(0).toUpperCase() + experience.type.slice(1)}

{experience.description && (

Description

{experience.description}

)} {experience.learned_at && (

πŸ“… When I Learned It

{experience.learned_at}

)} {experience.learned_from && (

πŸ‘¨β€πŸ« How I Learned It

{experience.learned_from}

)} {experience.learned_because && (

πŸ’‘ Why I Learned It

{experience.learned_because}

)}
); } function getTypeIcon(type: Experience["type"]) { switch (type) { case "language": return "πŸ’»"; case "service": return "☁️"; case "platform": return "πŸš€"; case "real life experience": return "🌍"; case "roles": return "πŸ‘”"; default: return "πŸ“¦"; } } function getTypeColor(type: Experience["type"]) { switch (type) { case "language": return "bg-blue-500/20"; case "service": return "bg-purple-500/20"; case "platform": return "bg-green-500/20"; case "real life experience": return "bg-orange-500/20"; case "roles": return "bg-pink-500/20"; default: return "bg-gray-500/20"; } } function MiniProjectCard({ project, onClick, }: { project: MiniProject; onClick: () => void; }) { return (
{project.image && (
{project.title}
)}

{project.title}

{project.description}

Click to learn more
); } function ExperienceCard({ experience, onClick, }: { experience: Experience; onClick?: () => void; }) { const isClickable = !!( experience.learned_at || experience.learned_from || experience.learned_because ); return (
{experience.image ? ( {experience.name} ) : ( getTypeIcon(experience.type) )} {isClickable && (
)}

{experience.name}

{experience.description && (

{experience.description}

)}
{isClickable && (
)}
); } function ProjectCard({ project }: { project: Project }) { return (
{project.image && (
{project.name}
)}

{project.name}

{project.description}

Visit {project.open_source && ( )}
); } function App() { const [status, setStatus] = useState(""); const [borderStatus, setBorderStatus] = useState("border-gray-700"); const [glowColor, setGlowColor] = useState("rgba(55, 65, 81, 0.5)"); const [statusMessage, setStatusMessage] = useState("Breaking SHSF"); const [messageIndex, setMessageIndex] = useState(0); const [displayMessage, setDisplayMessage] = useState(""); const [isScrambling, setIsScrambling] = useState(false); const [showOldNames, setShowOldNames] = useState(false); const [selectedMiniProject, setSelectedMiniProject] = useState(null); const [selectedExperience, setSelectedExperience] = useState(null); const oldUsernames = [ "getspaced (ingame)", "SpaceΒ² (alternative)", "Space-Banane (2022-2024)", ]; const rotatingMessages = [ "Bricking Esp32's 🧱", "Buy me a White Redbull⁉️", "Testing in production πŸ§ͺ", "Shipping bug fixes πŸ“¦", "Not learning Rust πŸ¦€", "Pushing before Copilot's Review βœ…", "Breaking SHSF 🚧", "No debugger attached 🐞", "Asking ChatGPT for help πŸ€–", "Refactoring for the 10th time πŸ”„", "Writing documentation πŸ₯Ή", "Removing Comments 🧹", "Collecting Spotify hours 🎡", ]; const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+[]{}|;:',.<>?/`~" + "πŸ§±β‰οΈπŸ§ͺπŸ“¦πŸ¦€βœ…πŸš§πŸžπŸ€–πŸ”„πŸ₯ΉπŸ§ΉπŸŽ΅"; useEffect(() => { if (status === "online") { setBorderStatus("border-green-500"); setGlowColor("rgba(34, 197, 94, 0.5)"); setStatusMessage("Reachable"); } else if (status === "offline") { setBorderStatus("border-gray-500"); setGlowColor("rgba(107, 114, 128, 0.5)"); setStatusMessage("Probably Away"); } else if (status === "dnd") { setBorderStatus("border-red-600"); setGlowColor("rgba(220, 38, 38, 0.5)"); setStatusMessage("Not Reachable"); } else if (status === "idle") { setBorderStatus("border-yellow-500"); setGlowColor("rgba(234, 179, 8, 0.5)"); setStatusMessage("Doing anything but work"); } else { setBorderStatus("border-gray-700"); setGlowColor("rgba(55, 65, 81, 0.5)"); setStatusMessage("Breaking SHSF"); } }, [status]); useEffect(() => { fetch( "https://shsf-api.reversed.dev/api/exec/6/c084ec4a-1b20-491e-ab2e-67c5fa8881e6", ) .then((res) => res.json()) .then((data) => { setStatus(data.status); }) .catch((err) => { console.error(err); setStatus("offline"); }); }, []); // Scramble effect useEffect(() => { const targetMessage = rotatingMessages[messageIndex]; if (isScrambling) { let iteration = 0; const scrambleInterval = setInterval(() => { setDisplayMessage( targetMessage .split("") .map((char, index) => { if (index < iteration) { return targetMessage[index]; } if (char === " " || /[\u{1F000}-\u{1F9FF}]/u.test(char)) { return char; } return characters[Math.floor(Math.random() * characters.length)]; }) .join(""), ); if (iteration >= targetMessage.length) { clearInterval(scrambleInterval); setIsScrambling(false); } iteration += 1 / 3; }, 30); return () => clearInterval(scrambleInterval); } else { setDisplayMessage(targetMessage); } }, [messageIndex, isScrambling]); // Rotating message effect useEffect(() => { const messageInterval = setInterval(() => { setIsScrambling(true); setMessageIndex((prev) => (prev + 1) % rotatingMessages.length); }, 7000); return () => { clearInterval(messageInterval); }; }, []); return (
{/* Background Grid */}
{/* Hero Section */}
Space
{/* Rotating Message Bubble (Left Side) */}
{/* Arrow pointing to profile */}

{displayMessage || rotatingMessages[0]}

{/* Status Bubble (Right Side) */}
{/* Arrow pointing to profile */}

Currently{" "} {statusMessage}
on Discord

Hey, I'm{" "} setShowOldNames(true)} onMouseLeave={() => setShowOldNames(false)} > SpaceΒ² {showOldNames && (

Also known as:

    {oldUsernames.map((name, index) => (
  • {name}
  • ))}
)}

A{" "} Self-proclaimed {" "} Developer breaking things to see how they work.

{/* About Section */}

About Me

What i do and who i am.

I'm a Developer from Germany. I love doing full-stack web development, tinkering with hardware, and 3D printing cool stuff.

I focus on building projects that i need, and that don't already exist.

{/* Hardware Mods & Builds Section */}

Hardware Stuff

The lion is concerned with a 5v rated LED connected to 12V

When im not breaking Typescript im usually playing with{" "} Arduinos {" "} and{" "} ESP32s. I love interacting via Software with self-made hardware.

I've built some Smarthome sensors myself, including a few little bluetooth proxys that also serve as temperature sensors.

I love using ESP32s because they're stupidly easy to build with & the bar to entry is stupidly low with a stupid amount of tutorials.

{/* 3D Printing Section */}

3D Printing

Plastic on a Spool -{">"} Plasic in a Shape

I run a modded Creality Ender 3 V1 with a{" "} BLTouch{" "} for auto bed leveling, all managed through{" "} OctoPrint . I slice my stuff using{" "} OrcaSlicer {" "} because Cura's UI gives me a flashbang everytime i open it.

I would lie if i said i print useful stuff. Most of the stuff i print is for organising stuff and a few fun prints here and there.

{/* Goals Section */}

My Goals

future things

πŸš€

Not Just Semi-Fullstack

I want to work more with Serverless Architectures and Cloud Services to build scalable applications.

πŸ’»

Contribute More to Open Source

I want to commit more to Open-Source Projects. That's it...

⚑

Expand on Existing Projects

I want to make SHSF more stable and usable.

πŸ¦€

Explore the Unknown

Rust?πŸ‘€

{/* Projects Section */}

Favourite Projects

Personal Faviorite? Uhhhhh....

{projects.map((project, index) => ( ))}
{/* Mini Projects Section */}

Mini Projects

Small experiments and fun projects I've built along the way

{miniProjects.map((project, index) => ( setSelectedMiniProject(project)} /> ))}
{selectedMiniProject && ( setSelectedMiniProject(null)} /> )} {selectedExperience && ( setSelectedExperience(null)} /> )} {/* Experience Section */}

Experience

Technologies, platforms, and roles I've worked with

{Object.entries( experiences.reduce( (acc, exp) => { if (!acc[exp.type]) acc[exp.type] = []; acc[exp.type].push(exp); return acc; }, {} as Record, ), ).map(([type, items]) => (

{getTypeIcon(type as Experience["type"])}{" "} {type.charAt(0).toUpperCase() + type.slice(1)}

{items.map((exp, index) => ( setSelectedExperience(exp)} /> ))}
))}

And a bunch of stuff i probably also forgot...

{/* Contact Section */}

Let's Connect

Got anything on your mind? Shoot me a DM or Email.

{/* Footer */}
); } interface Project { name: string; description: string; image?: string; link: string; open_source: false | { link: string }; rounded?: boolean; } const projects: Project[] = [ { name: "BetterNews", description: "A news feed where you submit the news.", image: "https://betternews.app/assets/icon.png", open_source: false, link: "https://betternews.app", }, { name: "SHSF", description: 'Self-hostable "Cloud Functions" on your own hardware.', link: "https://github.com/Space-Banane/shsf", open_source: { link: "https://github.com/Space-Banane/shsf" }, image: "https://cdn.reversed.dev/pictures/shsf/SHSF.png", }, { name: "Thoughtful", description: "A minimalistic and privacy-focused idea-taking app.", link: "https://github.com/Space-Banane/thoughtful", open_source: { link: "https://github.com/Space-Banane/thoughtful" }, image: "https://em-content.zobj.net/source/microsoft-3D-fluent/433/thinking-face_1f914.png", }, { name: "3D Print Card", description: "Showcase Your 3D Prints Beautifully", link: "https://card.peakprinting.top", image: "https://card.peakprinting.top/icon.png", open_source: { link: "https://github.com/Space-Banane/imsoprintingit" }, }, { name: "Whatsapp-Chat-Analyzer", description: "Analyze your Whatsapp chats with ease. Get insights, stats and more.", image: "https://cdn.reversed.dev/pictures/wca.png", open_source: { link: "https://github.com/Space-Banane/whatsapp-stats" }, link: "https://whatstat.reversed.dev", } ]; const miniProjects: MiniProject[] = [ { title: "Discord Status to Website", description: "Display your Discord status on your personal website.", why: "I wanted to show my Discord status here on my portfolio.", github: "https://github.com/Space-Banane/shsf-discord-status", note: { color: "red", content: "Requires SHSF to run", }, image: "https://github.com/Space-Banane/shsf-discord-status/blob/main/Discord%20Status%20Image.png?raw=true", }, { title: "Mirror GoXLR to Discord", description: "Muting your Mic Channel mutes you on Discord.", why: "When i mute myself on my GoXLR, my friends don't know that, now they do.", github: "https://github.com/Space-Banane/mirror-goxlr-to-discord", note: { color: "yellow", content: "Experimental - This might interfere with some other Hotkeys you set, or Applications that listen to those Hotkeys", }, image: "https://github.com/Space-Banane/mirror-goxlr-to-discord/blob/main/Discord%20x%20GoXLR.png?raw=true", }, { title: "Octo-Activity", description: "Show your 3D Printer activity as Discord Status.", why: "I wanted to show off my 3D Printer activity on Discord.", github: "https://github.com/Space-Banane/discord-octo-activity", image: "https://github.com/Space-Banane/discord-octo-activity/blob/main/Discord%20Octo%20Activity.png?raw=true", }, { title: "Fishing Rod Automation Raft", description: "Automate fishing in Raft with this simple script.", why: "Fishing while Shitting is kinda difficult.", github: "https://github.com/Space-Banane/raft-fishing", note: { color: "yellow", content: "Might interfere with other Applications that use Mouse/Keyboard input. In case of trust issues, move the mouse to the bottom right corner to stop the script.", }, image: "https://github.com/Space-Banane/raft-fishing/blob/main/Raft%20Fishing%20Guide%20-%20cover.jpg?raw=true", }, { title: "Nvidia-SMI Server", description: "A simple server to expose Nvidia-SMI data via HTTP.", why: "I wanted to monitor my GPU usage remotely without installing additional software.", github: "https://github.com/Space-Banane/nvidia-smi-server", image: "https://github.com/Space-Banane/nvidia-smi-server/blob/main/Nvidia%20-%20SMI.png?raw=true", }, { title: "Lego Set to STL", description: "Convert Lego set instructions to STL files for 3D printing.", why: "A friend of mine searched for a website that does something like this, so i made one.", github: "https://github.com/Space-Banane/lego-to-stl", image: "https://shx.reversed.dev/u/44nekH.png", }, { title: "Thoughtful Extention for Raycast", description: "Quickly add ideas to Thoughtful from Raycast.", why: "I use Raycast a lot, so having a quick way to add ideas to Thoughtful is super convenient.", github: "https://gitea.reversed.dev/space/thoughtful-extention", note: { color: "blue", content: "Requires Thoughtful & Raycast to use lol", }, image: "https://shx.reversed.dev/u/bCOaZt.png" }, { title: "Big File Generator", description: "Generate large files filled with random data for testing purposes.", why: "SMB performance test, i did NOT have a big file lying around.", github: "https://gitea.reversed.dev/space/big-file-gen", image: "https://em-content.zobj.net/source/microsoft-3D-fluent/433/file-folder_1f4c1.png", }, { title: "Active Directory Profile Picture Management", description: "Manage and update Active Directory profile pictures easily.", why: "I wanted a simple way to manage profile pictures in Active Directory. (home lab stuff)", github: "https://github.com/Space-Banane/ADPPM", image: "https://shx.reversed.dev/u/RSqlwN.png", note: { color: "red", content: "Work in Progress + Requires Active Directory Environment + Requires Go to be installed", }, }, { title: "QrCode Generator", description: "Vue.JS based QR Code Generator with a bit of customization.", why: "I wanted a simple and customizable QR code generator.", github: "https://github.com/reversed-dev/qr-code-gen", image: "https://cdn.reversed.dev/pictures/qrcode.jpeg", }, ]; const experiences: Experience[] = [ { name: "TypeScript", type: "language", description: "My go-to language for building scalable web applications with type safety.", image: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/typescript/typescript-original.svg", learned_because: "I HATE JavaScript, this makes it minimally better", }, { name: "JavaScript", type: "language", description: "The foundation of web development.", image: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/javascript/javascript-original.svg", }, { name: "Python", type: "language", description: "Used for automation scripts, data processing, and backend services.", image: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/python/python-original.svg", }, { name: "Go", type: "language", description: "For building fast and efficient backend services.", image: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/go/go-original.svg", }, { name: "Lua", type: "language", description: "Scripting and embedded applications.", image: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/lua/lua-original.svg", learned_from: "Youtube & Docs", learned_because: "Used in some Robots in a Minecraft mod called CC:Tweaked", }, { name: "React", type: "platform", description: "Building interactive user interfaces with modern React patterns and hooks.", image: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/react/react-original.svg", }, { name: "Vue.js", type: "platform", description: "Creating reactive web applications with Vue's elegant API.", image: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/vuejs/vuejs-original.svg", }, { name: "Docker", type: "service", description: "Containerizing applications for consistent deployment across environments.", image: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/docker/docker-original.svg", }, { name: "PostgreSQL", type: "service", description: "Reliable relational database for complex data storage needs.", image: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/postgresql/postgresql-original.svg", }, { name: "Redis", type: "service", description: "High-performance caching and data structure store.", image: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/redis/redis-original.svg", }, { name: "MariaDB", type: "service", description: "Open-source relational database management system.", image: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/mariadb/mariadb-original.svg", }, { name: "Proxy Software", type: "service", description: "Configuring and managing reverse proxies for web applications.", }, { name: "Home Assistant", type: "platform", description: "Building smart home automations and integrating various IoT devices.", image: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/home-assistant.png", }, { name: "ESPHome", type: "platform", description: "Programming ESP32 and ESP8266 microcontrollers for custom smart home sensors.", image: "https://esphome.io/_images/logo.svg", }, { name: "Troubleshooting Hardware", type: "real life experience", description: "Diagnosing and fixing hardware issues, from bricked microcontrollers to server problems.", }, { name: "Node.js", type: "platform", description: "Building backend services and APIs with Express and Fastify.", image: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/nodejs/nodejs-original.svg", }, { name: "Immich", type: "platform", description: "Self-hosted photo and video management solution.", image: "https://avatars.githubusercontent.com/u/109746326?v=4", learned_because: "I hate OneDrive", }, { name: "Pangolin", type: "platform", description: "Proxy solution for network management.", image: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/pangolin.svg", learned_because: "My old proxy did NOT work super well with authentication.", }, { name: "Nginx", type: "platform", description: "Proxy solution for network management. (old proxy)", image: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/nginx/nginx-original.svg", }, { name: "Minecraft Servers", type: "platform", description: "Hosting and managing multiplayer game servers.", image: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/minecraft.png", }, { name: "Gitea", type: "platform", description: "Self-hosted Git service for version control.", image: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/gitea.png", }, { name: "Serverless Functions", type: "platform", description: "Building scalable cloud functions and microservices. (SHSF)", image: "https://cdn.reversed.dev/pictures/shsf/SHSF%20SMALL%20TRANSPARENT.png", }, { name: "Cloud Infrastructure", type: "platform", description: "Managing and deploying applications on cloud platforms. (GCP, AWS, DigitalOcean)", }, { name: "Git", type: "service", description: "Version control for collaborative development and open-source contributions.", image: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/git/git-original.svg", }, { name: "ShareX", type: "platform", description: "Custom uploaders and automation workflows for screenshots and file sharing.", image: "https://upload.wikimedia.org/wikipedia/commons/d/d1/ShareX_Logo.png", }, { name: "Zipline", type: "platform", description: "ShareX companion for self-hosted file uploads.", image: "https://media.sys.truenas.net/apps/zipline/icons/icon.png", }, { name: "Tailwind CSS", type: "platform", description: "Utility-first CSS framework for rapid UI development.", image: "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/Tailwind_CSS_Logo.svg/2560px-Tailwind_CSS_Logo.svg.png", }, { name: "Proxmox VE", type: "platform", description: "Virtualization management platform for running VMs and containers.", image: "https://media.printables.com/media/prints/543748/images/4374616_04ed4585-3662-4652-a84d-04621cb9f709/thumbs/inside/1280x960/png/proxmox.webp", }, { name: "MongoDB", type: "service", description: "NoSQL database for flexible document-based data storage.", image: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/mongodb/mongodb-original.svg", learned_because: "I didn't wanna mess around with schemas for a project.", learned_at: "09.01.2026", }, { name: "Insomnia", type: "platform", description: "REST API client for testing and debugging HTTP requests.", image: "https://s3.amazonaws.com/s3.roaringapps.com/assets/icons/1561251841927-Insomnia.png", learned_because: "Postman is bloatware", }, ]; export default App;