mirror of
https://github.com/MrUnknownDE/utools.git
synced 2026-05-06 06:16:04 +02:00
remove placeholder sentry and add mobil menu
This commit is contained in:
+4
-41
@@ -5,22 +5,14 @@ const Sentry = require("@sentry/node");
|
||||
|
||||
// Initialize Sentry BEFORE requiring any other modules!
|
||||
Sentry.init({
|
||||
// DSN should now be available from process.env if set in .env
|
||||
dsn: process.env.SENTRY_DSN || "https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@oooooooooooooooo.ingest.sentry.io/123456",
|
||||
// Enable tracing - Adjust sample rate as needed
|
||||
dsn: process.env.SENTRY_DSN,
|
||||
tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,
|
||||
integrations: [
|
||||
// send console.log, console.warn, and console.error calls as logs to Sentry
|
||||
Sentry.consoleLoggingIntegration({ levels: ["log", "warn", "error"] }),
|
||||
Sentry.consoleLoggingIntegration({ levels: ["warn", "error"] }),
|
||||
],
|
||||
// Enable logs to be sent to Sentry
|
||||
enableLogs: true,
|
||||
});
|
||||
|
||||
// DEBUG: Check Sentry object after init
|
||||
console.log("Sentry object after init:", typeof Sentry, Sentry ? Object.keys(Sentry) : 'Sentry is undefined/null');
|
||||
// --- Ende Sentry Initialisierung ---
|
||||
|
||||
|
||||
// Require necessary core modules AFTER Sentry is initialized
|
||||
const express = require('express');
|
||||
@@ -53,20 +45,6 @@ const logger = pino({
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 3000;
|
||||
|
||||
// --- Sentry Middleware (Request Handler & Tracing) ---
|
||||
// Must be the first middleware
|
||||
if (Sentry.Handlers && Sentry.Handlers.requestHandler) {
|
||||
app.use(Sentry.Handlers.requestHandler());
|
||||
} else {
|
||||
logger.error("Sentry.Handlers.requestHandler is not available!");
|
||||
}
|
||||
// Must be after requestHandler, before routes
|
||||
if (Sentry.Handlers && Sentry.Handlers.tracingHandler) {
|
||||
app.use(Sentry.Handlers.tracingHandler());
|
||||
} else {
|
||||
logger.error("Sentry.Handlers.tracingHandler is not available!");
|
||||
}
|
||||
// --- Ende Sentry Middleware ---
|
||||
|
||||
|
||||
// --- Core Middleware ---
|
||||
@@ -112,23 +90,8 @@ app.use('/api/mac-lookup', macLookupRoutes);
|
||||
app.use('/api/asn-lookup', asnLookupRoutes);
|
||||
|
||||
|
||||
// --- Sentry Error Handler ---
|
||||
// Must be AFTER all controllers and BEFORE any other error handling middleware
|
||||
if (Sentry.Handlers && Sentry.Handlers.errorHandler) {
|
||||
app.use(Sentry.Handlers.errorHandler({
|
||||
shouldHandleError(error) {
|
||||
// Capture all 500 errors
|
||||
if (error.status === 500) return true;
|
||||
// Capture specific client errors if needed, e.g., 403
|
||||
// if (error.status === 403) return true;
|
||||
// By default, capture only server errors (5xx)
|
||||
return error.status >= 500;
|
||||
},
|
||||
}));
|
||||
} else {
|
||||
logger.error("Sentry.Handlers.errorHandler is not available!");
|
||||
}
|
||||
// --- Ende Sentry Error Handler ---
|
||||
// Sentry error handler — must be after routes, before custom error handler
|
||||
Sentry.setupExpressErrorHandler(app);
|
||||
|
||||
|
||||
// --- Fallback Error Handler ---
|
||||
|
||||
+10
-4
@@ -4,6 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>uTools – Network Suite</title>
|
||||
<link rel="icon" href="https://mrunk.de/pic/favicon/favicon.svg" type="image/svg+xml">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
|
||||
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="">
|
||||
@@ -12,10 +13,15 @@
|
||||
<body class="bg-gray-950 text-gray-100 font-sans p-4 md:p-8 min-h-screen bg-[url('https://tailwindcss.com/_next/static/media/hero-dark.939eb757.png')] bg-cover bg-center bg-fixed selection:bg-purple-500 selection:text-white">
|
||||
|
||||
<header class="glass-panel">
|
||||
<h1 style="background:linear-gradient(to right,#c084fc,#e879f9);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent" class="text-2xl font-bold">
|
||||
uTools <span style="-webkit-text-fill-color:#9ca3af" class="text-sm font-normal tracking-wider uppercase ml-2">Network Suite</span>
|
||||
</h1>
|
||||
<nav>
|
||||
<div class="header-top">
|
||||
<h1 style="background:linear-gradient(to right,#c084fc,#e879f9);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent" class="text-2xl font-bold">
|
||||
uTools <span style="-webkit-text-fill-color:#9ca3af" class="text-sm font-normal tracking-wider uppercase ml-2">Network Suite</span>
|
||||
</h1>
|
||||
<button id="nav-toggle" class="nav-toggle" aria-label="Toggle navigation" aria-expanded="false">
|
||||
<span></span><span></span><span></span>
|
||||
</button>
|
||||
</div>
|
||||
<nav id="main-nav">
|
||||
<ul>
|
||||
<li><a href="/">IP Info & Tools</a></li>
|
||||
<li><a href="/subnet">Subnetz Rechner</a></li>
|
||||
|
||||
@@ -421,18 +421,14 @@ export const page = {
|
||||
let ipToLookup = query;
|
||||
if (!isValidIp(query)) {
|
||||
try {
|
||||
const r = await fetch(`${API}/dns-lookup?domain=${encodeURIComponent(query)}&type=A`);
|
||||
const r = await fetch(`${API}/dns-lookup?domain=${encodeURIComponent(query)}&type=ANY`);
|
||||
const data = await r.json();
|
||||
if (r.ok && data.success && data.records?.length) {
|
||||
ipToLookup = Array.isArray(data.records) ? data.records[0] : data.records;
|
||||
if (r.ok && data.success) {
|
||||
const ip = data.records?.A?.[0] ?? data.records?.AAAA?.[0];
|
||||
if (ip) ipToLookup = ip;
|
||||
else throw new Error('No A or AAAA records found.');
|
||||
} else {
|
||||
const r2 = await fetch(`${API}/dns-lookup?domain=${encodeURIComponent(query)}&type=AAAA`);
|
||||
const data2 = await r2.json();
|
||||
if (r2.ok && data2.success && data2.records?.length) {
|
||||
ipToLookup = Array.isArray(data2.records) ? data2.records[0] : data2.records;
|
||||
} else {
|
||||
throw new Error(data.error || 'No A or AAAA records found.');
|
||||
}
|
||||
throw new Error(data.error || 'DNS lookup failed.');
|
||||
}
|
||||
} catch (err) {
|
||||
lookupErrorEl.textContent = `Error: Could not resolve domain — ${err.message}`;
|
||||
|
||||
@@ -15,8 +15,18 @@ const routes = {
|
||||
};
|
||||
|
||||
const app = document.getElementById('app');
|
||||
const header = document.querySelector('header');
|
||||
let currentCleanup = null;
|
||||
|
||||
// ── Hamburger toggle ─────────────────────────────────────────────
|
||||
const navToggle = document.getElementById('nav-toggle');
|
||||
if (navToggle) {
|
||||
navToggle.addEventListener('click', () => {
|
||||
const open = header.classList.toggle('nav-open');
|
||||
navToggle.setAttribute('aria-expanded', open);
|
||||
});
|
||||
}
|
||||
|
||||
function setActiveNav(path) {
|
||||
document.querySelectorAll('nav a').forEach(a => {
|
||||
try {
|
||||
@@ -29,6 +39,9 @@ function setActiveNav(path) {
|
||||
async function navigate(path, { push = true, search = '' } = {}) {
|
||||
const route = routes[path] ?? routes['/'];
|
||||
|
||||
// ── close mobile nav on navigate ────────────────────────────
|
||||
if (header) { header.classList.remove('nav-open'); navToggle?.setAttribute('aria-expanded', 'false'); }
|
||||
|
||||
// ── leave animation ──────────────────────────────────────────
|
||||
app.classList.add('page-leaving');
|
||||
if (currentCleanup) { try { currentCleanup(); } catch {} currentCleanup = null; }
|
||||
|
||||
+49
-5
@@ -109,15 +109,59 @@ header {
|
||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
gap: 0;
|
||||
box-shadow: 0 4px 6px -1px rgba(0,0,0,.1), 0 2px 4px -1px rgba(0,0,0,.06);
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
header { flex-direction: row; justify-content: space-between; }
|
||||
}
|
||||
header h1 { background-clip: text; }
|
||||
|
||||
/* ── Header top row (title + hamburger) ────────────────────────── */
|
||||
.header-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* ── Hamburger button ──────────────────────────────────────────── */
|
||||
.nav-toggle {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
background: none;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 6px;
|
||||
padding: 8px 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.nav-toggle span {
|
||||
display: block;
|
||||
width: 22px;
|
||||
height: 2px;
|
||||
background: #d1d5db;
|
||||
border-radius: 2px;
|
||||
transition: transform 0.25s ease, opacity 0.2s ease;
|
||||
}
|
||||
header.nav-open .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
|
||||
header.nav-open .nav-toggle span:nth-child(2) { opacity: 0; transform: scaleX(0); }
|
||||
header.nav-open .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
|
||||
|
||||
/* ── Mobile nav ────────────────────────────────────────────────── */
|
||||
#main-nav {
|
||||
display: none;
|
||||
padding-top: 1rem;
|
||||
margin-top: 1rem;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
header.nav-open #main-nav { display: block; }
|
||||
|
||||
/* ── Desktop nav ───────────────────────────────────────────────── */
|
||||
@media (min-width: 768px) {
|
||||
header { flex-direction: row; align-items: center; gap: 1rem; }
|
||||
.header-top { flex: 0 0 auto; }
|
||||
.nav-toggle { display: none; }
|
||||
#main-nav { display: block !important; padding-top: 0; margin-top: 0; border-top: none; }
|
||||
}
|
||||
|
||||
/* ── Text gradient ─────────────────────────────────────────────── */
|
||||
.text-gradient {
|
||||
background: linear-gradient(to right, #c084fc, #e879f9);
|
||||
|
||||
Reference in New Issue
Block a user