| Server IP : 188.114.96.3 / Your IP : 216.73.216.143 Web Server : Apache System : Linux sv058.home.net.pl 6.8.2 husak_dirty_pages_fix #1 SMP PREEMPT_DYNAMIC Tue Apr 2 22:06:51 CEST 2024 x86_64 User : ( 3194769) PHP Version : 8.5.12 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /test2.famaresto/szukaj/ |
Upload File : |
<?php
declare(strict_types=1);
?><!doctype html>
<html lang="pl">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Wyszukiwarka dokumentów</title>
<style>
body{font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;margin:0;background:#f6f6ef;color:#111}
header{position:sticky;top:0;background:#D6D3C0;border-bottom:1px solid #c8c5b2;padding:14px 16px;z-index:10}
header .row{display:flex;gap:10px;flex-wrap:wrap;align-items:center;max-width:1100px;margin:0 auto}
h1{font-size:18px;margin:0}
.home{margin-left:auto;font-size:13px;white-space:nowrap}
.home a{color:#0645ad;text-decoration:none;font-weight:600}
.home a:hover{text-decoration:underline}
input,select{font:inherit;padding:10px 12px;border:1px solid #c9c9c9;border-radius:10px;background:white}
input{flex:2;min-width:220px}
select{flex:1;min-width:170px}
main{max-width:1100px;margin:0 auto;padding:14px 16px 40px 16px}
.meta{color:#444;font-size:13px;margin:10px 0 16px 0}
.card{background:white;border:1px solid #e2e2e2;border-radius:14px;padding:12px 14px;margin:10px 0;display:flex;gap:12px;align-items:flex-start}
.card a{color:#0645ad;text-decoration:none;font-weight:600}
.card a:hover{text-decoration:underline}
.pill{font-size:12px;color:#333;background:#efefef;border:1px solid #e0e0e0;border-radius:999px;padding:2px 8px;display:inline-block;margin-right:6px}
.small{font-size:12px;color:#555;margin-top:4px}
.right{margin-left:auto;color:#666;font-size:12px;white-space:nowrap}
.empty{padding:24px 8px;color:#555}
.error{padding:12px 14px;border-radius:14px;background:#fff;border:1px solid #e2e2e2}
footer{max-width:1100px;margin:0 auto;padding:0 16px 24px 16px;color:#555;font-size:12px}
code{background:#eee;padding:2px 6px;border-radius:6px}
</style>
</head>
<body>
<header>
<div class="row">
<h1>Wyszukiwarka dokumentów</h1>
<div class="home"><a href="../index.html">← Strona główna</a></div>
<input id="q" type="search" placeholder="Szukaj po tytule (np. regulamin, bhp, urlop...)" autocomplete="off" />
<select id="section">
<option value="">Wszystkie działy</option>
</select>
</div>
</header>
<main>
<div class="meta" id="meta">Ładowanie indeksu…</div>
<div id="results"></div>
</main>
<footer>
<div>Tip: jeżeli tytuł jest mało czytelny, administrator może go nadpisać w <code>/szukaj/admin</code>.</div>
</footer>
<script>
const elQ = document.getElementById('q');
const elS = document.getElementById('section');
const elM = document.getElementById('meta');
const elR = document.getElementById('results');
let docs = [];
function fmtDate(ts){
try{ return new Date(ts*1000).toLocaleDateString('pl-PL'); }
catch(e){ return '' }
}
function fmtSize(bytes){
const units = ['B','KB','MB','GB'];
let i=0, b=bytes;
while(b>=1024 && i<units.length-1){ b/=1024; i++; }
return (i===0? b : b.toFixed(1)) + ' ' + units[i];
}
function escapeHtml(s){
return (s||'').replace(/[&<>"']/g, c => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
}
function render(){
const q = (elQ.value || '').trim().toLowerCase();
const sec = elS.value;
let filtered = docs;
if (sec) filtered = filtered.filter(d => d.section === sec);
if (q) filtered = filtered.filter(d => (d.title||'').toLowerCase().includes(q));
elM.textContent = `Dokumentów: ${docs.length}. Wyników: ${filtered.length}.`;
if (!filtered.length){
elR.innerHTML = `<div class="empty">Brak wyników. Spróbuj innego hasła.</div>`;
return;
}
elR.innerHTML = filtered.slice(0, 200).map(d => {
const pills = `<span class="pill">${escapeHtml(d.section)}</span><span class="pill">${escapeHtml((d.ext||'').toUpperCase())}</span>`;
const right = `${fmtDate(d.mtime)} • ${fmtSize(d.size)}`;
return `
<div class="card">
<div>
<div>${pills}</div>
<div><a href="${d.url}">${escapeHtml(d.title)}</a></div>
<div class="small">${escapeHtml(d.rel)}</div>
</div>
<div class="right">${right}</div>
</div>`;
}).join('') + (filtered.length>200 ? `<div class="empty">Pokazuję pierwsze 200 wyników – zawęź wyszukiwanie.</div>` : '');
}
async function init(){
const res = await fetch('./api.php', {cache:'no-store'});
if (!res.ok) {
const txt = await res.text();
throw new Error(`HTTP ${res.status}: ${txt}`);
}
const json = await res.json();
docs = json.docs || [];
const set = new Set(docs.map(d => d.section).filter(Boolean));
[...set].sort((a,b)=>a.localeCompare(b,'pl')).forEach(sec => {
const opt = document.createElement('option');
opt.value = sec; opt.textContent = sec;
elS.appendChild(opt);
});
elM.textContent = `Dokumentów: ${docs.length}.`;
render();
}
elQ.addEventListener('input', render);
elS.addEventListener('change', render);
init().catch(err => {
console.error(err);
elM.textContent = 'Nie udało się wczytać indeksu.';
elR.innerHTML = `
<div class="error">
<div><strong>Błąd:</strong> wyszukiwarka nie mogła zbudować indeksu.</div>
<div class="small">Najczęściej: zły katalog root albo brak uprawnień do skanowania.</div>
<div class="small">Wejdź w <code>/szukaj/api.php?debug=1</code> żeby zobaczyć gdzie skanuje.</div>
</div>`;
});
</script>
</body>
</html>