diff --git a/lps-admin/src/components/Layout.tsx b/lps-admin/src/components/Layout.tsx index 5f9e76d..9abc16a 100644 --- a/lps-admin/src/components/Layout.tsx +++ b/lps-admin/src/components/Layout.tsx @@ -25,10 +25,10 @@ export default function Layout() { L
LPS 관리자
-
인터넷 최저가 검색
+
인터넷 최저가 검색
-
+
{up ? "연결됨" : "연결 안 됨"}
@@ -52,7 +52,7 @@ export default function Layout() { ))} -
+
-
{label}
+
{label}
{value}
{sub &&
{sub}
}
@@ -57,17 +57,17 @@ export function StatusBadge({ status }: { status: JobStatusName }) { } export function Empty({ children }: { children: ReactNode }) { - return

{children}

; + return

{children}

; } export function ErrorNote({ error }: { error: unknown }) { return ( -

+

{error instanceof Error ? error.message : "요청에 실패했습니다"}

); } export function Loading() { - return

불러오는 중…

; + return

불러오는 중…

; } diff --git a/lps-admin/src/index.css b/lps-admin/src/index.css index fbdc5e1..8b45707 100644 --- a/lps-admin/src/index.css +++ b/lps-admin/src/index.css @@ -50,7 +50,7 @@ } body { - @apply bg-page text-ink-900 font-sans text-[13.5px] antialiased; + @apply bg-page text-ink-900 font-sans text-[14px] antialiased; } /* 테이블 숫자 열 정렬 */ @@ -61,5 +61,5 @@ body { /* recharts 기본 폰트 */ .recharts-wrapper, .recharts-tooltip-wrapper { - font-size: 11.5px; + font-size: 12px; } diff --git a/lps-admin/src/pages/Crawl.tsx b/lps-admin/src/pages/Crawl.tsx index 5abc7ca..597ce66 100644 --- a/lps-admin/src/pages/Crawl.tsx +++ b/lps-admin/src/pages/Crawl.tsx @@ -65,11 +65,11 @@ export default function Crawl() { {ip.data && ( blockCount === 0 ? ( -

+

✓ 기간 내 차단된 IP 세션 0건 — 요청 예산(선제 회전)이 잘 작동하고 있습니다

) : ( -

+

⚠ 예산 안에서도 차단된 세션 {blockCount}건 — 최소 {ip.data.block_min_requests}회 요청에서 차단됐습니다. 요청 예산을 그보다 낮게 유지하세요(현재 서버 설정은 toml [DecodoConfig].ip_request_budget)

@@ -212,7 +212,7 @@ export default function Crawl() { {s.ok_count}/{s.blocked_count} {durationSec(s.elapsed_sec)} - + {r.label} diff --git a/lps-admin/src/pages/Dashboard.tsx b/lps-admin/src/pages/Dashboard.tsx index 8b35694..09a6b74 100644 --- a/lps-admin/src/pages/Dashboard.tsx +++ b/lps-admin/src/pages/Dashboard.tsx @@ -50,12 +50,12 @@ export default function Dashboard() { {ops.isError && } {alerts.map((a) => (

+ className="rounded-lg border border-dead-600/20 bg-dead-50 px-3 py-2 text-[13px] font-semibold text-dead-600"> ⚠ {a.msg}

))} {d && alerts.length === 0 && ( -

+

✓ 모든 지표가 임계 안에 있습니다

)} diff --git a/lps-admin/src/pages/Jobs.tsx b/lps-admin/src/pages/Jobs.tsx index 3999e20..db3b48c 100644 --- a/lps-admin/src/pages/Jobs.tsx +++ b/lps-admin/src/pages/Jobs.tsx @@ -52,7 +52,7 @@ export default function Jobs() {
{ e.preventDefault(); setQ(qInput.trim()); setPage(0); }}> setQInput(e.target.value)} placeholder="상품코드·상품명 검색" - className="w-56 rounded-lg border border-line-200 bg-surface px-3 py-1.5 text-[12.5px] outline-none focus:border-primary-600" /> + className="w-56 rounded-lg border border-line-200 bg-surface px-3 py-1.5 text-[13px] outline-none focus:border-primary-600" />
@@ -64,7 +64,7 @@ export default function Jobs() { {list.data && list.data.items.length === 0 && 조건에 맞는 작업이 없습니다} {list.data && list.data.items.length > 0 && (
- +
@@ -87,7 +87,7 @@ export default function Jobs() { - + ))} @@ -128,8 +128,8 @@ function JobDetail({ job, onClose }: { job: JobListItem | null; onClose: () => v const out = detail.data?.output as Record | undefined; return ( 닫기}> -
- {job.job_id} +
+ {job.job_id} {job.product_name || "—"}{job.product_code && ({job.product_code})} 시도 {job.attempts}/{job.max_attempts} {job.last_error && {job.last_error}} @@ -146,7 +146,7 @@ function JobDetail({ job, onClose }: { job: JobListItem | null; onClose: () => v {job.status === "DEAD" && (
{requeue.isError &&

{(requeue.error as Error).message}

} @@ -156,8 +156,8 @@ function JobDetail({ job, onClose }: { job: JobListItem | null; onClose: () => v {out && (
- 원본 결과(JSON) -
{JSON.stringify(out, null, 2)}
+ 원본 결과(JSON) +
{JSON.stringify(out, null, 2)}
)} @@ -167,7 +167,7 @@ function JobDetail({ job, onClose }: { job: JobListItem | null; onClose: () => v function Row({ k, children }: { k: string; children: React.ReactNode }) { return (
-
{k}
+
{k}
{children}
); diff --git a/lps-admin/src/pages/Products.tsx b/lps-admin/src/pages/Products.tsx index 4022515..55491d3 100644 --- a/lps-admin/src/pages/Products.tsx +++ b/lps-admin/src/pages/Products.tsx @@ -33,7 +33,7 @@ export default function Products() {
{ e.preventDefault(); setQ(qInput.trim()); }}> setQInput(e.target.value)} placeholder="상품코드 검색" - className="w-64 rounded-lg border border-line-200 bg-surface px-3 py-1.5 text-[12.5px] outline-none focus:border-primary-600" /> + className="w-64 rounded-lg border border-line-200 bg-surface px-3 py-1.5 text-[13px] outline-none focus:border-primary-600" /> @@ -49,8 +49,8 @@ export default function Products() { }> @@ -160,7 +160,7 @@ function ProductDetail({ product }: { product: ProductItem | null }) { -
@@ -34,10 +34,10 @@ export default function Settings() { setApiKey(e.target.value)} placeholder="개발(개방 모드)은 비워둠 — prod 만 필요" autoComplete="off" - className="w-full rounded-lg border border-line-200 bg-surface px-3 py-2 text-[12.5px] outline-none focus:border-primary-600" /> + className="w-full rounded-lg border border-line-200 bg-surface px-3 py-2 text-[13px] outline-none focus:border-primary-600" />

서버 toml 의 [WebServerConfig].api_keys 중 하나. 이 브라우저에만 저장됩니다.

- {saved && 저장했습니다}
상품{j.outcome === "found" ? "찾음" : j.outcome === "not_found" ? "없음" : "—"} {won(j.final_lowest)} {usd(j.cost_usd)}{dateShort(j.created_at)}{dateShort(j.created_at)}