feat(targets): wrap PriceTargets in Collapsible
사이드바 5번째(이자 마지막 정보성) 패널인 PriceTargets 도 공용 Collapsible 로 통일. SymbolSidebar(상단 종목 카드 — 자체 톤 유지가 맞음) 만 남기고 나머지 사이드 패널 5개(Orderbook / Targets / Alerts / Note / Related)가 모두 같은 토글/영속 패턴. subtitle 설계 — 접힌 상태에서도 저장값 한눈에: - 둘 다 저장됨: "목표 12,500 · 손절 9,800" - 한쪽만: "목표 12,500" / "손절 9,800" - 둘 다 없음: "비공개 · 브라우저 저장" (InvestmentNote 와 동일 톤) - dirty 입력값이 아닌 saved 기준만 표시 — 토글 사이클 사이에 안내가 깜빡이지 않게. storageKey="targets" → panel-open:targets 영속. defaultOpen=true — 입력값은 Collapsible 의 hidden 본문 덕에 토글에도 보존되지만, 처음 보는 사용자에겐 input 이 펴져 있어야 "여기서 적는다" 가 자명. 입력 흐름 우선. 기존 rounded-lg 는 Collapsible 기본 rounded-md 로 흡수 — 다른 사이드 패널과 모서리 톤 통일. 검증: - npx tsc --noEmit clean - npx next lint "✔ No ESLint warnings or errors"
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { readTargets, writeTargets, type Targets } from "../lib/targets";
|
||||
import { Collapsible } from "./Collapsible";
|
||||
|
||||
type Props = {
|
||||
code: string;
|
||||
@@ -69,12 +70,24 @@ export function PriceTargets({ code, current, onChange }: Props) {
|
||||
const pctCls = (p: number | null): string =>
|
||||
p == null ? "text-zinc-500" : p >= 0 ? "text-rose-400" : "text-sky-400";
|
||||
|
||||
// 접힌 상태에서도 유저가 어떤 값을 저장해뒀는지 한눈에 — 둘 다 없으면 InvestmentNote 와
|
||||
// 같은 톤의 "비공개 · 브라우저 저장" 안내. 저장값(savedN)이 아닌 dirty 입력값을 보여주면
|
||||
// 토글 사이클 사이에 안내가 깜빡여 혼란. saved 기준만 표시.
|
||||
const fmtNum = (n: number): string =>
|
||||
n.toLocaleString(undefined, { maximumFractionDigits: 0 });
|
||||
const subtitle =
|
||||
saved.target != null && saved.stop != null
|
||||
? `목표 ${fmtNum(saved.target)} · 손절 ${fmtNum(saved.stop)}`
|
||||
: saved.target != null
|
||||
? `목표 ${fmtNum(saved.target)}`
|
||||
: saved.stop != null
|
||||
? `손절 ${fmtNum(saved.stop)}`
|
||||
: "비공개 · 브라우저 저장";
|
||||
|
||||
return (
|
||||
<div className="rounded-lg border border-zinc-800 bg-zinc-900/40 p-3">
|
||||
<div className="mb-2 flex items-baseline justify-between">
|
||||
<h3 className="text-xs font-semibold text-zinc-300">내 목표가</h3>
|
||||
<span className="text-[10px] text-zinc-500">브라우저 저장 · 비공개</span>
|
||||
</div>
|
||||
// defaultOpen=true — 입력 중인 텍스트는 Collapsible 의 hidden 본문 덕에 토글로 사라지지
|
||||
// 않지만, 처음 보는 사용자에겐 input 이 펴져 있어야 "여기서 목표가를 적는다" 가 자명.
|
||||
<Collapsible title="내 목표가" subtitle={subtitle} storageKey="targets">
|
||||
<div className="space-y-2">
|
||||
<Row
|
||||
label="목표가"
|
||||
@@ -114,7 +127,7 @@ export function PriceTargets({ code, current, onChange }: Props) {
|
||||
{current == null && (
|
||||
<div className="mt-1 text-[10px] text-zinc-500">현재가 로딩 중 — 변동률은 잠시 후 표시</div>
|
||||
)}
|
||||
</div>
|
||||
</Collapsible>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user