Merge pull request #69 from kristianwind/ai-dagens-plan-2
CI / OpenAPI is valid (push) Successful in 11s
CI / End-to-end (push) Successful in 10m57s
CI / Docker image builds (push) Successful in 2m19s
Release / Build and publish image (push) Failing after 7s
CI / Go (push) Failing after 15m3s

feat(ai): dagens plan, mails der giver mening, og svar på et spørgsmål
This commit is contained in:
Kristian Wind
2026-09-08 15:15:48 +02:00
committed by GitHub
18 changed files with 1348 additions and 15 deletions
@@ -86,6 +86,39 @@
// --- the list -----------------------------------------------------------------
// Dagens plan: én besked om morgenen om det, der venter. Slået fra som
// udgangspunkt — en besked klokken syv, man ikke har bedt om, er ikke en hjælp.
let plan = $state(null);
let planBusy = $state(false);
$effect(() => {
api
.planSettings()
.then((p) => (plan = p))
.catch(() => {});
});
async function savePlan(change) {
try {
plan = await api.setPlanSettings(change);
} catch (e) {
app.toast(humanMessage(e));
}
}
async function sendPlanNow() {
if (planBusy) return;
planBusy = true;
try {
const r = await api.planNow();
app.toast(r.sent ? t('ai.planSent') : t('ai.planNothing'));
} catch (e) {
app.toast(humanMessage(e));
} finally {
planBusy = false;
}
}
let notifications = $state([]);
let unread = $state(0);
let loading = $state(true);
@@ -180,6 +213,45 @@
});
</script>
<section class="panel">
<header>
<h2>{t('ai.plan')}</h2>
<p class="hint">{t('ai.planHint')}</p>
</header>
{#if plan}
<label class="check">
<input
type="checkbox"
checked={plan.enabled}
onchange={(e) => savePlan({ enabled: e.currentTarget.checked })}
/>
<span>{t('ai.plan')}</span>
</label>
{#if plan.enabled}
<div class="field">
<label for="planhour">{t('ai.planHour')}</label>
<select
id="planhour"
value={plan.hour}
onchange={(e) => savePlan({ hour: Number(e.currentTarget.value) })}
>
{#each Array.from({ length: 24 }, (_, i) => i) as hour (hour)}
<option value={hour}>{String(hour).padStart(2, '0')}:00</option>
{/each}
</select>
</div>
<!-- En indstilling, man skal vente til i morgen for at se virkningen af,
er en indstilling, ingen tør slå til. -->
<button class="secondary" disabled={planBusy} onclick={sendPlanNow}>
{t('ai.planNow')}
</button>
{/if}
{/if}
</section>
<section class="panel">
<header>
<h2>{t('push.title')}</h2>