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)
}