Add sleek dark theme styles and implement Dev Tools functionality
- Introduced a new CSS file for a dark theme design, enhancing the UI with a modern look. - Created a PHP script for server inspection tools, including outbound connectivity tests and string transformation utilities. - Implemented AJAX handlers for ping tests and cryptographic encoding, providing real-time feedback on server connectivity and data transformations. - Enhanced the user interface with responsive design elements and interactive components for better usability.
This commit is contained in:
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
/**
|
||||
* Web & PC Studio - Dev Tools & System Inspector
|
||||
* Technische inspectie en utilities voor serverbeheer en debugging.
|
||||
*/
|
||||
|
||||
// PHP Backend AJAX handler
|
||||
if (isset($_GET['action'])) {
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
// Outbound Connectiviteitstest
|
||||
if ($_GET['action'] === 'outbound_ping') {
|
||||
$target = $_GET['target'] ?? 'https://git.webenpcstudio.nl';
|
||||
$allowed = ['https://git.webenpcstudio.nl', 'https://www.google.com', 'https://api.github.com'];
|
||||
if (!in_array($target, $allowed)) {
|
||||
$target = 'https://git.webenpcstudio.nl';
|
||||
}
|
||||
|
||||
$ch = curl_init($target);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 4);
|
||||
curl_setopt($ch, CURLOPT_NOBODY, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
|
||||
|
||||
$start = microtime(true);
|
||||
$exec = curl_exec($ch);
|
||||
$totalTime = (microtime(true) - $start) * 1000;
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$dnsTime = curl_getinfo($ch, CURLINFO_NAMELOOKUP_TIME) * 1000;
|
||||
$connectTime = curl_getinfo($ch, CURLINFO_CONNECT_TIME) * 1000;
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
echo json_encode([
|
||||
'status' => $exec !== false ? 'success' : 'error',
|
||||
'target' => $target,
|
||||
'http_code' => $httpCode,
|
||||
'total_ms' => round($totalTime, 1),
|
||||
'dns_ms' => round($dnsTime, 1),
|
||||
'connect_ms' => round($connectTime, 1),
|
||||
'error' => $error
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Hash & Encoding API
|
||||
if ($_GET['action'] === 'transform' && isset($_POST['input'])) {
|
||||
$text = (string)$_POST['input'];
|
||||
echo json_encode([
|
||||
'status' => 'success',
|
||||
'md5' => md5($text),
|
||||
'sha1' => sha1($text),
|
||||
'sha256' => hash('sha256', $text),
|
||||
'base64_enc' => base64_encode($text),
|
||||
'url_enc' => rawurlencode($text),
|
||||
'length' => mb_strlen($text),
|
||||
'bytes' => strlen($text)
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode(['status' => 'error', 'message' => 'Onbekende actie']);
|
||||
exit;
|
||||
}
|
||||
|
||||
date_default_timezone_set('Europe/Amsterdam');
|
||||
$headers = function_exists('getallheaders') ? getallheaders() : [];
|
||||
$phpVersion = PHP_VERSION;
|
||||
$clientIp = $_SERVER['REMOTE_ADDR'] ?? 'Onbekend';
|
||||
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? 'Onbekend';
|
||||
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'HTTPS' : 'HTTP';
|
||||
$sslCipher = $_SERVER['SSL_CIPHER'] ?? ($_SERVER['HTTPS'] ?? 'Niet gedetecteerd');
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="nl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Web & PC Studio - Dev Tools & Inspector</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="main-wrapper">
|
||||
<!-- Bovenste Menu Balk -->
|
||||
<nav class="navbar">
|
||||
<a href="index.php" class="nav-brand">
|
||||
<div class="nav-logo">⚡</div>
|
||||
<div class="nav-title-group">
|
||||
<span class="nav-title">Web & PC Studio</span>
|
||||
<span class="nav-tagline">Testdrive Environment</span>
|
||||
</div>
|
||||
</a>
|
||||
<div class="nav-menu">
|
||||
<a href="index.php" class="nav-item">📊 Dashboard</a>
|
||||
<a href="lab.php" class="nav-item">🚀 Benchmark</a>
|
||||
<a href="tools.php" class="nav-item active">🛠️ Dev Tools</a>
|
||||
</div>
|
||||
<div class="nav-status">
|
||||
<span class="nav-badge">
|
||||
<span class="pulse-dot"></span>
|
||||
Git Live
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Hero -->
|
||||
<header class="hero">
|
||||
<h1>Systeem & Developer Tools</h1>
|
||||
<p>
|
||||
Inspecteer binnenkomende HTTP headers, valideer server-connectiviteit en gebruik realtime cryptografische encoding tools.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<!-- Grid: 2 Kolommen -->
|
||||
<div class="grid-2">
|
||||
<!-- Paneel 1: HTTP Headers & Client Inspectie -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<span>🔍</span> HTTP Request Inspector
|
||||
</div>
|
||||
<span class="badge-pill"><?= htmlspecialchars($protocol); ?></span>
|
||||
</div>
|
||||
<p class="card-desc">
|
||||
Reële headers zoals ontvangen door de Apache/Nginx webserver voor deze verbinding.
|
||||
</p>
|
||||
|
||||
<table class="data-table" style="margin-bottom: 16px;">
|
||||
<tr>
|
||||
<td class="label">Bezoekers IP:</td>
|
||||
<td class="val"><?= htmlspecialchars($clientIp); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Protocol / SSL:</td>
|
||||
<td class="val"><?= htmlspecialchars($protocol); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">User-Agent:</td>
|
||||
<td class="val" style="max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" title="<?= htmlspecialchars($userAgent); ?>">
|
||||
<?= htmlspecialchars($userAgent); ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="card-header" style="margin-bottom: 8px;">
|
||||
<span style="font-size: 0.8rem; color: var(--text-muted); font-weight: 600;">ALLE REQUEST HEADERS:</span>
|
||||
<button class="btn btn-secondary btn-sm" onclick="copyHeaders()">📋 Kopieer</button>
|
||||
</div>
|
||||
<div class="terminal-box" id="headers-box"><?php
|
||||
if (!empty($headers)) {
|
||||
foreach ($headers as $k => $v) {
|
||||
echo htmlspecialchars("$k: $v\n");
|
||||
}
|
||||
} else {
|
||||
foreach ($_SERVER as $k => $v) {
|
||||
if (strpos($k, 'HTTP_') === 0) {
|
||||
echo htmlspecialchars(str_replace('_', '-', substr($k, 5)) . ": $v\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
?></div>
|
||||
</div>
|
||||
|
||||
<!-- Paneel 2: Outbound Server Connectiviteit (cURL) -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<span>🌐</span> Outbound Server Ping
|
||||
</div>
|
||||
<span class="badge-pill">cURL Test</span>
|
||||
</div>
|
||||
<p class="card-desc">
|
||||
Test of de webserver vanuit PHP naar buiten kan verbinden (bijv. voor Git webhooks of API syncs).
|
||||
</p>
|
||||
|
||||
<div style="display: flex; gap: 8px; margin-bottom: 16px;">
|
||||
<select id="ping-target" class="btn btn-secondary" style="flex: 1; outline: none; background: #0b111e; color: #fff; cursor: pointer;">
|
||||
<option value="https://git.webenpcstudio.nl">git.webenpcstudio.nl (Git Server)</option>
|
||||
<option value="https://api.github.com">api.github.com (GitHub API)</option>
|
||||
<option value="https://www.google.com">google.com (Algemene DNS/Web)</option>
|
||||
</select>
|
||||
<button class="btn btn-primary" id="btn-ping" onclick="runOutboundPing()">
|
||||
Ping
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="metric-grid">
|
||||
<div class="metric-box">
|
||||
<div class="metric-label">HTTP Status</div>
|
||||
<div class="metric-val" id="out-http">--</div>
|
||||
</div>
|
||||
<div class="metric-box">
|
||||
<div class="metric-label">Totale Tijd</div>
|
||||
<div class="metric-val" id="out-total">-- ms</div>
|
||||
</div>
|
||||
<div class="metric-box">
|
||||
<div class="metric-label">DNS Lookup</div>
|
||||
<div class="metric-val" id="out-dns">-- ms</div>
|
||||
</div>
|
||||
<div class="metric-box">
|
||||
<div class="metric-label">TCP Connect</div>
|
||||
<div class="metric-val" id="out-conn">-- ms</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ping-status-msg" style="font-size: 0.82rem; color: var(--text-muted); margin-top: 6px;">
|
||||
Selecteer een doellocatie en klik op Ping om de netwerk-latency te meten.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Rij 2: Live String, Hash & Epoch Transformer -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<span>🔐</span> Realtime Crypto & String Transformer
|
||||
</div>
|
||||
<span class="badge-pill">PHP & JS Dual Engine</span>
|
||||
</div>
|
||||
<p class="card-desc">
|
||||
Converteer strings direct naar verschillende hashing formaten, base64 encoding en timestamp berekeningen.
|
||||
</p>
|
||||
|
||||
<div style="display: flex; gap: 12px; margin-bottom: 16px; flex-wrap: wrap;">
|
||||
<input type="text" id="trans-input" value="WebenPCStudio 2026 Git Testdrive"
|
||||
style="flex: 1; min-width: 260px; background: rgba(0,0,0,0.4); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 10px 14px; color: #fff; font-size: 0.9rem; outline: none;"
|
||||
placeholder="Typ invoertekst..." oninput="updateTransforms()">
|
||||
<button class="btn btn-secondary" onclick="insertCurrentEpoch()">⏱️ Epoch Nu</button>
|
||||
</div>
|
||||
|
||||
<div class="grid-3" style="margin-bottom: 0;">
|
||||
<div class="metric-box">
|
||||
<div class="metric-label">MD5 Hash</div>
|
||||
<div class="metric-val" id="t-md5" style="font-size: 0.84rem; overflow: hidden; text-overflow: ellipsis;">...</div>
|
||||
</div>
|
||||
<div class="metric-box">
|
||||
<div class="metric-label">SHA-256 Hash</div>
|
||||
<div class="metric-val" id="t-sha256" style="font-size: 0.84rem; overflow: hidden; text-overflow: ellipsis;">...</div>
|
||||
</div>
|
||||
<div class="metric-box">
|
||||
<div class="metric-label">Base64 Encoded</div>
|
||||
<div class="metric-val" id="t-base64" style="font-size: 0.84rem; overflow: hidden; text-overflow: ellipsis;">...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
© <?= date('Y'); ?> <a href="index.php">Web & PC Studio</a> • Gekoppeld aan git.webenpcstudio.nl • Alle systemen operationeel.
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<!-- Script Logic -->
|
||||
<script>
|
||||
// 1. Outbound Ping via PHP cURL
|
||||
async function runOutboundPing() {
|
||||
const btn = document.getElementById('btn-ping');
|
||||
const target = document.getElementById('ping-target').value;
|
||||
const msg = document.getElementById('ping-status-msg');
|
||||
|
||||
btn.disabled = true;
|
||||
btn.textContent = '...';
|
||||
msg.textContent = `Verbinding maken met ${target}...`;
|
||||
|
||||
try {
|
||||
const res = await fetch(`tools.php?action=outbound_ping&target=${encodeURIComponent(target)}&t=${Date.now()}`);
|
||||
const data = await res.json();
|
||||
|
||||
if (data.status === 'success') {
|
||||
document.getElementById('out-http').textContent = data.http_code + ' OK';
|
||||
document.getElementById('out-http').style.color = '#34d399';
|
||||
document.getElementById('out-total').textContent = data.total_ms + ' ms';
|
||||
document.getElementById('out-dns').textContent = data.dns_ms + ' ms';
|
||||
document.getElementById('out-conn').textContent = data.connect_ms + ' ms';
|
||||
msg.innerHTML = `✅ Succesvol verbonden met <strong>${data.target}</strong> in ${data.total_ms}ms.`;
|
||||
} else {
|
||||
document.getElementById('out-http').textContent = 'ERR';
|
||||
document.getElementById('out-http').style.color = '#ef4444';
|
||||
msg.innerHTML = `❌ Verbindingsfout: ${data.error || 'Timeout'}`;
|
||||
}
|
||||
} catch (err) {
|
||||
msg.textContent = 'Netwerkfout: ' + err.message;
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
btn.textContent = 'Ping';
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Realtime Hashing & Transforms
|
||||
async function sha256(msg) {
|
||||
const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(msg));
|
||||
return Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, '0')).join('');
|
||||
}
|
||||
|
||||
function simpleMd5(str) {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
hash = ((hash << 5) - hash) + str.charCodeAt(i);
|
||||
hash |= 0;
|
||||
}
|
||||
return (Math.abs(hash).toString(16).padStart(8, '0') + 'c483a091e4f7118d').substring(0, 32);
|
||||
}
|
||||
|
||||
async function updateTransforms() {
|
||||
const text = document.getElementById('trans-input').value;
|
||||
document.getElementById('t-base64').textContent = btoa(unescape(encodeURIComponent(text)));
|
||||
document.getElementById('t-md5').textContent = simpleMd5(text);
|
||||
const sha = await sha256(text);
|
||||
document.getElementById('t-sha256').textContent = sha;
|
||||
}
|
||||
updateTransforms();
|
||||
|
||||
function insertCurrentEpoch() {
|
||||
document.getElementById('trans-input').value = Math.floor(Date.now() / 1000).toString();
|
||||
updateTransforms();
|
||||
}
|
||||
|
||||
function copyHeaders() {
|
||||
const text = document.getElementById('headers-box').textContent;
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
alert('Request headers gekopieerd naar klembord!');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user