78 lines
2.2 KiB
TypeScript
78 lines
2.2 KiB
TypeScript
/**
|
|
* CreateSessionDialog — modal for naming a new session
|
|
*/
|
|
import { Component, createSignal, onMount } from "solid-js";
|
|
import { createSession } from "../stores/journalStream";
|
|
|
|
interface CreateSessionDialogProps {
|
|
onClose: () => void;
|
|
}
|
|
|
|
export const CreateSessionDialog: Component<CreateSessionDialogProps> = (
|
|
props,
|
|
) => {
|
|
const [name, setName] = createSignal("");
|
|
let inputRef!: HTMLInputElement;
|
|
|
|
const handleCreate = () => {
|
|
const trimmed = name().trim();
|
|
if (!trimmed) return;
|
|
createSession(trimmed);
|
|
setName("");
|
|
props.onClose();
|
|
};
|
|
|
|
onMount(() => inputRef?.focus());
|
|
|
|
return (
|
|
<div
|
|
class="absolute inset-0 z-50 flex items-center justify-center bg-black/20"
|
|
onClick={props.onClose}
|
|
>
|
|
<div
|
|
class="bg-white rounded-lg border border-gray-200 shadow-xl w-[280px] p-4 space-y-3"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<div class="flex items-center justify-between">
|
|
<h3 class="text-sm font-semibold text-gray-800">新建会话</h3>
|
|
<button
|
|
onClick={props.onClose}
|
|
class="text-gray-400 hover:text-gray-600 text-sm"
|
|
>
|
|
✕
|
|
</button>
|
|
</div>
|
|
<p class="text-xs text-gray-500">输入新会话的名称。</p>
|
|
<input
|
|
ref={inputRef!}
|
|
type="text"
|
|
value={name()}
|
|
onInput={(e) => setName(e.currentTarget.value)}
|
|
onKeyDown={(e) => {
|
|
if (e.key === "Enter") handleCreate();
|
|
if (e.key === "Escape") props.onClose();
|
|
}}
|
|
placeholder="会话名称"
|
|
class="w-full border border-gray-300 rounded px-2 py-1.5 text-sm"
|
|
autofocus
|
|
/>
|
|
<div class="flex justify-end gap-1">
|
|
<button
|
|
onClick={props.onClose}
|
|
class="px-3 py-1 text-xs text-gray-600 hover:text-gray-800"
|
|
>
|
|
取消
|
|
</button>
|
|
<button
|
|
onClick={handleCreate}
|
|
disabled={!name().trim()}
|
|
class="bg-blue-600 text-white rounded px-3 py-1 text-xs font-medium hover:bg-blue-700 disabled:opacity-50"
|
|
>
|
|
创建
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|