feat(journals): add drag-and-drop zone to import modal

This commit is contained in:
Scott Idem
2026-01-13 23:30:30 -05:00
parent d691fa8cb3
commit 07bb31f412

View File

@@ -20,6 +20,7 @@
let is_parsing = $state(false);
let is_importing = $state(false);
let import_log: string[] = $state([]);
let is_dragging = $state(false);
// Watch for file selection or parser change to trigger parsing
$effect(() => {
@@ -28,6 +29,34 @@
}
});
function handle_drag_enter(e: DragEvent) {
e.preventDefault();
e.stopPropagation();
is_dragging = true;
}
function handle_drag_leave(e: DragEvent) {
e.preventDefault();
e.stopPropagation();
is_dragging = false;
}
function handle_drag_over(e: DragEvent) {
e.preventDefault();
e.stopPropagation();
is_dragging = true;
}
function handle_drop(e: DragEvent) {
e.preventDefault();
e.stopPropagation();
is_dragging = false;
if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {
files = e.dataTransfer.files;
}
}
async function parse_files() {
if (!files) return;
is_parsing = true;
@@ -120,16 +149,41 @@
</label>
</div>
<div>
<label class="label">
<div class="label mb-2">
<span>Select Files</span>
</div>
<!-- Drop Zone -->
<!-- svelte-ignore a11y_click_events_have_key_events -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
class="
border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-all duration-200
flex flex-col items-center justify-center gap-2
{is_dragging ? 'border-primary-500 bg-primary-50 dark:bg-primary-900/20' : 'border-gray-300 dark:border-gray-600 hover:border-gray-400 dark:hover:border-gray-500'}
"
ondragenter={handle_drag_enter}
ondragleave={handle_drag_leave}
ondragover={handle_drag_over}
ondrop={handle_drop}
onclick={() => document.getElementById('file_import_input')?.click()}
>
<Upload class="h-10 w-10 text-gray-400" />
<p class="text-sm text-gray-500">
<span class="font-semibold text-primary-600 hover:text-primary-500">Click to upload</span>
or drag and drop
</p>
<p class="text-xs text-gray-400">Markdown (.md) or Text (.txt) files</p>
<input
id="file_import_input"
type="file"
class="file-input w-full"
class="hidden"
multiple
accept=".md,.txt"
onchange={(e) => files = e.currentTarget.files}
/>
</label>
</div>
</div>
</div>