Files
scannerbot/ui/index.html
T
2026-06-03 01:30:38 +00:00

84 lines
2.3 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ScannerBot</title>
</head>
<body>
<div x-data="app()" x-init="init()">
<h1>ScannerBot</h1>
<p>Logged in as <strong x-text="username"></strong></p>
<button @click="doLogout()">Logout</button>
<p x-show="error" x-text="error" style="color:red"></p>
<ul>
<template x-for="ch in channels" :key="ch.ID">
<li>
<button @click="selectChannel(ch)" x-text="ch.Name"></button>
</li>
</template>
</ul>
<template x-if="selectedChannel">
<div>
<h2 x-text="selectedChannel.Name"></h2>
<ul>
<template x-for="msg in messages" :key="msg.ID">
<li>
<small x-text="msg.Created"></small>
<span x-text="msg.Content"></span>
</li>
</template>
</ul>
</div>
</template>
</div>
<script type="module">
import Alpine from 'alpinejs'
import { requireAuth } from '/src/auth.js'
import { logout, getchannels, getmessages } from '/src/api.js'
window.app = () => ({
username: '',
error: '',
channels: [],
selectedChannel: null,
messages: [],
async init() {
const username = await requireAuth()
if (!username) return
this.username = username
try {
this.channels = await getchannels()
} catch (e) {
this.error = e.message
}
},
async selectChannel(ch) {
this.selectedChannel = ch
this.messages = []
this.error = ''
try {
const from = new Date(Date.now() - 96 * 60 * 60 * 1000)
const to = new Date(Date.now())
this.messages = await getmessages(ch.ID, { from, to })
} catch (e) {
this.error = e.message
}
},
async doLogout() {
try {
await logout()
} finally {
window.location.href = '/login.html'
}
},
})
window.Alpine = Alpine
Alpine.start()
</script>
</body>
</html>