112 lines
3.9 KiB
Svelte
112 lines
3.9 KiB
Svelte
<script lang="ts">
|
|
import type { AgendaContext } from '@ka-note/shared';
|
|
import { upsertContext } from '$lib/db/repositories';
|
|
import { scopeSettings } from '$lib/stores/scopeContext';
|
|
|
|
interface Props {
|
|
context: AgendaContext;
|
|
mode?: 'prep' | 'meeting';
|
|
onmodechange?: (mode: 'prep' | 'meeting') => void;
|
|
journalScope?: 'business' | 'private';
|
|
onjournalscopechange?: (scope: 'business' | 'private') => void;
|
|
}
|
|
let { context, mode, onmodechange, journalScope, onjournalscopechange }: Props = $props();
|
|
|
|
const showModeSwitch = $derived(!!onmodechange && context.type === 'meeting' && context.id !== 'daily-log');
|
|
const showScopeSwitch = $derived(!!onjournalscopechange && context.id === 'daily-log');
|
|
const canRename = $derived(context.id !== 'daily-log');
|
|
let editing = $state(false);
|
|
let nameInput = $state('');
|
|
|
|
function editableName(): string {
|
|
return context.name.replace(/^(Person |Project |Firma )/, '');
|
|
}
|
|
|
|
function fullName(input: string): string {
|
|
if (context.type === 'person') return 'Person ' + input;
|
|
if (context.type === 'project') return 'Project ' + input;
|
|
if (context.type === 'company') return 'Firma ' + input;
|
|
return input;
|
|
}
|
|
|
|
function startEdit() {
|
|
nameInput = editableName();
|
|
editing = true;
|
|
}
|
|
|
|
async function saveEdit() {
|
|
editing = false;
|
|
const trimmed = nameInput.trim();
|
|
if (!trimmed || trimmed === editableName()) return;
|
|
await upsertContext({ id: context.id, name: fullName(trimmed) });
|
|
}
|
|
|
|
function onKeydown(e: KeyboardEvent) {
|
|
if (e.key === 'Enter') {
|
|
e.preventDefault();
|
|
(e.target as HTMLInputElement).blur();
|
|
} else if (e.key === 'Escape') {
|
|
editing = false;
|
|
}
|
|
}
|
|
|
|
const headerColor = $derived(
|
|
showScopeSwitch
|
|
? (journalScope === 'private' ? $scopeSettings.privateColor : $scopeSettings.businessColor)
|
|
: $scopeSettings.businessColor
|
|
);
|
|
</script>
|
|
|
|
<h1 class="flex items-center justify-between border-b-2 pb-2.5 mb-5" style="border-color: {headerColor}">
|
|
{#if editing}
|
|
<input
|
|
class="text-2xl font-bold bg-transparent border-b-2 text-inherit outline-none w-full mr-4"
|
|
style="border-color: {headerColor}"
|
|
bind:value={nameInput}
|
|
onkeydown={onKeydown}
|
|
onblur={saveEdit}
|
|
autofocus
|
|
/>
|
|
{:else}
|
|
<span class="text-2xl font-bold">{context.name}</span>
|
|
{#if canRename}
|
|
<button
|
|
class="ml-2 text-[#888] hover:text-white bg-transparent border-none cursor-pointer text-base"
|
|
onclick={startEdit}
|
|
title="Rename"
|
|
>✎</button>
|
|
{/if}
|
|
{/if}
|
|
|
|
{#if showModeSwitch}
|
|
<div class="flex gap-1 rounded-full bg-[#333] p-1">
|
|
<button
|
|
class="rounded-full border-none px-3 py-1.5 text-sm font-bold transition-all {mode === 'prep' ? 'bg-accent text-white shadow-md' : 'bg-transparent text-[#aaa] cursor-pointer'}"
|
|
onclick={() => onmodechange?.('prep')}
|
|
>
|
|
Vorbereitung
|
|
</button>
|
|
<button
|
|
class="rounded-full border-none px-3 py-1.5 text-sm font-bold transition-all {mode === 'meeting' ? 'bg-warning text-[#222] shadow-md' : 'bg-transparent text-[#aaa] cursor-pointer'}"
|
|
onclick={() => onmodechange?.('meeting')}
|
|
>
|
|
Meeting
|
|
</button>
|
|
</div>
|
|
{/if}
|
|
{#if showScopeSwitch}
|
|
<div class="flex gap-1 rounded-full bg-[#333] p-1">
|
|
<button
|
|
class="rounded-full border-none px-3 py-1.5 text-sm font-bold transition-all {journalScope === 'business' ? 'text-white shadow-md' : 'bg-transparent text-[#aaa] cursor-pointer'}"
|
|
style={journalScope === 'business' ? `background-color: ${$scopeSettings.businessColor}` : ''}
|
|
onclick={() => onjournalscopechange?.('business')}
|
|
>Firma</button>
|
|
<button
|
|
class="rounded-full border-none px-3 py-1.5 text-sm font-bold transition-all {journalScope === 'private' ? 'text-white shadow-md' : 'bg-transparent text-[#aaa] cursor-pointer'}"
|
|
style={journalScope === 'private' ? `background-color: ${$scopeSettings.privateColor}` : ''}
|
|
onclick={() => onjournalscopechange?.('private')}
|
|
>Privat</button>
|
|
</div>
|
|
{/if}
|
|
</h1>
|