Initial Commit
This commit is contained in:
58
templates/board.html
Normal file
58
templates/board.html
Normal file
@@ -0,0 +1,58 @@
|
||||
{% extends 'base.html' %}{% block title %}Intercom — {{ brand }}{% endblock %}
|
||||
{% block content %}
|
||||
<section class="max-w-5xl mx-auto">
|
||||
<div class="card glass p-4">
|
||||
<textarea id="composer" rows="3" class="w-full" placeholder="Share an update…" {% if not can_post %}disabled{% endif %}></textarea>
|
||||
<div class="mt-3 flex items-center justify-between">
|
||||
<div class="text-xs text-white/60">{% if not can_post %}You don’t have permission to post.{% endif %}</div>
|
||||
<button id="sendBtn" class="btn bg-accent font-semibold" {% if not can_post %}disabled{% endif %}>Post</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-6 space-y-3" id="board">
|
||||
{% for m in messages %}
|
||||
<article class="card glass p-4">
|
||||
<div class="flex items-start gap-3">
|
||||
{% if m.avatar %}<img src="{{ m.avatar }}" class="size-9 rounded-lg">{% else %}<div class="size-9 rounded-lg bg-white/10 grid place-items-center">🟣</div>{% endif %}
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="font-semibold">{{ m.username }}</div>
|
||||
{% if m.timestamp %}<div class="text-xs text-white/50">{{ m.timestamp.replace('T',' ').replace('Z',' UTC') }}</div>{% endif %}
|
||||
</div>
|
||||
<div class="mt-1 whitespace-pre-wrap text-white/90">{{ m.content }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="mt-4 text-center"><button id="refreshBtn" class="btn">Refresh</button></div>
|
||||
</section>
|
||||
<script>
|
||||
const board=document.getElementById('board'), sendBtn=document.getElementById('sendBtn'), composer=document.getElementById('composer');
|
||||
function esc(s){return (s||'').replaceAll('&','&').replaceAll('<','<').replaceAll('>','>');}
|
||||
async function fetchMessages(){
|
||||
const r=await fetch('/api/board/messages'); if(!r.ok) return;
|
||||
const data=await r.json();
|
||||
board.innerHTML=data.map(m=>`
|
||||
<article class="card glass p-4">
|
||||
<div class="flex items-start gap-3">
|
||||
${m.avatar?`<img src="${m.avatar}" class="size-9 rounded-lg">`:`<div class="size-9 rounded-lg bg-white/10 grid place-items-center">🟣</div>`}
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="font-semibold">${esc(m.username)}</div>
|
||||
${m.timestamp?`<div class="text-xs text-white/50">${esc(m.timestamp.replace('T',' ').replace('Z',' UTC'))}</div>`:''}
|
||||
</div>
|
||||
<div class="mt-1 whitespace-pre-wrap text-white/90">${esc(m.content)}</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>`).join('');
|
||||
}
|
||||
async function postMessage(){
|
||||
const content=(composer.value||'').trim(); if(!content) return;
|
||||
const r=await fetch('/api/board/post',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({content})});
|
||||
if(r.ok){composer.value=''; fetchMessages()} else {const e=await r.json().catch(()=>({error:'Failed'})); alert(e.error||'Failed')}
|
||||
}
|
||||
document.getElementById('refreshBtn').addEventListener('click', fetchMessages);
|
||||
sendBtn?.addEventListener('click', postMessage);
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user