first commit

This commit is contained in:
Patrick
2026-05-01 20:02:13 +02:00
commit 75fb753fc0
77 changed files with 4793 additions and 0 deletions
+88
View File
@@ -0,0 +1,88 @@
// ═══════════════════════════════════════════════════════
// Particles
// ═══════════════════════════════════════════════════════
(function initParticles() {
const c = document.getElementById('particles');
for (let i = 0; i < 30; i++) {
const p = document.createElement('div');
p.className = 'particle';
p.style.left = Math.random() * 100 + '%';
p.style.animationDelay = Math.random() * 15 + 's';
p.style.animationDuration = (10 + Math.random() * 20) + 's';
p.style.width = p.style.height = (1 + Math.random() * 3) + 'px';
c.appendChild(p);
}
})();
// ═══════════════════════════════════════════════════════
// Navigation
// ═══════════════════════════════════════════════════════
function showPage(name) {
document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
document.getElementById('page-' + name).classList.add('active');
window.scrollTo({ top: 0, behavior: 'smooth' });
}
// ═══════════════════════════════════════════════════════
// Search & Filter
// ═══════════════════════════════════════════════════════
function filterTools(query) {
const q = query.toLowerCase();
document.querySelectorAll('.tool-card').forEach(card => {
const name = card.dataset.name.toLowerCase();
card.style.display = name.includes(q) ? '' : 'none';
});
}
function filterCategory(cat, btn) {
document.querySelectorAll('.cat-btn').forEach(b => b.classList.remove('active'));
if (btn) btn.classList.add('active');
document.querySelectorAll('.tool-card').forEach(card => {
card.style.display = (cat === 'all' || card.dataset.cat === cat) ? '' : 'none';
});
}
// Ctrl+K to focus search
document.addEventListener('keydown', e => {
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
e.preventDefault();
const el = document.getElementById('searchInput');
if (el) el.focus();
}
});
// ═══════════════════════════════════════════════════════
// Helpers
// ═══════════════════════════════════════════════════════
// ✦ Change this for production deployment:
const BASE_URL = window.location.origin; // e.g. "https://winnieapi-v2.yourdomain.com"
function copyText(text) {
navigator.clipboard.writeText(text).then(() => {
const t = document.getElementById('copyToast');
t.classList.add('show');
setTimeout(() => t.classList.remove('show'), 1500);
});
}
function copyOutput(id) { copyText(document.getElementById(id).value); }
function setStatus(id, type, msg) {
const el = document.getElementById(id);
el.className = 'status ' + type;
el.textContent = msg;
}
async function apiPost(url, body) {
const r = await fetch(BASE_URL + url, { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(body) });
return r.json();
}
async function apiGet(url) {
const r = await fetch(BASE_URL + url);
return r.json();
}
function toggleApiUsage(btn) {
btn.classList.toggle('open');
const body = btn.nextElementSibling;
body.classList.toggle('open');
}
function copyApiCode(btn) {
const code = btn.parentElement.textContent.replace('Copy', '').trim();
copyText(code);
}