zkt26/sk1/web/nginx/html/index.html
2026-05-13 21:49:47 +02:00

93 lines
4.1 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Read it later</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
background: #fff;
color: #1a1a1a;
max-width: 640px;
margin: 0 auto;
padding: 48px 24px;
}
h1 { font-size: 20px; font-weight: 600; margin-bottom: 32px; }
.input-row { display: flex; gap: 8px; margin-bottom: 12px; }
input[type="url"] {
flex: 1; padding: 10px 14px; border: 1px solid #ddd;
border-radius: 8px; font-size: 14px; outline: none;
}
input[type="url"]:focus { border-color: #999; }
button {
padding: 10px 20px; background: #1a1a1a; color: #fff;
border: none; border-radius: 8px; font-size: 14px; cursor: pointer;
}
button:hover { background: #333; }
button:disabled { background: #999; cursor: not-allowed; }
.error { color: #c00; font-size: 13px; margin-bottom: 24px; min-height: 18px; }
.articles { display: flex; flex-direction: column; gap: 24px; margin-top: 24px; }
.article { padding-bottom: 24px; border-bottom: 1px solid #eee; }
.article:last-child { border-bottom: none; }
.article-url { font-size: 12px; color: #999; word-break: break-all; margin-bottom: 4px; }
.article-title { font-size: 16px; font-weight: 600; margin-bottom: 8px; }
.article-summary { font-size: 14px; color: #555; line-height: 1.6; }
.article-date { font-size: 12px; color: #bbb; margin-top: 8px; }
.empty { color: #bbb; font-size: 14px; text-align: center; padding: 48px 0; }
</style>
</head>
<body>
<h1>Read it later</h1>
<form class="input-row" id="form">
<input type="url" id="url" placeholder="Paste article URL..." required>
<button type="submit" id="btn">Save</button>
</form>
<div id="error" class="error"></div>
<div class="articles" id="articles"></div>
<script>
const API = '/api';
async function load() {
try {
const r = await fetch(API + '/articles');
const data = await r.json();
const el = document.getElementById('articles');
if (!data.length) { el.innerHTML = '<div class="empty">No articles yet</div>'; return; }
el.innerHTML = data.map(a => `
<div class="article">
<div class="article-url">${a.url}</div>
<div class="article-title">${a.title || 'Untitled'}</div>
<div class="article-summary">${a.summary || 'Processing...'}</div>
<div class="article-date">${new Date(a.created_at).toLocaleDateString()}</div>
</div>`).join('');
} catch (e) {
document.getElementById('articles').innerHTML = '<div class="empty">Failed to load</div>';
}
}
document.getElementById('form').addEventListener('submit', async (e) => {
e.preventDefault();
const btn = document.getElementById('btn');
const inp = document.getElementById('url');
const err = document.getElementById('error');
btn.disabled = true; btn.textContent = '...'; err.textContent = '';
try {
const r = await fetch(API + '/articles', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({url: inp.value})
});
if (!r.ok) throw new Error((await r.json()).detail || 'Error');
inp.value = '';
await load();
} catch (e) { err.textContent = e.message; }
finally { btn.disabled = false; btn.textContent = 'Save'; }
});
load();
</script>
</body>
</html>