fix: 뉴스 페이지 — 닫기 버튼 + 페이지네이션 + 상세 링크 + 본문 입력
- 미리보기 닫기 버튼 추가
- 페이지네이션 (30건 단위)
- "상세" 링크 → /documents/{id}
- "본문/메모 입력" → user_note 저장
- DocumentUpdate에 is_read 필드 추가
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -72,6 +72,7 @@ class DocumentUpdate(BaseModel):
|
|||||||
ai_sub_group: str | None = None
|
ai_sub_group: str | None = None
|
||||||
ai_tags: list | None = None
|
ai_tags: list | None = None
|
||||||
user_note: str | None = None
|
user_note: str | None = None
|
||||||
|
is_read: bool | None = None
|
||||||
edit_url: str | None = None
|
edit_url: str | None = None
|
||||||
source_channel: str | None = None
|
source_channel: str | None = None
|
||||||
data_origin: str | None = None
|
data_origin: str | None = None
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
let showUnreadOnly = $state(false);
|
let showUnreadOnly = $state(false);
|
||||||
let sources = $state([]);
|
let sources = $state([]);
|
||||||
let currentPage = $state(1);
|
let currentPage = $state(1);
|
||||||
|
let noteEditing = $state(false);
|
||||||
|
let noteText = $state('');
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
try {
|
try {
|
||||||
@@ -79,6 +81,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function saveNote() {
|
||||||
|
try {
|
||||||
|
await api(`/documents/${selectedArticle.id}`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
body: JSON.stringify({ user_note: noteText }),
|
||||||
|
});
|
||||||
|
selectedArticle.user_note = noteText;
|
||||||
|
noteEditing = false;
|
||||||
|
addToast('success', '저장됨');
|
||||||
|
} catch (e) {
|
||||||
|
addToast('error', '저장 실패');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function timeAgo(dateStr) {
|
function timeAgo(dateStr) {
|
||||||
const diff = Date.now() - new Date(dateStr).getTime();
|
const diff = Date.now() - new Date(dateStr).getTime();
|
||||||
const mins = Math.floor(diff / 60000);
|
const mins = Math.floor(diff / 60000);
|
||||||
@@ -172,26 +188,83 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 페이지네이션 -->
|
||||||
|
{#if total > 30}
|
||||||
|
<div class="flex justify-center gap-1 py-2 border-t border-[var(--border)] shrink-0">
|
||||||
|
{#each Array(Math.ceil(total / 30)) as _, i}
|
||||||
|
<button
|
||||||
|
onclick={() => { currentPage = i + 1; loadArticles(); }}
|
||||||
|
class="px-2 py-0.5 rounded text-xs {currentPage === i + 1 ? 'bg-[var(--accent)] text-white' : 'text-[var(--text-dim)]'}"
|
||||||
|
>{i + 1}</button>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<!-- 하단: 기사 미리보기 -->
|
<!-- 하단: 기사 미리보기 -->
|
||||||
{#if selectedArticle}
|
{#if selectedArticle}
|
||||||
<div class="flex-1 overflow-y-auto p-5 bg-[var(--surface)]">
|
<div class="flex-1 overflow-y-auto bg-[var(--surface)] min-h-0">
|
||||||
<h2 class="text-lg font-bold mb-2">{selectedArticle.title}</h2>
|
<!-- 미리보기 헤더 -->
|
||||||
<div class="flex items-center gap-2 mb-4 text-xs text-[var(--text-dim)]">
|
<div class="flex items-center justify-between px-5 py-2 border-b border-[var(--border)] sticky top-0 bg-[var(--surface)]">
|
||||||
<span>{selectedArticle.ai_sub_group}</span>
|
<div class="flex items-center gap-2 text-xs text-[var(--text-dim)]">
|
||||||
<span>·</span>
|
<span>{selectedArticle.ai_sub_group}</span>
|
||||||
<span>{timeAgo(selectedArticle.created_at)}</span>
|
<span>·</span>
|
||||||
|
<span>{timeAgo(selectedArticle.created_at)}</span>
|
||||||
|
<span>·</span>
|
||||||
|
<span>{selectedArticle.file_format}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
{#if selectedArticle.edit_url}
|
||||||
|
<a
|
||||||
|
href={selectedArticle.edit_url}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="text-xs text-[var(--accent)] hover:underline"
|
||||||
|
>원문 보기 →</a>
|
||||||
|
{/if}
|
||||||
|
<a
|
||||||
|
href="/documents/{selectedArticle.id}"
|
||||||
|
class="text-xs text-[var(--text-dim)] hover:text-[var(--text)]"
|
||||||
|
>상세</a>
|
||||||
|
<button
|
||||||
|
onclick={() => selectedArticle = null}
|
||||||
|
class="text-xs text-[var(--text-dim)] hover:text-[var(--text)]"
|
||||||
|
>닫기</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="markdown-body mb-4">
|
|
||||||
{@html renderMd(selectedArticle.extracted_text || '')}
|
<!-- 본문 -->
|
||||||
|
<div class="p-5">
|
||||||
|
<h2 class="text-lg font-bold mb-3">{selectedArticle.title}</h2>
|
||||||
|
<div class="markdown-body mb-4">
|
||||||
|
{@html renderMd(selectedArticle.extracted_text || '')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 본문 입력 -->
|
||||||
|
{#if noteEditing}
|
||||||
|
<div class="mt-4 border-t border-[var(--border)] pt-4">
|
||||||
|
<h4 class="text-xs font-semibold text-[var(--text-dim)] mb-2">본문 / 메모 입력</h4>
|
||||||
|
<textarea
|
||||||
|
bind:value={noteText}
|
||||||
|
class="w-full h-32 px-3 py-2 bg-[var(--bg)] border border-[var(--border)] rounded-lg text-sm text-[var(--text)] resize-y outline-none focus:border-[var(--accent)]"
|
||||||
|
placeholder="기사 본문이나 메모를 입력하세요..."
|
||||||
|
></textarea>
|
||||||
|
<div class="flex gap-2 mt-2">
|
||||||
|
<button onclick={saveNote} class="px-3 py-1 text-xs bg-[var(--accent)] text-white rounded">저장</button>
|
||||||
|
<button onclick={() => noteEditing = false} class="px-3 py-1 text-xs text-[var(--text-dim)]">취소</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<button
|
||||||
|
onclick={() => { noteText = selectedArticle.user_note || ''; noteEditing = true; }}
|
||||||
|
class="mt-4 text-xs text-[var(--text-dim)] hover:text-[var(--accent)]"
|
||||||
|
>+ 본문/메모 입력</button>
|
||||||
|
{#if selectedArticle.user_note}
|
||||||
|
<div class="mt-2 p-3 bg-[var(--bg)] rounded-lg text-sm">
|
||||||
|
{selectedArticle.user_note}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#if selectedArticle.edit_url}
|
|
||||||
<a
|
|
||||||
href={selectedArticle.edit_url}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
class="inline-flex items-center gap-2 px-4 py-2 bg-[var(--accent)] text-white rounded-lg hover:bg-[var(--accent-hover)] text-sm"
|
|
||||||
>원문 보기 →</a>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user