278 lines
8.6 KiB
TypeScript
278 lines
8.6 KiB
TypeScript
import { apiDelete, apiGet, apiPost, apiPut } from './http'
|
|
import type {
|
|
ImportJob,
|
|
DashboardData,
|
|
PageData,
|
|
Paper,
|
|
Permission,
|
|
Question,
|
|
QuestionBank,
|
|
ReportBankDetail,
|
|
ReportDimension,
|
|
ReportFilters,
|
|
ReportInsights,
|
|
ReportMastery,
|
|
ReportOptions,
|
|
ReportOverview,
|
|
ReportQuestionError,
|
|
ReportStudent,
|
|
ReportStudentDetail,
|
|
ReportTrend,
|
|
SchoolClass,
|
|
TaxonomyItem,
|
|
User,
|
|
} from '@/types/api'
|
|
|
|
export function fetchDashboard() {
|
|
return apiGet<DashboardData>('/api/admin/dashboard')
|
|
}
|
|
|
|
export function fetchBanks(params?: Record<string, unknown>) {
|
|
return apiGet<PageData<QuestionBank>>('/api/admin/banks', params)
|
|
}
|
|
|
|
export function createBank(payload: Partial<QuestionBank>) {
|
|
return apiPost<QuestionBank>('/api/admin/banks', payload)
|
|
}
|
|
|
|
export function updateBank(bankId: number, payload: Partial<QuestionBank>) {
|
|
return apiPut<QuestionBank>(`/api/admin/banks/${bankId}`, payload)
|
|
}
|
|
|
|
export function deleteBank(bankId: number) {
|
|
return apiDelete<null>(`/api/admin/banks/${bankId}`)
|
|
}
|
|
|
|
export function shareBank(bankId: number, targets: Array<{ type: 'user' | 'class'; id: number }>) {
|
|
return apiPost<null>(`/api/admin/banks/${bankId}/shares`, { targets })
|
|
}
|
|
|
|
export function fetchQuestions(params?: Record<string, unknown>) {
|
|
return apiGet<PageData<Question>>('/api/admin/questions', params)
|
|
}
|
|
|
|
export function createQuestion(payload: Record<string, unknown>) {
|
|
return apiPost('/api/admin/questions', payload)
|
|
}
|
|
|
|
export function updateQuestion(questionId: number, payload: Partial<Question>) {
|
|
return apiPut<Question>(`/api/admin/questions/${questionId}`, payload)
|
|
}
|
|
|
|
export function deleteQuestion(questionId: number) {
|
|
return apiDelete<null>(`/api/admin/questions/${questionId}`)
|
|
}
|
|
|
|
export function importQuestions(bankId: number, file: File) {
|
|
const form = new FormData()
|
|
form.append('file', file)
|
|
return apiPost<ImportJob>(`/api/admin/banks/${bankId}/imports`, form)
|
|
}
|
|
|
|
export function validateQuestionImport(bankId: number, file: File) {
|
|
const form = new FormData()
|
|
form.append('file', file)
|
|
return apiPost<{
|
|
valid: boolean
|
|
rows: Array<Record<string, unknown>>
|
|
errors: Array<{ row: number; message: string }>
|
|
duplicates: Array<{ row: number; message: string; content: string; type: string }>
|
|
importable_count: number
|
|
type: string
|
|
file_path: string
|
|
}>(`/api/admin/banks/${bankId}/imports/validate`, form)
|
|
}
|
|
|
|
export function importQuestionRows(bankId: number, payload: {
|
|
rows: Array<Record<string, unknown>>
|
|
type?: string
|
|
file_path?: string
|
|
}) {
|
|
return apiPost<ImportJob>(`/api/admin/banks/${bankId}/imports/rows`, payload)
|
|
}
|
|
|
|
export function validateQuestionRows(bankId: number, payload: {
|
|
rows: Array<Record<string, unknown>>
|
|
}) {
|
|
return apiPost<{
|
|
valid: boolean
|
|
rows: Array<Record<string, unknown>>
|
|
errors: Array<{ row: number; message: string }>
|
|
duplicates: Array<{ row: number; message: string; content: string; type: string }>
|
|
importable_count: number
|
|
}>(`/api/admin/banks/${bankId}/imports/rows/validate`, payload)
|
|
}
|
|
|
|
export function exportBank(bankId: number) {
|
|
return apiPost(`/api/admin/banks/${bankId}/export`)
|
|
}
|
|
|
|
export function fetchCategories(bankId: number) {
|
|
return apiGet<TaxonomyItem[]>(`/api/admin/banks/${bankId}/categories`)
|
|
}
|
|
|
|
export function createCategory(bankId: number, payload: { name: string; parent_id?: number; sort?: number }) {
|
|
return apiPost(`/api/admin/banks/${bankId}/categories`, payload)
|
|
}
|
|
|
|
export function fetchTags(bankId: number) {
|
|
return apiGet<TaxonomyItem[]>(`/api/admin/banks/${bankId}/tags`)
|
|
}
|
|
|
|
export function createTag(bankId: number, payload: { name: string }) {
|
|
return apiPost(`/api/admin/banks/${bankId}/tags`, payload)
|
|
}
|
|
|
|
export function fetchUsers(params?: Record<string, unknown>) {
|
|
return apiGet<PageData<User>>('/api/admin/users', params)
|
|
}
|
|
|
|
export function fetchClasses(params?: Record<string, unknown>) {
|
|
return apiGet<PageData<SchoolClass>>('/api/admin/classes', params)
|
|
}
|
|
|
|
export function createClass(payload: { name: string; description?: string }) {
|
|
return apiPost<SchoolClass>('/api/admin/classes', payload)
|
|
}
|
|
|
|
export function updateClass(classId: number, payload: { name?: string; description?: string; is_active?: boolean }) {
|
|
return apiPut<SchoolClass>(`/api/admin/classes/${classId}`, payload)
|
|
}
|
|
|
|
export function addClassMember(classId: number, payload: { user_id: number; role?: string }) {
|
|
return apiPost<SchoolClass>(`/api/admin/classes/${classId}/members`, payload)
|
|
}
|
|
|
|
export function addClassMembers(classId: number, payload: { user_ids: number[]; role?: string }) {
|
|
return apiPost<SchoolClass>(`/api/admin/classes/${classId}/members/batch`, payload)
|
|
}
|
|
|
|
export function fetchPapers(params?: Record<string, unknown>) {
|
|
return apiGet<PageData<Paper>>('/api/admin/papers', params)
|
|
}
|
|
|
|
export function fetchPaper(paperId: number) {
|
|
return apiGet<Paper>(`/api/admin/papers/${paperId}`)
|
|
}
|
|
|
|
export function createPaper(payload: {
|
|
title: string
|
|
description?: string
|
|
question_bank_id?: number
|
|
duration_minutes?: number
|
|
attempt_limit?: number
|
|
is_active?: boolean
|
|
questions?: Array<{ id: number; score?: number }>
|
|
}) {
|
|
return apiPost<Paper>('/api/admin/papers', payload)
|
|
}
|
|
|
|
export function updatePaper(paperId: number, payload: {
|
|
title?: string
|
|
description?: string
|
|
question_bank_id?: number
|
|
duration_minutes?: number
|
|
attempt_limit?: number
|
|
is_active?: boolean
|
|
questions?: Array<{ id: number; score?: number }>
|
|
}) {
|
|
return apiPut<Paper>(`/api/admin/papers/${paperId}`, payload)
|
|
}
|
|
|
|
export function deletePaper(paperId: number) {
|
|
return apiDelete<null>(`/api/admin/papers/${paperId}`)
|
|
}
|
|
|
|
export function createUser(payload: { name: string; email: string; password: string; role: string }) {
|
|
return apiPost<User>('/api/admin/users', payload)
|
|
}
|
|
|
|
export function updateUser(userId: number, payload: {
|
|
name?: string
|
|
email?: string
|
|
role?: string
|
|
is_active?: boolean
|
|
password?: string
|
|
}) {
|
|
return apiPut<User>(`/api/admin/users/${userId}`, payload)
|
|
}
|
|
|
|
export function fetchInvites(params?: Record<string, unknown>) {
|
|
return apiGet<PageData<Record<string, unknown>>>('/api/admin/invite-codes', params)
|
|
}
|
|
|
|
export function createInvite(payload: { role: string; assigned_name?: string; max_uses: number; expires_at?: string }) {
|
|
return apiPost('/api/admin/invite-codes', payload)
|
|
}
|
|
|
|
export function deleteInvite(inviteId: number) {
|
|
return apiDelete<null>(`/api/admin/invite-codes/${inviteId}`)
|
|
}
|
|
|
|
export function fetchPermissions() {
|
|
return apiGet<{
|
|
permissions: Permission[]
|
|
role_permissions: Record<string, number[]>
|
|
}>('/api/admin/permissions')
|
|
}
|
|
|
|
export function syncRolePermissions(role: string, permissionIds: number[]) {
|
|
return apiPut(`/api/admin/roles/${role}/permissions`, { permission_ids: permissionIds })
|
|
}
|
|
|
|
export function fetchSettings() {
|
|
return apiGet<Array<{ key: string; value: unknown; group: string }>>('/api/admin/settings')
|
|
}
|
|
|
|
export function saveSettings(settings: Record<string, unknown>) {
|
|
return apiPut('/api/admin/settings', { settings })
|
|
}
|
|
|
|
export function fetchReportOptions(params?: ReportFilters) {
|
|
return apiGet<ReportOptions>('/api/admin/reports/options', params)
|
|
}
|
|
|
|
export function fetchReportOverview(params?: ReportFilters) {
|
|
return apiGet<ReportOverview>('/api/admin/reports/overview', params)
|
|
}
|
|
|
|
export function fetchReportTrends(params?: ReportFilters) {
|
|
return apiGet<ReportTrend[]>('/api/admin/reports/trends', params)
|
|
}
|
|
|
|
export function fetchQuestionErrors(params?: ReportFilters) {
|
|
return apiGet<PageData<ReportQuestionError>>('/api/admin/reports/question-errors', params)
|
|
}
|
|
|
|
export function fetchClassRanking(params?: ReportFilters) {
|
|
return apiGet<Array<ReportDimension & { members_count: number; attempts: number; completion_rate: number }>>('/api/admin/reports/class-ranking', params)
|
|
}
|
|
|
|
export function fetchMastery(params?: ReportFilters) {
|
|
return apiGet<ReportMastery>('/api/admin/reports/mastery', params)
|
|
}
|
|
|
|
export function fetchReportStudents(params?: ReportFilters) {
|
|
return apiGet<PageData<ReportStudent>>('/api/admin/reports/students', params)
|
|
}
|
|
|
|
export function fetchReportStudentDetail(userId: number, params?: ReportFilters) {
|
|
return apiGet<ReportStudentDetail>(`/api/admin/reports/students/${userId}`, params)
|
|
}
|
|
|
|
export function fetchReportBankDetail(bankId: number, params?: ReportFilters) {
|
|
return apiGet<ReportBankDetail>(`/api/admin/reports/banks/${bankId}`, params)
|
|
}
|
|
|
|
export function fetchReportInsights(params?: ReportFilters) {
|
|
return apiGet<ReportInsights>('/api/admin/reports/insights', params)
|
|
}
|
|
|
|
export function exportReport(params?: ReportFilters) {
|
|
return apiPost('/api/admin/reports/export', params)
|
|
}
|
|
|
|
export function fetchLogs(params?: Record<string, unknown>) {
|
|
return apiGet<PageData<Record<string, unknown>>>('/api/admin/logs', params)
|
|
}
|