Added External Links

This commit is contained in:
2025-04-23 12:07:33 +08:00
parent 419567e4ff
commit 9ccc636fef

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Services Hub</title> <title>🌐 My Services Hub</title>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script> <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<link <link
rel="stylesheet" rel="stylesheet"
@@ -29,104 +29,69 @@
} }
</style> </style>
</head> </head>
<body class="min-h-screen text-white font-sans tracking-wide">
<body <main class="flex flex-col items-center px-6 py-10 space-y-24">
class="min-h-screen flex flex-col items-center justify-center text-white font-sans tracking-wide" <!-- Header -->
> <header class="text-center space-y-4">
<header class="text-center mb-12"> <h1 class="text-5xl font-bold">🌐 My Network Services</h1>
<h1 class="text-5xl font-bold mb-4">🌐 My Network Services</h1>
<p class="text-gray-300 text-lg"> <p class="text-gray-300 text-lg">
All services hosted under the same IP, organized for your convenience 💡 All services hosted under the same IP, organized for your convenience 💡
</p> </p>
</header> </header>
<!-- Services Section -->
<section class="w-full max-w-7xl">
<h2 class="text-3xl font-semibold mb-6">🛎️ Hosted Services</h2>
<div <div
id="service-grid" id="service-grid"
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 max-w-7xl w-full px-6" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8"
></div> ></div>
</section>
<footer class="mt-16 text-gray-400 text-sm text-center"> <!-- External Links Section -->
<section class="w-full max-w-4xl border-t border-white/20 pt-12">
<h2 class="text-3xl font-semibold mb-6">📎 External Resources</h2>
<div id="external-links" class="grid grid-cols-1 sm:grid-cols-2 gap-6"></div>
</section>
<!-- Footer -->
<footer class="text-gray-400 text-sm text-center pt-8 border-t border-white/10 w-full">
&copy; 2024-2025 Xiaomai. All services self-hosted 🧠💻<br /> &copy; 2024-2025 Xiaomai. All services self-hosted 🧠💻<br />
Powered by TailwindCSS · Script-enhanced · Inspired by Productivity ⚙️ Powered by TailwindCSS · Script-enhanced · Inspired by Productivity ⚙️
</footer> </footer>
</main>
<script> <script>
const hostIP = window.location.hostname; const hostIP = window.location.hostname;
const services = [ const services = [
{ { port: 81, name: "🏠 Personal Homepage", desc: "Work in progress. Stay tuned!", tags: ["Web"] },
port: 81, { port: 40069, name: "☁ Nextcloud", desc: "Self-hosted cloud storage", secured: true, tags: ["Cloud", "Storage"] },
name: "🏠 Personal Homepage", { port: 1957, name: "🌦️ Malaysia Weather Radar", desc: "Historical weather radar visualization", tags: ["Data", "Weather"] },
desc: "Work in progress. Stay tuned!", { port: 1025, name: "🎮 Kenney's Assets", desc: "Open game art & asset collection", tags: ["Assets", "Games"] },
tags: ["Web"], { port: 1031, name: "🌐 Itch io PCK dl", desc: "Download Godot pck files from itch.io", tags: ["Games", "Tools"] },
}, { port: 3000, name: "📁 Gitea", desc: "Self-hosted Git service", tags: ["Code", "Git"] },
{ { port: 5230, name: "📝 Memos", desc: "Lightweight self-hosted note-taking", tags: ["Notes", "Productivity"] },
port: 40069, { port: 10001, name: "📄 Stirling PDF", desc: "Powerful locally hosted web based PDF manipulation tool", tags: ["Tools", "PDF"] },
name: "☁ Nextcloud", { port: 40178, name: "📊 JSON Hero", desc: "Visual JSON explorer", tags: ["Tools", "JSON"] },
desc: "Self-hosted cloud storage", { port: 24680, name: "🛠️ 1Panel Dashboard", desc: "Unified server management panel", tags: ["Admin", "Dashboard"] },
secured: true, ];
tags: ["Cloud", "Storage"],
}, const externalLinks = [
{ { name: "🔗 GitHub", desc: "Code repositories and projects", url: "https://github.com/kingsmai" },
port: 1957, { name: "📘 Blog", desc: "Personal dev blog and updates", url: "https://kingsmai.github.io" },
name: "🌦️ Malaysia Weather Radar", { name: "💬 Discord Server", desc: "Join the dev chat room", url: "https://discord.gg/sJcv7ZM" },
desc: "Historical weather radar visualization",
tags: ["Data", "Weather"],
},
{
port: 1025,
name: "🎮 Kenney's Assets",
desc: "Open game art & asset collection",
tags: ["Assets", "Games"],
},
{
port: 1031,
name: "🌐 Itch io PCK dl",
desc: "Download Godot pck files from itch.io",
tags: ["Games", "Tools"],
},
{
port: 3000,
name: "📁 Gitea",
desc: "Self-hosted Git service",
tags: ["Code", "Git"],
},
{
port: 5230,
name: "📝 Memos",
desc: "Lightweight self-hosted note-taking",
tags: ["Notes", "Productivity"],
},
{
port: 10001,
name: "📄 Stirling PDF",
desc: "Powerful locally hosted web based PDF manipulation tool",
tags: ["Tools", "PDF"],
},
{
port: 40178,
name: "📊 JSON Hero",
desc: "Visual JSON explorer",
tags: ["Tools", "JSON"],
},
{
port: 24680,
name: "🛠️ 1Panel Dashboard",
desc: "Unified server management panel",
tags: ["Admin", "Dashboard"],
},
]; ];
const container = document.getElementById("service-grid"); const container = document.getElementById("service-grid");
const extContainer = document.getElementById("external-links");
async function checkStatus(service) { async function checkStatus(service) {
try { try {
// Using fetch HEAD mode may be blocked due to CORS; await fetch(`${service.secured ? "https" : "http"}://${hostIP}:${service.port}`, {
// For local/internal services, this is mostly illustrative. method: "HEAD",
const res = await fetch( mode: "no-cors",
`${service.secured ? "https" : "http"}://${hostIP}:${service.port}`, });
{ method: "HEAD", mode: "no-cors" }
);
return true; return true;
} catch { } catch {
return false; return false;
@@ -138,9 +103,7 @@
const online = await checkStatus(service); const online = await checkStatus(service);
const card = document.createElement("a"); const card = document.createElement("a");
card.href = `${service.secured ? "https" : "http"}://${hostIP}:${ card.href = `${service.secured ? "https" : "http"}://${hostIP}:${service.port}`;
service.port
}`;
card.target = "_blank"; card.target = "_blank";
card.rel = "noopener noreferrer"; card.rel = "noopener noreferrer";
card.className = card.className =
@@ -150,16 +113,14 @@
<div class="flex flex-col h-full"> <div class="flex flex-col h-full">
<h2 class="text-2xl font-bold mb-2">${service.name}</h2> <h2 class="text-2xl font-bold mb-2">${service.name}</h2>
<p class="text-gray-300 flex-grow">${service.desc}</p> <p class="text-gray-300 flex-grow">${service.desc}</p>
<div class="mt-4 flex flex-wrap items-center justify-between text-sm"> <div class="mt-4 flex justify-between items-center text-sm">
<div class="text-gray-400">Port: ${service.port}</div> <div class="text-gray-400">Port: ${service.port}</div>
<div class="${ <div class="${online ? "bg-green-600" : "bg-red-600"} text-white px-2 py-1 rounded-full text-xs">
online ? "bg-green-600" : "bg-red-600"
} text-white px-2 py-1 rounded-full text-xs">
${online ? "🟢 Online" : "🔴 Offline"} ${online ? "🟢 Online" : "🔴 Offline"}
</div> </div>
</div> </div>
<div class="mt-3 flex flex-wrap gap-2"> <div class="mt-3 flex flex-wrap gap-2">
${(service.tags || []) ${service.tags
.map( .map(
(tag) => (tag) =>
`<span class="bg-blue-800 text-white text-xs px-2 py-1 rounded-full">${tag}</span>` `<span class="bg-blue-800 text-white text-xs px-2 py-1 rounded-full">${tag}</span>`
@@ -171,6 +132,22 @@
container.appendChild(card); container.appendChild(card);
} }
})(); })();
for (const link of externalLinks) {
const card = document.createElement("a");
card.href = link.url;
card.target = "_blank";
card.rel = "noopener noreferrer";
card.className =
"rounded-lg border border-white/20 backdrop-blur-md bg-white/10 hover:bg-white/20 transition p-5 shadow-lg flex flex-col";
card.innerHTML = `
<h3 class="text-xl font-semibold mb-1">${link.name}</h3>
<p class="text-gray-300 text-sm">${link.desc}</p>
`;
extContainer.appendChild(card);
}
</script> </script>
</body> </body>
</html> </html>