Files
yakcloud-packages/packages/client-shell/src/context/ServiceClientContext.tsx
jungwoo choi 362e3168a7 feat(auth-adapter,bff-kit,client-shell): 마지막 추출 배치
@yakcloud/auth-adapter: core 인터페이스(프레임워크 무관, ds-sdk type-only)
  + dev-bypass + next-auth 격리 계층(peer). exports 서브패스(./core·./dev-bypass).
@yakcloud/bff-kit: respond(web 표준)·serialize(Prisma-free)·ratelimit·session(AuthAdapter DI).
  auth-adapter=devDependency(type-only), 죽은 next peer 제거.
@yakcloud/client-shell: ServiceClientShell 셸 크롬(헤더/탭/pane/가드)+패널 슬롯+BackupPanel 스텁.
  (FileBrowser 는 Phase 1)

FIX-FIRST 반영: client-shell tsconfig jsx:react-jsx + @types/react(-dom),
  bff-kit/auth-adapter += @types/node. 7개 패키지 전부 tsc --noEmit 통과.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-25 13:12:34 +09:00

61 lines
1.9 KiB
TypeScript

"use client";
// @yakcloud/client-shell — 서비스 클라이언트 셸 컨텍스트.
// 서비스 메타(id/type/cluster/status) + 탭 상태(activeTab) + 패널 시트 컨트롤(usePanelSheets) 공유.
// ⛔ DOM 가정 금지(main.main querySelector 폴백 없음) — scrollContainer 는 명시 주입만.
// ds-sdk 는 type-only, ui(usePanelSheets)는 런타임 소비.
import { createContext, useContext } from "react";
import type { ReactNode } from "react";
import { usePanelSheets } from "@yakcloud/ui";
import type { PanelSheetsCtl } from "@yakcloud/ui";
import type { ServiceStatusDTO, ServiceTypeDTO } from "@yakcloud/ds-sdk";
import type { LoadingGuardState } from "../hooks/useServiceClient";
export interface ServiceClientContextValue {
// 서비스 메타
serviceId: string;
name: string;
sourceType: ServiceTypeDTO;
clusterId: string;
clusterName: string;
status: ServiceStatusDTO | undefined;
guardState: LoadingGuardState;
// 탭 상태
activeTab: string;
setActiveTab: (tab: string) => void;
tabs: readonly string[];
// 패널 시트 컨트롤(헤더↔본문 슬라이드 시트)
sheets: PanelSheetsCtl;
// 스크롤 잠금 대상 컨테이너(선택) — 시트 열림 동안 잠금. 미지정 시 no-op.
scrollContainer: HTMLElement | null;
// 로고 URL 조합 베이스(getServiceMeta logoBase).
logoBase: string;
}
const Ctx = createContext<ServiceClientContextValue | null>(null);
export function ServiceClientProvider({
value,
children,
}: {
value: Omit<ServiceClientContextValue, "sheets">;
children: ReactNode;
}) {
const sheets = usePanelSheets();
return <Ctx.Provider value={{ ...value, sheets }}>{children}</Ctx.Provider>;
}
export function useServiceClientContext(): ServiceClientContextValue {
const v = useContext(Ctx);
if (!v) {
throw new Error(
"useServiceClientContext must be used within <ServiceClientProvider> (ServiceClientShell).",
);
}
return v;
}