Files
my-portfolio/app/routes/_index.tsx

503 lines
17 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { MetaFunction } from "@remix-run/node";
import { useEffect, useState } from "react";
import { json } from "@remix-run/node";
import { useLoaderData, Link } from "@remix-run/react";
export const meta: MetaFunction = () => {
return [
{ title: "Paul W." },
{ name: "description", content: "This is my Profile!" },
{
name: "keywords",
content: "Paul W, Paul W Portfolio, Paul W Profile, Paul W Remix",
},
];
};
interface BlogPost {
id: string;
title: string;
excerpt: string;
date: string;
access: string; // Where its located in the folder
tags: string[];
hide_date?: boolean;
}
export async function loader() {
const posts: BlogPost[] = [
{
id: "1",
title: "My First Post",
excerpt: "Yeah, as it says, this is my first post.",
date: "2024-01-23",
access: "myfirstpost",
tags: ["Hello, World!"],
hide_date: true,
},
// Add more posts here
];
return json({ posts });
}
export default function Index() {
const { posts } = useLoaderData<typeof loader>();
return (
<div className="relative flex min-h-screen flex-col items-center justify-center p-8 overflow-hidden">
<div className="absolute inset-0 z-0">
<div className="h-full w-full bg-black">
<div
className="absolute inset-0"
style={{
backgroundImage:
"linear-gradient(#ffffff15 1px, transparent 1px), linear-gradient(90deg, #ffffff15 1px, transparent 1px)",
backgroundSize: "20px 20px",
}}
/>
</div>
</div>
<div className="relative z-10 flex flex-col items-center gap-8 max-w-6xl w-full">
{/* Hero */}
<div className="text-center">
<div className="w-56 h-56 mb-6 overflow-hidden rounded-full">
<img
src="https://cdn.reversed.dev/pictures/cat.png"
alt="Paul W"
className="w-full h-full object-cover"
/>
</div>
<div className="flex items-center justify-center gap-3 mb-3">
<h1 className="text-6xl font-bold text-gray-100">Paul W.</h1>
</div>
<span className="px-3 py-1.5 text-base bg-blue-900 text-blue-100 rounded-full">
Developer & Gamer
</span>
<p className="text-xl text-gray-300 mt-4">Woah, thats me😲</p>
</div>
{/* About Section */}
<section className="w-full">
<h2 className="text-3xl font-bold mb-8 text-center text-gray-100 bg-gradient-to-r from-blue-500 to-purple-500 bg-clip-text text-transparent">
About Me
</h2>
<div
className="p-8 rounded-xl border border-gray-700 bg-white/5 backdrop-blur-lg
flex flex-col md:flex-row gap-8 items-center"
>
<div className="flex-1 space-y-6">
<p className="text-gray-300 text-lg leading-relaxed">
Hey! I'm <span className="underline font-bold">Paul</span>, a
passionate Developer from{" "}
<span className="bg-gradient-to-r from-gray-800 via-red-500 to-yellow-400 font-bold bg-clip-text text-transparent">
Germany
</span>{" "}
🇩🇪.
<span className="block mt-4">
I specialize in JavaScript and Node.js development, crafting
digital experiences that make a difference. When I'm not
coding, you'll find me gaming or scrolling through my
Instagram feed.
</span>
</p>
<div className="bg-white/5 p-6 rounded-lg backdrop-blur-sm">
<h3 className="text-xl font-bold text-gray-100 mb-4 bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent">
Fun Facts About Me
</h3>
<div className="grid grid-cols-2 gap-4">
<div className="flex items-center gap-3 text-gray-300 hover:text-blue-400 transition-colors">
<span className="text-2xl">🚲</span>
<span>Avid Cyclist</span>
</div>
<div className="flex items-center gap-3 text-gray-300 hover:text-blue-400 transition-colors">
<span className="text-2xl">🎮</span>
<span>Gaming Enthusiast</span>
</div>
<div className="flex items-center gap-3 text-gray-300 hover:text-blue-400 transition-colors">
<span className="text-2xl">🛠️</span>
<span>Builder at Heart</span>
</div>
<div className="flex items-center gap-3 text-gray-300 hover:text-blue-400 transition-colors">
<span className="text-2xl">🐕</span>
<span>Dog Dad to Charly</span>
</div>
</div>
</div>
</div>
</div>
</section>
{/* My Blog Posts */}
<section className="w-full">
<h2 className="text-3xl font-bold mb-8 text-center text-gray-100 bg-gradient-to-r from-blue-500 to-purple-500 bg-clip-text text-transparent">
Blog Posts
</h2>
<div
className="p-8 rounded-xl border border-gray-700 bg-white/5 backdrop-blur-lg
flex flex-col md:flex-row gap-8 items-center"
>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 sm:gap-8 text-center">
{posts.map((post) => (
<article
key={post.id}
className="p-6 rounded-xl border border-gray-700 bg-gray-800
transform transition-all duration-300 hover:scale-105 hover:shadow-xl
backdrop-blur-sm hover:bg-opacity-90"
>
<div className="flex flex-wrap gap-2 mb-3">
{!post.hide_date && (
<time className="text-sm text-gray-500">
{new Date(post.date).toLocaleDateString()}
</time>
)}
{post.tags.map((tag) => (
<span
key={tag}
className="px-3 py-1 text-sm bg-gray-900 text-gray-100 rounded-full"
>
{tag}
</span>
))}
</div>
<h3 className="text-xl font-bold mb-3 text-gray-100">
{post.title}
</h3>
<p className=" text-gray-400 text-base mb-4">
{post.excerpt}
</p>
<Link
to={`/blog/${post.access}`}
className="inline-flex items-center px-6 py-2 bg-gradient-to-r from-blue-500 to-purple-500
text-white rounded-full font-medium transition-all duration-300
hover:from-blue-600 hover:to-purple-600 hover:shadow-lg"
>
Read More
<svg
className="w-4 h-4 ml-2"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M14 5l7 7m0 0l-7 7m7-7H3"
/>
</svg>
</Link>
</article>
))}
</div>
</div>
</section>
{/* My Dawg */}
<section className="w-full">
<h2 className="text-3xl font-bold mb-8 text-center text-gray-100 bg-gradient-to-r from-blue-500 to-purple-500 bg-clip-text text-transparent">
My Dawg
</h2>
<div
className="p-8 rounded-xl border border-gray-700 bg-white/5 backdrop-blur-lg
flex flex-col md:flex-row gap-8 items-center"
>
<div className="flex-1 space-y-6">
<img
src="https://cdn.reversed.dev/pictures/20250103_121234.jpg"
alt="Charly Image"
className="w-full h-96 object-cover rounded-lg shadow-lg"
/>
<p className="text-gray-300 text-lg leading-relaxed">
This is Charly🙏 This lil guy is about{" "}
<span className="italic">13</span> Years old. Very mixed.
</p>
<div className="bg-white/5 p-6 rounded-lg backdrop-blur-sm">
<h3 className="text-xl font-bold text-gray-100 mb-4 bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent">
Charly
</h3>
<div className="grid grid-cols-4">
<div className="flex items-center gap-3 text-gray-300 hover:text-blue-400 transition-colors">
<span className="text-2xl">🗣️</span>
<span>the guy is a little deaf</span>
</div>
<div className="flex items-center gap-3 text-gray-300 hover:text-blue-400 transition-colors">
<span className="text-2xl">🚶</span>
<span>Runs faster than me</span>
</div>
<div className="flex items-center gap-3 text-gray-300 hover:text-blue-400 transition-colors">
<span className="text-2xl">🐶</span>
<span>Barks</span>
</div>
<div className="flex items-center gap-3 text-gray-300 hover:text-blue-400 transition-colors">
<span className="text-2xl">🐕</span>
<span>Is a Dog (probably)</span>
</div>
</div>
</div>
</div>
</div>
</section>
{/* Projects Section */}
<section className="w-full">
<h2 className="text-3xl font-bold mb-8 text-gray-100 bg-gradient-to-r from-blue-500 to-purple-500 bg-clip-text text-transparent">
Projects
</h2>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 sm:gap-8 text-center">
{projects.map((project, index) => (
<div
key={index}
className="p-6 rounded-xl border border-gray-700 bg-gray-800
transform transition-all duration-300 hover:scale-105 hover:shadow-xl
backdrop-blur-sm hover:bg-opacity-90"
>
{project.image && (
<div className="mb-6 items-center justify-center flex flex-col">
<img
src={project.image}
alt={project.name}
className="h-40 w-40 object-cover rounded-full shadow-lg
outline outline-gray-600 outline-2 hover:outline-blue-500
transition-all duration-300"
/>
</div>
)}
<h3 className="text-xl font-bold mb-3 text-gray-100">
{project.name}
</h3>
<p className=" text-gray-400 text-base mb-4">
{project.description}
</p>
<div className="flex flex-col sm:flex-row gap-3 justify-center">
<a
href={
project.link +
"?utm_source=portfolio&utm_medium=referral&ref=space"
}
target="_blank"
className="px-6 py-2 bg-gradient-to-r from-blue-500 to-purple-500
text-white rounded-full font-medium transition-all duration-300
hover:from-blue-600 hover:to-purple-600 hover:shadow-lg"
>
Visit {project.name}
</a>
{project.open_source && (
<a
href={project.open_source.link}
target="_blank"
className="px-6 py-2 border border-gray-600
rounded-full font-medium transition-all duration-300
hover:bg-gray-700"
>
View Source
</a>
)}
</div>
</div>
))}
</div>
</section>
{/* Contact */}
<section className="w-full">
<h2 className="text-3xl font-bold mb-8 text-center text-gray-100 bg-gradient-to-r from-blue-500 to-purple-500 bg-clip-text text-transparent">
Contact
</h2>
<div
className="p-6 rounded-xl border border-gray-700 bg-white/5 backdrop-blur-lg
transform transition-all duration-300 hover:scale-105 hover:shadow-xl"
>
<p className="text-gray-300 text-lg text-center">
You can contact me via Email or on Discord. I'm always open for a
chat or a <span className="line-through">coffee</span> tea🫖
</p>
<div className="flex flex-col sm:flex-row gap-3 justify-center mt-6">
<a
href="mailto:paul.w@betternews.app"
className="px-6 py-2 bg-gradient-to-r from-blue-500 to-purple-500
text-white rounded-full font-medium transition-all duration-300
hover:from-blue-600 hover:to-purple-600 hover:shadow-lg"
>
Email
</a>
<a
href="https://discord.com/users/456443941169004545"
target="_blank"
className="px-6 py-2 bg-gradient-to-r from-blue-500 to-purple-500
text-white rounded-full font-medium transition-all duration-300
hover:from-blue-600 hover:to-purple-600 hover:shadow-lg"
>
Discord
</a>
</div>
</div>
</section>
{/* My "Skills" */}
<section className="w-full">
<h2 className="text-3xl font-bold mb-8 text-center text-gray-100 bg-gradient-to-r from-blue-500 to-purple-500 bg-clip-text text-transparent">
Skills
</h2>
<p className="text-gray-300 text-lg mb-4 text-center">
Skills? Whats that? Never heard of it🤔
</p>
<div
className="p-6 rounded-xl border border-gray-700 bg-white/5 backdrop-blur-lg
hover:shadow-xl"
>
<ul className="space-y-4 text-center">
{skills.map((skill, index) => (
<li
key={index}
className="flex items-center gap-4 text-gray-300 text-lg transition-all duration-300 hover:text-blue-400"
>
{skill.image && (
<img
src={skill.image}
alt={skill.name}
className="h-12 w-12 object-cover rounded-full shadow-lg"
/>
)}
<span>
{skill.name} - {skill.description}
</span>
</li>
))}
</ul>
</div>
</section>
{/* What's Next Section */}
<section className="w-full">
<h2 className="text-3xl font-bold mb-8 text-center text-gray-100 bg-gradient-to-r from-blue-500 to-purple-500 bg-clip-text text-transparent">
What's Next?
</h2>
<div
className="p-6 rounded-xl border border-gray-700 bg-white/5 backdrop-blur-lg
transform transition-all duration-300 hover:scale-105 hover:shadow-xl"
>
<ul className="space-y-4 text-center">
<li className="text-gray-300 text-lg transition-all duration-300 hover:text-blue-400">
• Learning more ways to build Apps
</li>
<li className="text-gray-300 text-lg transition-all duration-300 hover:text-blue-400">
• Building more fun little open-source Projects
</li>
<li className="text-gray-300 text-lg transition-all duration-300 hover:text-blue-400">
• Working on existing Projects
</li>
</ul>
</div>
</section>
</div>
</div>
);
}
const skills: {
name: string;
description: string;
image?: string;
}[] = [
{
name: "JavaScript",
description:
"I'm a JavaScript Developer with a lot of experience in JS. I love to build things with JS. Js my beloved",
image: "https://cdn.reversed.dev/pictures/languages/js_logo.png",
},
{
name: "Vue.JS",
description:
"I have not much experience with Vue.js, but i its fun to play around with.",
image: "https://cdn.reversed.dev/pictures/languages/vue.png",
},
{
name: "Node.js",
description:
"Node.js is my go-to Framework for Backend Development. I love to build things with Node.js.",
image: "https://cdn.reversed.dev/pictures/languages/nodejs.jpg",
},
{
name: "TailwindCSS",
description: "TailwindCSS is my go-to CSS Framework. TailwindCss 🙏🙏🙏",
image: "https://cdn.reversed.dev/pictures/languages/tailwind.png",
},
{
name: "TypeScript",
description:
"TypeScript is my go-to Language for larger Projects with type-safety. Typescript 🔥",
image: "https://cdn.reversed.dev/pictures/languages/ts.png",
},
{
name: "Docker",
description: "Docker is the best Containerization Tool imo. ",
image: "https://cdn.reversed.dev/pictures/languages/docker.png",
},
{
name: "HTML",
description: "HTML is the language of the Web. I dont need to say more.",
image:
"https://imagedelivery.net/5MYSbk45M80qAwecrlKzdQ/51703b85-ef3f-4d45-fae0-c39d4c733900/preview",
},
];
const projects: {
name: string;
description: string;
image?: string;
open_source: { link: string } | false;
link: string;
}[] = [
{
name: "BetterNews",
description:
"A news aggregator app, custom built. No ads, no tracking, just news.",
image: "https://betternews.app/assets/icon.png",
open_source: false,
link: "https://betternews.app",
},
{
name: "Reversed.Dev",
description:
"An upcomming overlooking platform showing off Projects under the Reversed.Dev Brand.",
image: "https://cdn.reversed.dev/pictures/icon.png",
open_source: false,
link: "https://reversed.dev",
},
{
name: "Luna",
description: "Luna is an All-In-One Discord Bot with a lot of AI features.",
image: "https://cdn.reversed.dev/pictures/luna/lunasmol.jpg",
open_source: false,
link: "https://luna.reversed.dev",
},
{
name: "Whatsapp-Chat-Analyzer",
description:
"A simple Chat Analyzer for WhatsApp Chats. All private, all yours.",
image: "https://cdn.reversed.dev/pictures/wca.png",
open_source: { link: "https://github.com/Space-Banane/whatsapp-stats" },
link: "https://whatstat.reversed.dev",
},
{
name: "Free QrCode Generator",
description:
"A simple QR Code Generator for free. No tracking, no ads, just QR Codes. Just like we love em.",
image: "https://cdn.reversed.dev/pictures/qrcode.jpeg",
open_source: { link: "https://github.com/reversed-dev/qr-code-gen" },
link: "https://qrcode.reversed.dev",
},
{
name: "Tyler-The-Creator Countdown",
description:
"A simple Countdown for the next Tyler-The-Creator Album 'Chromokopia'. Just for fun, and because i can.",
link: "https://tyler.reversed.dev",
open_source: {
link: "https://github.com/Space-Banane/tylerthecreatorcounter",
},
image: "https://i.scdn.co/image/ab67616d00001e02124e9249fada4ff3c3a0739c",
},
];