From a15208f0cf595ff3f93151b396dbd0f408c2002b Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Fri, 3 Apr 2026 09:11:13 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20Phase=201C=20=E2=80=94=20=ED=94=84?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=ED=8C=A8=EB=84=90=20(=EB=AC=B8=EC=84=9C?= =?UTF-8?q?=20=EC=84=A0=ED=83=9D=20=EC=8B=9C=20=EC=9A=B0=EC=B8=A1=20?= =?UTF-8?q?=ED=91=9C=EC=8B=9C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PreviewPanel: AI 요약, 태그, 메타 정보, 처리 상태 표시 - DocumentCard: 선택 모드 지원 (클릭→프리뷰, 더블클릭 불필요) - 3-pane 완성: sidebar | document list | preview panel - 필터 변경 시 선택 자동 해제 - 데스크톱만 표시 (모바일은 detail 페이지로 이동) Co-Authored-By: Claude Opus 4.6 (1M context) --- .../src/lib/components/DocumentCard.svelte | 14 ++- .../src/lib/components/PreviewPanel.svelte | 119 ++++++++++++++++++ frontend/src/routes/documents/+page.svelte | 27 +++- 3 files changed, 153 insertions(+), 7 deletions(-) create mode 100644 frontend/src/lib/components/PreviewPanel.svelte diff --git a/frontend/src/lib/components/DocumentCard.svelte b/frontend/src/lib/components/DocumentCard.svelte index 274d636..9f6a3c1 100644 --- a/frontend/src/lib/components/DocumentCard.svelte +++ b/frontend/src/lib/components/DocumentCard.svelte @@ -2,7 +2,7 @@ import FormatIcon from './FormatIcon.svelte'; import TagPill from './TagPill.svelte'; - let { doc, showDomain = true } = $props(); + let { doc, showDomain = true, selected = false, onselect = null } = $props(); function formatDate(dateStr) { if (!dateStr) return ''; @@ -23,9 +23,13 @@ } - { e.preventDefault(); onselect(doc); } : undefined} + class="flex items-start gap-3 p-3 bg-[var(--surface)] border rounded-lg hover:border-[var(--accent)] transition-colors group w-full text-left + {selected ? 'border-[var(--accent)] bg-[var(--accent)]/5' : 'border-[var(--border)]'}" >
@@ -76,4 +80,4 @@ {formatSize(doc.file_size)} {/if}
-
+ diff --git a/frontend/src/lib/components/PreviewPanel.svelte b/frontend/src/lib/components/PreviewPanel.svelte new file mode 100644 index 0000000..603a14f --- /dev/null +++ b/frontend/src/lib/components/PreviewPanel.svelte @@ -0,0 +1,119 @@ + + + diff --git a/frontend/src/routes/documents/+page.svelte b/frontend/src/routes/documents/+page.svelte index 89dc07d..bfdf3e0 100644 --- a/frontend/src/routes/documents/+page.svelte +++ b/frontend/src/routes/documents/+page.svelte @@ -4,8 +4,10 @@ import { api } from '$lib/api'; import { addToast } from '$lib/stores/ui'; import DocumentCard from '$lib/components/DocumentCard.svelte'; + import PreviewPanel from '$lib/components/PreviewPanel.svelte'; let documents = $state([]); + let selectedDoc = $state(null); let total = $state(0); let loading = $state(true); let searchQuery = $state(''); @@ -29,6 +31,8 @@ searchQuery = urlQ; searchMode = urlMode; + selectedDoc = null; // 필터 변경 시 선택 해제 + if (urlQ) { doSearch(urlQ, urlMode); } else { @@ -112,9 +116,15 @@ let totalPages = $derived(Math.ceil(total / 20)); let items = $derived(searchResults || documents); let hasActiveFilters = $derived(!!filterDomain || !!filterSubGroup || !!searchQuery); + + function selectDoc(doc) { + selectedDoc = selectedDoc?.id === doc.id ? null : doc; + } -
+
+ +
{#each items as doc} - + {/each}
@@ -203,3 +218,11 @@ {/if} {/if}
+ + +{#if selectedDoc} + +{/if} +