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.
79 lines
2.2 KiB
TypeScript
79 lines
2.2 KiB
TypeScript
// frontend/components/connectors/ConnectorCard.tsx — 라이프 연결 카드 (글래스, on/last/상태)
|
|
"use client";
|
|
import { type CSSProperties } from "react";
|
|
import { Icon } from "@/components/Icon";
|
|
import type { IconName } from "@/components/icons/paths";
|
|
import type { ConnectorStatus } from "@/lib/types";
|
|
import { ConnectStateBadge } from "./ConnectStateBadge";
|
|
import { ImportDropzone } from "./ImportDropzone";
|
|
|
|
// 도메인 → 대표 아이콘 (Icon 글리프 재사용)
|
|
const DOMAIN_ICON: Record<ConnectorStatus["domain"], IconName> = {
|
|
mail: "mail",
|
|
calendar: "cal",
|
|
chat: "msg",
|
|
finance: "wallet",
|
|
health: "heart",
|
|
knowledge: "brain",
|
|
};
|
|
|
|
export function ConnectorCard({
|
|
connector,
|
|
onSync,
|
|
onDisconnect,
|
|
onImport,
|
|
}: {
|
|
connector: ConnectorStatus;
|
|
onSync: (id: string) => void;
|
|
onDisconnect: (id: string) => void;
|
|
onImport: (file: File) => void;
|
|
}) {
|
|
const c = connector;
|
|
const syncing = c.state === "syncing";
|
|
|
|
return (
|
|
<div
|
|
className={"cn-card t-" + c.tone + (c.on ? "" : " off")}
|
|
style={{ ["--tone" as string]: `var(--${c.tone})` } as CSSProperties}
|
|
>
|
|
<div className="cn-top">
|
|
<div className="cn-ava" aria-hidden>
|
|
<Icon name={DOMAIN_ICON[c.domain]} />
|
|
</div>
|
|
<div className="cn-info">
|
|
<b className="cn-name">{c.name}</b>
|
|
<span className="cn-kind">{c.kind}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<ConnectStateBadge state={c.state} last={c.last} />
|
|
|
|
<div className="cn-actions">
|
|
{c.on ? (
|
|
<>
|
|
<button
|
|
type="button"
|
|
className="cn-btn"
|
|
disabled={syncing}
|
|
onClick={() => onSync(c.id)}
|
|
>
|
|
<Icon name="refresh" />
|
|
동기화
|
|
</button>
|
|
<button type="button" className="cn-btn cn-ghost" onClick={() => onDisconnect(c.id)}>
|
|
<Icon name="x" />
|
|
해제
|
|
</button>
|
|
</>
|
|
) : (
|
|
<button type="button" className="cn-btn" onClick={() => onSync(c.id)}>
|
|
<Icon name="link" />
|
|
연결
|
|
</button>
|
|
)}
|
|
<ImportDropzone onImport={onImport} />
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|