fix: 3+4단계 — 반응형/에러분기/a11y/Synology URL
- DocumentCard: window.innerWidth → matchMedia (반응형 정확) - documents/[id]: 로딩 상태 3분기 (loading/not_found/network) - documents/[id]: Synology URL 하드코딩 → edit_url fallback - DocumentCard: aria-label 추가 - Toast: aria-live 이미 적용 (1단계) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -35,9 +35,14 @@
|
|||||||
|
|
||||||
let domainColor = $derived(DOMAIN_COLORS[doc.ai_domain] || 'var(--border)');
|
let domainColor = $derived(DOMAIN_COLORS[doc.ai_domain] || 'var(--border)');
|
||||||
|
|
||||||
|
// 반응형: CSS media query matchMedia 사용
|
||||||
|
let isDesktop = $state(typeof window !== 'undefined' ? window.matchMedia('(min-width: 1024px)').matches : true);
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
window.matchMedia('(min-width: 1024px)').addEventListener('change', (e) => isDesktop = e.matches);
|
||||||
|
}
|
||||||
|
|
||||||
function handleClick() {
|
function handleClick() {
|
||||||
// 모바일에서는 항상 detail 페이지로 이동
|
if (!isDesktop) {
|
||||||
if (window.innerWidth < 1024) {
|
|
||||||
goto(`/documents/${doc.id}`);
|
goto(`/documents/${doc.id}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -51,6 +56,7 @@
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
onclick={handleClick}
|
onclick={handleClick}
|
||||||
|
aria-label={doc.title || '문서 선택'}
|
||||||
class="flex items-stretch bg-[var(--surface)] border rounded-lg hover:border-[var(--accent)] transition-colors group w-full text-left overflow-hidden
|
class="flex items-stretch bg-[var(--surface)] border rounded-lg hover:border-[var(--accent)] transition-colors group w-full text-left overflow-hidden
|
||||||
{selected ? 'border-[var(--accent)] bg-[var(--accent)]/5' : 'border-[var(--border)]'}"
|
{selected ? 'border-[var(--accent)] bg-[var(--accent)]/5' : 'border-[var(--border)]'}"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
let doc = $state(null);
|
let doc = $state(null);
|
||||||
let loading = $state(true);
|
let loading = $state(true);
|
||||||
|
let error = $state(null); // 'not_found' | 'network' | null
|
||||||
|
|
||||||
let docId = $derived($page.params.id);
|
let docId = $derived($page.params.id);
|
||||||
|
|
||||||
@@ -26,7 +27,7 @@
|
|||||||
try {
|
try {
|
||||||
doc = await api(`/documents/${docId}`);
|
doc = await api(`/documents/${docId}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
addToast('error', '문서를 찾을 수 없습니다');
|
error = err?.status === 404 ? 'not_found' : 'network';
|
||||||
} finally {
|
} finally {
|
||||||
loading = false;
|
loading = false;
|
||||||
}
|
}
|
||||||
@@ -56,6 +57,16 @@
|
|||||||
<div class="max-w-6xl mx-auto p-6">
|
<div class="max-w-6xl mx-auto p-6">
|
||||||
<div class="bg-[var(--surface)] rounded-xl p-6 border border-[var(--border)] animate-pulse h-96"></div>
|
<div class="bg-[var(--surface)] rounded-xl p-6 border border-[var(--border)] animate-pulse h-96"></div>
|
||||||
</div>
|
</div>
|
||||||
|
{:else if error === 'not_found'}
|
||||||
|
<div class="text-center py-20 text-[var(--text-dim)]">
|
||||||
|
<p class="text-lg mb-2">문서를 찾을 수 없습니다</p>
|
||||||
|
<a href="/documents" class="text-sm text-[var(--accent)] hover:underline">목록으로 돌아가기</a>
|
||||||
|
</div>
|
||||||
|
{:else if error === 'network'}
|
||||||
|
<div class="text-center py-20 text-[var(--text-dim)]">
|
||||||
|
<p class="text-lg mb-2">문서를 불러올 수 없습니다</p>
|
||||||
|
<button onclick={() => location.reload()} class="text-sm text-[var(--accent)] hover:underline">다시 시도</button>
|
||||||
|
</div>
|
||||||
{:else if doc}
|
{:else if doc}
|
||||||
<div class="max-w-6xl mx-auto p-6 grid grid-cols-1 lg:grid-cols-3 gap-6">
|
<div class="max-w-6xl mx-auto p-6 grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||||
<!-- 뷰어 (2/3) -->
|
<!-- 뷰어 (2/3) -->
|
||||||
@@ -76,7 +87,7 @@
|
|||||||
<div class="text-center py-10">
|
<div class="text-center py-10">
|
||||||
<p class="text-[var(--text-dim)] mb-4">Synology Office 문서</p>
|
<p class="text-[var(--text-dim)] mb-4">Synology Office 문서</p>
|
||||||
<a
|
<a
|
||||||
href="https://ds1525.hyungi.net:15001/oo/r/{doc.id}"
|
href={doc.edit_url || 'https://link.hyungi.net'}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="px-4 py-2 bg-[var(--accent)] text-white rounded-lg hover:bg-[var(--accent-hover)]"
|
class="px-4 py-2 bg-[var(--accent)] text-white rounded-lg hover:bg-[var(--accent-hover)]"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user