init studio admin frontend
This commit is contained in:
@@ -0,0 +1,271 @@
|
||||
import { apiRequest } from '../../lib/api';
|
||||
|
||||
export type AdminSession = {
|
||||
id?: string;
|
||||
revokedAt?: string | null;
|
||||
};
|
||||
|
||||
export type AdminSshKey = {
|
||||
id: string;
|
||||
label?: string | null;
|
||||
fingerprint?: string | null;
|
||||
};
|
||||
|
||||
export type AdminAccount = {
|
||||
id: string;
|
||||
email: string;
|
||||
name: string;
|
||||
role: 'OWNER' | 'ADMIN' | 'OPERATOR' | 'VIEWER' | string;
|
||||
isActive: boolean;
|
||||
lastLoginAt?: string | null;
|
||||
sessions?: AdminSession[];
|
||||
sshKeys?: AdminSshKey[];
|
||||
};
|
||||
|
||||
export type AdminRoleOption = {
|
||||
id: string;
|
||||
code: string;
|
||||
name: string;
|
||||
description?: string | null;
|
||||
sortOrder: number;
|
||||
isActive: boolean;
|
||||
};
|
||||
|
||||
export type UserSession = {
|
||||
id: string;
|
||||
no?: number;
|
||||
userId: string;
|
||||
sessionId?: string | null;
|
||||
user: string;
|
||||
email?: string;
|
||||
role: string;
|
||||
session: string;
|
||||
expiresAt?: string | null;
|
||||
lastSeen?: string | null;
|
||||
state: string;
|
||||
};
|
||||
|
||||
export type LauncherNotice = {
|
||||
id: string;
|
||||
no?: number;
|
||||
appKey: string;
|
||||
title: string;
|
||||
body: string;
|
||||
linkUrl?: string | null;
|
||||
isActive: boolean;
|
||||
startsAt?: string | null;
|
||||
endsAt?: string | null;
|
||||
priority: number;
|
||||
status?: string;
|
||||
createdAt: string;
|
||||
updatedAt?: string;
|
||||
};
|
||||
|
||||
export async function loadAdmins() {
|
||||
const response = await apiRequest<AdminAccount[] | { admins?: AdminAccount[] }>('/admins');
|
||||
return Array.isArray(response) ? response : response.admins ?? [];
|
||||
}
|
||||
|
||||
export function loadAdminRoles() {
|
||||
return apiRequest<AdminRoleOption[]>('/admins/roles');
|
||||
}
|
||||
|
||||
export function createAdmin(payload: {
|
||||
email: string;
|
||||
name: string;
|
||||
role: string;
|
||||
temporaryPassword?: string;
|
||||
}) {
|
||||
return apiRequest('/admins', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
}
|
||||
|
||||
export function updateAdminStatus(adminId: string, isActive: boolean) {
|
||||
return apiRequest(`/admins/${adminId}/status`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({ isActive })
|
||||
});
|
||||
}
|
||||
|
||||
export function updateAdminRole(adminId: string, role: string) {
|
||||
return apiRequest(`/admins/${adminId}/role`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({ role })
|
||||
});
|
||||
}
|
||||
|
||||
export function resetAdminPassword(adminId: string, temporaryPassword: string) {
|
||||
return apiRequest(`/admins/${adminId}/password`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({ temporaryPassword })
|
||||
});
|
||||
}
|
||||
|
||||
export function createAdminSshKey(
|
||||
adminId: string,
|
||||
payload: { label?: string; giteaUsername?: string; publicKey: string }
|
||||
) {
|
||||
return apiRequest(`/admins/${adminId}/ssh-keys`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteAdminSshKey(adminId: string, keyId: string) {
|
||||
return apiRequest(`/admins/${adminId}/ssh-keys/${keyId}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
}
|
||||
|
||||
export async function loadUserSessions() {
|
||||
const response = await apiRequest<{ sessions?: UserSession[] }>('/users/sessions');
|
||||
return response.sessions ?? [];
|
||||
}
|
||||
|
||||
export function lockUser(userId: string) {
|
||||
return apiRequest(`/users/${userId}/lock`, {
|
||||
method: 'PATCH'
|
||||
});
|
||||
}
|
||||
|
||||
export function unlockUser(userId: string) {
|
||||
return apiRequest(`/users/${userId}/unlock`, {
|
||||
method: 'PATCH'
|
||||
});
|
||||
}
|
||||
|
||||
export function terminateUserSession(sessionId: string) {
|
||||
return apiRequest(`/users/sessions/${sessionId}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
}
|
||||
|
||||
export async function loadLauncherNotices() {
|
||||
const response = await apiRequest<{ notices?: LauncherNotice[] }>('/notices');
|
||||
return response.notices ?? [];
|
||||
}
|
||||
|
||||
export function createLauncherNotice(payload: {
|
||||
appKey: string;
|
||||
title: string;
|
||||
body: string;
|
||||
linkUrl?: string;
|
||||
isActive?: boolean;
|
||||
startsAt?: string;
|
||||
endsAt?: string;
|
||||
priority?: number;
|
||||
}) {
|
||||
return apiRequest<{ notice: LauncherNotice }>('/notices', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
}
|
||||
|
||||
export function updateLauncherNotice(
|
||||
noticeId: string,
|
||||
payload: Partial<{
|
||||
appKey: string;
|
||||
title: string;
|
||||
body: string;
|
||||
linkUrl: string;
|
||||
isActive: boolean;
|
||||
startsAt: string;
|
||||
endsAt: string;
|
||||
priority: number;
|
||||
}>
|
||||
) {
|
||||
return apiRequest<{ notice: LauncherNotice }>(`/notices/${noticeId}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteLauncherNotice(noticeId: string) {
|
||||
return apiRequest<{ ok: boolean }>(`/notices/${noticeId}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
}
|
||||
|
||||
export type LicensePlan = {
|
||||
id: string;
|
||||
code: string;
|
||||
name: string;
|
||||
description?: string | null;
|
||||
defaultDurationDays?: number | null;
|
||||
isActive: boolean;
|
||||
assignedCount: number;
|
||||
activeUserCount: number;
|
||||
expiringSoonCount: number;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
};
|
||||
|
||||
export type AuthUserLicense = {
|
||||
id: string;
|
||||
userId: string;
|
||||
licenseId: string;
|
||||
startsAt: string;
|
||||
expiresAt?: string | null;
|
||||
assignedById?: string | null;
|
||||
license: {
|
||||
id: string;
|
||||
code: string;
|
||||
name: string;
|
||||
description?: string | null;
|
||||
};
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type AuthLicenseUser = {
|
||||
id: string;
|
||||
email: string;
|
||||
name: string;
|
||||
role: string;
|
||||
isActive: boolean;
|
||||
currentLicense?: AuthUserLicense | null;
|
||||
licenses: AuthUserLicense[];
|
||||
};
|
||||
|
||||
export async function loadLicensePlans() {
|
||||
const response = await apiRequest<{ plans?: LicensePlan[] }>('/licenses/plans');
|
||||
return response.plans ?? [];
|
||||
}
|
||||
|
||||
export async function loadLicenseUsers(params?: { keyword?: string; licenseCode?: string }) {
|
||||
const searchParams = new URLSearchParams();
|
||||
if (params?.keyword) searchParams.set('keyword', params.keyword);
|
||||
if (params?.licenseCode) searchParams.set('licenseCode', params.licenseCode);
|
||||
const suffix = searchParams.toString() ? `?${searchParams.toString()}` : '';
|
||||
const response = await apiRequest<{ users?: AuthLicenseUser[] }>(`/licenses/users${suffix}`);
|
||||
return response.users ?? [];
|
||||
}
|
||||
|
||||
export function assignUserLicense(userId: string, payload: {
|
||||
licenseCode: string;
|
||||
startsAt?: string;
|
||||
expiresAt?: string;
|
||||
}) {
|
||||
return apiRequest<{ userLicense: AuthUserLicense }>(`/licenses/users/${userId}`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
}
|
||||
|
||||
export function updateUserLicense(userLicenseId: string, payload: {
|
||||
licenseCode: string;
|
||||
startsAt?: string;
|
||||
expiresAt?: string;
|
||||
}) {
|
||||
return apiRequest<{ userLicense: AuthUserLicense }>(`/licenses/user-licenses/${userLicenseId}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
}
|
||||
|
||||
export function revokeUserLicense(userLicenseId: string) {
|
||||
return apiRequest<{ ok: boolean }>(`/licenses/user-licenses/${userLicenseId}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user