You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
// frontend/components/tasks/RiskRadar.tsx
|
|
"use client";
|
|
import { Icon } from "@/components/Icon";
|
|
import type { IconName } from "@/components/icons/paths";
|
|
import type { Risk } from "@/lib/types";
|
|
|
|
function Bolded({ text }: { text: string }) {
|
|
// "**A**B" → <b>A</b>B (정규식 split, dangerouslySetInnerHTML 미사용)
|
|
return (
|
|
<>
|
|
{text.split(/(\*\*[^*]+\*\*)/).map((s, i) =>
|
|
s.startsWith("**") ? <b key={i}>{s.slice(2, -2)}</b> : <span key={i}>{s}</span>,
|
|
)}
|
|
</>
|
|
);
|
|
}
|
|
|
|
export function RiskRadar({ risks, onOpen }: { risks: Risk[]; onOpen: (id: string) => void }) {
|
|
if (!risks.length) return null;
|
|
return (
|
|
<div className="rradar">
|
|
<div className="rr-head">
|
|
<span className="rr-ic">
|
|
<Icon name="radar" />
|
|
</span>
|
|
<div className="rr-ht">
|
|
<b>리스크 레이더</b>
|
|
<span>마감 · 업무량 · 의존성을 아리가 훑었어요</span>
|
|
</div>
|
|
</div>
|
|
<div className="rr-items">
|
|
{risks.map((r, i) => (
|
|
<div key={i} className={`rr-item t-${r.tone}`}>
|
|
<span className="rr-item-ic">
|
|
<Icon name={r.icon as IconName} />
|
|
</span>
|
|
<div className="rr-body">
|
|
<span className="rr-kind">{r.kind}</span>
|
|
<p className="rr-text">
|
|
<Bolded text={r.text} />
|
|
</p>
|
|
</div>
|
|
{r.task_id && r.cta && (
|
|
<button className="rr-cta" onClick={() => onOpen(r.task_id!)}>
|
|
{r.cta}
|
|
<Icon name="chev" />
|
|
</button>
|
|
)}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|