From b65781fd554c266c5277b1b798d9296159ecd13a Mon Sep 17 00:00:00 2001 From: chyoo Date: Fri, 7 Aug 2026 11:57:38 +0900 Subject: [PATCH] add instructor invite code.. --- src/pages/operations/OrganizationsPage.tsx | 1 + src/pages/operations/UserSessionsPage.tsx | 34 +++++++++++++++++++++- src/pages/operations/operations-api.ts | 9 ++++++ src/types/application.ts | 1 + 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/pages/operations/OrganizationsPage.tsx b/src/pages/operations/OrganizationsPage.tsx index 22149d1..f3694d1 100644 --- a/src/pages/operations/OrganizationsPage.tsx +++ b/src/pages/operations/OrganizationsPage.tsx @@ -136,6 +136,7 @@ export function OrganizationsPage() { }, { key: 'type', header: '유형', className: 'w-32 px-5 py-3', cell: (row) => }, { key: 'license', header: '라이센스', className: 'w-36 px-5 py-3', cell: (row) => row.defaultLicenseCode ? : - }, + { key: 'instructorInviteCode', header: '강사 가입 코드', className: 'w-40 px-5 py-3', cell: (row) => {row.instructorInviteCode} }, { key: 'domain', header: '도메인', className: 'w-56 px-5 py-3', cell: (row) => {row.domain || '-'} }, { key: 'createdAt', header: '생성', className: 'w-48 px-5 py-3', cell: (row) => }, { diff --git a/src/pages/operations/UserSessionsPage.tsx b/src/pages/operations/UserSessionsPage.tsx index c0d3571..4ecfaf4 100644 --- a/src/pages/operations/UserSessionsPage.tsx +++ b/src/pages/operations/UserSessionsPage.tsx @@ -13,6 +13,7 @@ import { lockUser, terminateUserSession, unlockUser, + updateLmsInstructor, type LicensePlan, type Organization, type UserSession @@ -45,6 +46,7 @@ export function UserSessionsPage() { const [createSaving, setCreateSaving] = useState(false); const [menuSession, setMenuSession] = useState<{ id: string; x: number; y: number } | null>(null); const [detailSession, setDetailSession] = useState(null); + const [lmsRoleSaving, setLmsRoleSaving] = useState(false); const loadingVisible = useMinimumLoading(loading); const refresh = () => { @@ -183,6 +185,24 @@ export function UserSessionsPage() { .finally(() => setCreateSaving(false)); }; + const setLmsInstructor = (isInstructor: boolean) => { + if (!detailSession) return; + + setLmsRoleSaving(true); + updateLmsInstructor(detailSession.userId, isInstructor) + .then(() => { + setDetailSession((current) => current ? { ...current, isLmsInstructor: isInstructor } : current); + setSessions((current) => current.map((session) => ( + session.userId === detailSession.userId ? { ...session, isLmsInstructor: isInstructor } : session + ))); + toast({ type: 'success', title: 'LMS 역할 변경', message: isInstructor ? '강사 권한을 부여했습니다.' : '강사 권한을 해제했습니다.' }); + }) + .catch((error: Error) => { + toast({ type: 'error', title: 'LMS 역할 변경 실패', message: error.message }); + }) + .finally(() => setLmsRoleSaving(false)); + }; + return ( <> -
+
+ diff --git a/src/pages/operations/operations-api.ts b/src/pages/operations/operations-api.ts index c3c2623..5300c01 100644 --- a/src/pages/operations/operations-api.ts +++ b/src/pages/operations/operations-api.ts @@ -70,6 +70,7 @@ export type UserSession = { expiresAt?: string | null; lastSeen?: string | null; state: string; + isLmsInstructor?: boolean; primaryAffiliation?: { id: string; organizationId: string; @@ -90,6 +91,7 @@ export type Organization = { domain?: string | null; defaultLicenseCode?: string | null; defaultLicenseName?: string | null; + instructorInviteCode: string; createdById?: string | null; createdByName?: string | null; createdByEmail?: string | null; @@ -257,6 +259,13 @@ export function unlockUser(userId: string) { }); } +export function updateLmsInstructor(userId: string, isInstructor: boolean) { + return apiRequest<{ userId: string; isInstructor: boolean }>(`/users/${userId}/lms-instructor`, { + method: 'PATCH', + body: JSON.stringify({ isInstructor }) + }); +} + export function terminateUserSession(sessionId: string) { return apiRequest(`/users/sessions/${sessionId}`, { method: 'DELETE' diff --git a/src/types/application.ts b/src/types/application.ts index 1d3f9a7..69a7e82 100644 --- a/src/types/application.ts +++ b/src/types/application.ts @@ -21,6 +21,7 @@ export type BuildJob = { branch: string; commitSha?: string | null; artifact?: string | null; + artifactSha256?: string | null; image?: string | null; status: JobStatus; logs?: string | null;