import { useId } from "react"; import { errorMessage } from "./error-copy.js"; import { Button } from "./ui/button.jsx"; /** @param {{ label?: string }} props */ export function LoadingSurface({ label = "불러오는 중" }) { return ( {label} ); } /** * @param {{ * title?: string, * description?: string, * action?: React.ReactNode * }} props */ export function EmptySurface({ title = "표시할 항목이 없습니다.", description, action, }) { return ( {title} {description ? {description} : null} {action} ); } /** * @param {{ * userMessageKey: string, * action: "retry" | "reauth" | "navigate" | "reload-once" | * "contact-support" | "none", * onAction?: () => void * }} props */ export function TerminalErrorSurface({ userMessageKey, action, onAction }) { const messageId = useId(); const actionLabels = Object.freeze({ retry: "다시 시도", reauth: "로그인", navigate: "안전한 화면으로 이동", "reload-once": "한 번 새로고침", "contact-support": "지원 정보 확인", }); return ( {errorMessage(userMessageKey)} {action !== "none" && onAction && ( {actionLabels[action]} )} ); } /** * @param {{ * state: ReturnType, * children?: React.ReactNode, * onAction?: () => void, * onRetry?: () => void, * onResolveConflict?: () => void * }} props */ export function AsyncSurface({ state, children, onAction, onRetry, onResolveConflict, }) { if (state.base === "initial-loading") return ; if (state.base === "empty") return ; if (state.base === "terminal-error" && state.failure) { return ( ); } return ( {state.indicator ? ( {state.indicator} {state.indicator === "stale-degraded" && onRetry ? ( 다시 시도 ) : null} {state.indicator === "mutation-conflict" && onResolveConflict ? ( 충돌 해결 ) : null} ) : null} {children} ); }
{description}