From b7dc08dc2f9cc5b911a6a5d64976954f503bba48 Mon Sep 17 00:00:00 2001 From: carlitosbond Date: Thu, 28 May 2026 11:53:06 +0000 Subject: [PATCH] feat: add tools section with MarkItDown, update Caddyfile for md subdomain --- Caddyfile | 56 ++++++++++++------- frontend/src/components/tools.js | 95 ++++++++++++++++++++++++++++++++ frontend/src/main.js | 2 + 3 files changed, 132 insertions(+), 21 deletions(-) create mode 100644 frontend/src/components/tools.js diff --git a/Caddyfile b/Caddyfile index 878fcf4..fd9b617 100644 --- a/Caddyfile +++ b/Caddyfile @@ -74,27 +74,6 @@ portainer.carloselugo.com { } } -# ── Umami Analytics ─────────────────────────────────────────────────────────── -analytics.carloselugo.com { - import security_headers - encode gzip - log { - output file /var/log/caddy/analytics.log - format json - } - - @public path /script.js /api/send - handle @public { - reverse_proxy umami:3000 - } - - handle { - @blocked not remote_ip 24.139.235.46/32 192.168.68.0/24 2605:ba00:3108::/48 74.115.203.2/32 165.225.192.0/18 - abort @blocked - reverse_proxy umami:3000 - } -} - # ── ntfy (notificaciones push) ──────────────────────────────────────────────── ntfy.carloselugo.com { reverse_proxy ntfy:80 { @@ -126,3 +105,38 @@ logs.carloselugo.com { format json } } +# ── NI Quiz — evento público ─────────────────────────────────────────────────── +ni-quiz.carloselugo.com { + import security_headers + reverse_proxy ni-quiz:8000 { + header_up Host {host} + header_up X-Real-IP {remote_host} + } + log { + output file /var/log/caddy/ni-quiz.log + format json + } +} +# ── MarkItDown ──────────────────────────────────────────────────────────────── +md.carloselugo.com { + import security_headers + reverse_proxy markitdown:8000 + log { + output file /var/log/caddy/markitdown.log + format json + } +} + +# ── NI Quiz — evento público ─────────────────────────────────────────────────── +route-rush.carloselugo.com { + import security_headers + reverse_proxy route-rush:8001 { + header_up Host {host} + header_up X-Real-IP {remote_host} + } + log { + output file /var/log/caddy/ni-quiz.log + format json + } +} + diff --git a/frontend/src/components/tools.js b/frontend/src/components/tools.js new file mode 100644 index 0000000..b715c77 --- /dev/null +++ b/frontend/src/components/tools.js @@ -0,0 +1,95 @@ +const tools = [ + { + id: '01', + title: 'MarkItDown', + desc: 'Convert any document to Markdown. Drop a PDF, DOCX, PPTX, XLSX, HTML, or CSV and get clean Markdown output instantly.', + tags: ['python', 'fastapi', 'markitdown'], + url: 'https://md.carloselugo.com', + status: 'live', + }, +] + +const statusLabel = { + live: { text: 'live', color: '#c8ff00' }, + wip: { text: 'wip', color: '#ff6b35' }, +} + +export function renderTools() { + const cards = tools.map(t => { + const s = statusLabel[t.status] + return ` + +
+ ${t.id} + ● ${s.text} +
+

${t.title}

+

${t.desc}

+
+
+ ${t.tags.map(tag => `${tag}`).join('')} +
+ open ↗ +
+
+ ` + }).join('') + + return ` +
+
+
+
+

Tools

+

Self-hosted utilities running on the homelab.

+
+
+ ${cards} +
+
+
+ + + ` +} \ No newline at end of file diff --git a/frontend/src/main.js b/frontend/src/main.js index b62f63b..40d1d92 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -2,6 +2,7 @@ import './style.css' import { renderHeader } from './components/header.js' import { renderHero } from './components/hero.js' import { renderProjects } from './components/projects.js' +import { renderTools } from './components/tools.js' import { renderBlog, initBlog } from './components/blog.js' import { renderFooter } from './components/footer.js' @@ -12,6 +13,7 @@ app.innerHTML = `
${renderHero()} ${renderProjects()} + ${renderTools()} ${renderBlog()}
${renderFooter()}