ui update

This commit is contained in:
beo3000 2026-02-20 22:24:26 +01:00
parent 512c17a78c
commit 46047ca543
5 changed files with 133 additions and 19 deletions

View File

@ -282,6 +282,12 @@
{/if} {/if}
<div class="mt-auto border-t border-border pt-3"> <div class="mt-auto border-t border-border pt-3">
<button
class="mb-1 w-full rounded px-2.5 py-2 text-left text-xs text-muted transition-colors hover:bg-white/5 hover:text-white"
onclick={() => { goto('/settings'); onnavigate?.(); }}
>
Einstellungen
</button>
{#if $account} {#if $account}
<div class="mb-2 truncate px-1 text-xs text-muted" title={$account.username}> <div class="mb-2 truncate px-1 text-xs text-muted" title={$account.username}>
{$account.name ?? $account.username} {$account.name ?? $account.username}

View File

@ -2,37 +2,68 @@
import { liveQuery } from 'dexie'; import { liveQuery } from 'dexie';
import { db } from '$lib/db/schema'; import { db } from '$lib/db/schema';
import { updateTopic } from '$lib/db/repositories'; import { updateTopic } from '$lib/db/repositories';
import type { Topic, AgendaContext } from '@ka-note/shared';
interface Props { interface Props {
contextId: string; contextId: string;
} }
let { contextId }: Props = $props(); let { contextId }: Props = $props();
const isDailyLog = $derived(contextId === 'daily-log');
const snoozedTopics = liveQuery(() => const snoozedTopics = liveQuery(() =>
db.topics isDailyLog
.where('contextId').equals(contextId) ? db.topics.filter(t => !t.deletedAt && t.status === 'snoozed' && !!t.snoozeUntil).toArray()
.filter(t => !t.deletedAt && t.status === 'snoozed' && !!t.snoozeUntil) : db.topics.where('contextId').equals(contextId)
.toArray() .filter(t => !t.deletedAt && t.status === 'snoozed' && !!t.snoozeUntil)
.toArray()
); );
const contexts = liveQuery(() => db.contexts.filter(c => !c.deletedAt).toArray());
const contextMap = $derived(
new Map(($contexts ?? []).map((c: AgendaContext) => [c.id, c.name]))
);
const grouped = $derived(() => {
const topics = $snoozedTopics ?? [];
const groups = new Map<string, Topic[]>();
for (const t of topics) {
const date = t.snoozeUntil!;
const list = groups.get(date) ?? [];
list.push(t);
groups.set(date, list);
}
return [...groups.entries()].sort(([a], [b]) => a.localeCompare(b));
});
function reactivate(id: string) { function reactivate(id: string) {
updateTopic(id, { snoozeUntil: null, status: 'active', isNew: false }); updateTopic(id, { snoozeUntil: null, status: 'active', isNew: false });
} }
</script> </script>
{#each $snoozedTopics ?? [] as topic (topic.id)} {#each grouped() as [date, topics]}
<div class="mb-5 rounded-lg border-l-[5px] border-l-muted bg-card-bg opacity-60"> <div class="mb-6">
<div class="flex items-center justify-between px-5 py-4"> <div class="mb-2 text-sm font-bold text-accent">{date}</div>
<span class="text-lg font-bold">{topic.title}</span> {#each topics as topic (topic.id)}
<button <div class="mb-2 rounded-lg border-l-[5px] border-l-muted bg-card-bg opacity-60">
class="rounded bg-success px-4 py-2 font-bold text-white" <div class="flex items-center justify-between px-5 py-4">
onclick={() => reactivate(topic.id)} <div>
> <span class="text-lg font-bold">{topic.title}</span>
Reaktivieren {#if isDailyLog && topic.contextId !== 'daily-log'}
</button> <span class="ml-2 text-xs text-muted">{contextMap.get(topic.contextId) ?? topic.contextId}</span>
</div> {/if}
<div class="px-5 pb-4 text-[#aaa]">Bis: {topic.snoozeUntil}</div> </div>
<button
class="rounded bg-success px-4 py-2 font-bold text-white"
onclick={() => reactivate(topic.id)}
>
Reaktivieren
</button>
</div>
</div>
{/each}
</div> </div>
{:else} {:else}
<div class="text-center text-muted">Leer.</div> <div class="text-center text-muted">Keine verschobenen Themen.</div>
{/each} {/each}

View File

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import type { AgendaContext, PersonMeta } from '@ka-note/shared'; import type { AgendaContext, PersonMeta } from '@ka-note/shared';
import { settings } from '$lib/stores/settings';
interface Props { interface Props {
context: AgendaContext; context: AgendaContext;
@ -20,13 +21,16 @@
const isCompany = $derived(context.type === 'company'); const isCompany = $derived(context.type === 'company');
const isEmployee = $derived(isPerson && ((context.meta as PersonMeta | null)?.personSubType ?? 'contact') === 'employee'); const isEmployee = $derived(isPerson && ((context.meta as PersonMeta | null)?.personSubType ?? 'contact') === 'employee');
const showAgenda = $derived(!isDailyLog || $settings.showAgendaTab);
const showSnoozed = $derived(!isDailyLog || $settings.showSnoozedTab);
const tabs = $derived<Tab[]>( const tabs = $derived<Tab[]>(
isMeeting isMeeting
? [ ? [
...(isDailyLog ? [] : [{ id: 'agenda', label: 'Agenda / Eingabe' }]), ...(showAgenda ? [{ id: 'agenda', label: 'Agenda / Eingabe' }] : []),
{ id: 'journal', label: 'Journal / Historie' }, { id: 'journal', label: 'Journal / Historie' },
{ id: 'persons', label: 'Personen (All)' }, { id: 'persons', label: 'Personen (All)' },
{ id: 'snoozed', label: 'Verschoben' } ...(showSnoozed ? [{ id: 'snoozed', label: 'Verschoben' }] : [])
] ]
: [ : [
{ id: 'dashboard', label: `Dashboard: ${context.name.replace(/^(Project |Person |Firma )/, '')}` }, { id: 'dashboard', label: `Dashboard: ${context.name.replace(/^(Project |Person |Firma )/, '')}` },

View File

@ -0,0 +1,44 @@
import { writable } from 'svelte/store';
export interface AppSettings {
showAgendaTab: boolean;
showSnoozedTab: boolean;
}
const STORAGE_KEY = 'ka-note-settings';
const defaults: AppSettings = {
showAgendaTab: false,
showSnoozedTab: true
};
function load(): AppSettings {
if (typeof localStorage === 'undefined') return defaults;
try {
const raw = localStorage.getItem(STORAGE_KEY);
return raw ? { ...defaults, ...JSON.parse(raw) } : defaults;
} catch {
return defaults;
}
}
function createSettingsStore() {
const { subscribe, set, update } = writable<AppSettings>(load());
subscribe(v => {
if (typeof localStorage !== 'undefined') {
localStorage.setItem(STORAGE_KEY, JSON.stringify(v));
}
});
return {
subscribe,
set,
update,
patch(partial: Partial<AppSettings>) {
update(s => ({ ...s, ...partial }));
}
};
}
export const settings = createSettingsStore();

View File

@ -0,0 +1,29 @@
<script lang="ts">
import { settings } from '$lib/stores/settings';
</script>
<h1 class="mb-6 text-2xl font-bold text-accent">Einstellungen</h1>
<div class="rounded-lg border border-border bg-sidebar p-5">
<h2 class="mb-4 text-lg font-bold text-white">Daily Log Tabs</h2>
<label class="mb-3 flex items-center gap-3 cursor-pointer">
<input
type="checkbox"
class="h-4 w-4 accent-accent"
checked={$settings.showAgendaTab}
onchange={(e) => settings.patch({ showAgendaTab: e.currentTarget.checked })}
/>
<span class="text-[#ccc]">Agenda-Tab anzeigen</span>
</label>
<label class="flex items-center gap-3 cursor-pointer">
<input
type="checkbox"
class="h-4 w-4 accent-accent"
checked={$settings.showSnoozedTab}
onchange={(e) => settings.patch({ showSnoozedTab: e.currentTarget.checked })}
/>
<span class="text-[#ccc]">Verschoben-Tab anzeigen</span>
</label>
</div>