Files
UniVerse/frontend/src/api/index.ts
T
serega404 a8d51df3f1
Backend CI / build-and-test (push) Successful in 40s
Frontend CI / build-and-check (push) Failing after 19s
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 6s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 24s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Successful in 27s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 5s
feat: добавил эндпоинт для получения статистики админского дашборда
2026-05-30 01:23:57 +03:00

229 lines
7.1 KiB
TypeScript

import { apiRequest, extractItems } from './client'
import type {
AchievementDto,
AuthResponse,
CoinTransactionDto,
CourseDto,
CreateLectureRequest,
LectureDto,
LectureQuery,
LocationDto,
PagedResult,
ReviewDto,
ReviewQuery,
ReviewPromptDto,
SyncResultDto,
SyncScheduleRequest,
SyncStatusDto,
TagDto,
UpdateReviewPromptRequest,
UserAchievementDto,
AdminDashboardStatsDto,
CurrentUserDto,
UserDto,
UserQuery,
UserNotificationDto,
UserStatsDto,
} from './types'
export const authApi = {
loginMicrosoft: (authorizationCode: string, redirectUri?: string) =>
apiRequest<AuthResponse>('/auth/login/microsoft', {
method: 'POST',
body: JSON.stringify({ authorizationCode, redirectUri }),
}),
refresh: () => apiRequest<AuthResponse>('/auth/refresh', { method: 'POST' }),
logout: () => apiRequest<void>('/auth/logout', { method: 'POST' }),
me: () => apiRequest<CurrentUserDto>('/auth/me'),
}
export const lecturesApi = {
async list(query: LectureQuery = {}) {
const payload = await apiRequest<PagedResult<LectureDto> | LectureDto[]>('/lectures', {
query: query as Record<string, unknown>,
})
return extractItems(payload)
},
get: (id: string | number) => apiRequest<LectureDto>(`/lectures/${id}`),
create: (payload: CreateLectureRequest) =>
apiRequest<LectureDto>('/lectures', {
method: 'POST',
body: JSON.stringify(payload),
}),
enroll: (id: string | number) => apiRequest<void>(`/lectures/${id}/enroll`, { method: 'POST' }),
unenroll: (id: string | number) =>
apiRequest<void>(`/lectures/${id}/enroll`, { method: 'DELETE' }),
async reviews(id: string | number) {
const payload = await apiRequest<PagedResult<ReviewDto> | ReviewDto[]>(
`/lectures/${id}/reviews`,
)
return extractItems(payload)
},
}
export const usersApi = {
me: () => apiRequest<CurrentUserDto>('/users/me'),
updateMe: (payload: { displayName?: string | null; avatarUrl?: string | null }) =>
apiRequest<CurrentUserDto>('/users/me', {
method: 'PUT',
body: JSON.stringify(payload),
}),
myStats: () => apiRequest<UserStatsDto>('/users/me/stats'),
adminStats: () => apiRequest<AdminDashboardStatsDto>('/users/admin/stats'),
async myEnrollments() {
const payload = await apiRequest<PagedResult<LectureDto> | LectureDto[] | undefined>(
'/users/me/enrollments',
)
return extractItems(payload)
},
async myAchievements() {
const payload = await apiRequest<
PagedResult<UserAchievementDto> | UserAchievementDto[] | AchievementDto[]
>('/users/me/achievements')
if (Array.isArray(payload)) return payload
return payload.items ?? []
},
async myTransactions() {
const payload = await apiRequest<PagedResult<CoinTransactionDto> | CoinTransactionDto[]>(
'/users/me/transactions',
)
return extractItems(payload)
},
get: (id: string | number) => apiRequest<UserDto>(`/users/${id}`),
async list(query: UserQuery = {}) {
const payload = await apiRequest<PagedResult<UserDto> | UserDto[]>('/users', {
query: query as Record<string, unknown>,
})
return extractItems(payload)
},
stats: (id: string | number) => apiRequest<UserStatsDto>(`/users/${id}/stats`),
async enrollments(id: string | number) {
const payload = await apiRequest<PagedResult<LectureDto> | LectureDto[] | undefined>(
`/users/${id}/enrollments`,
)
return extractItems(payload)
},
async achievements(id: string | number) {
const payload = await apiRequest<
PagedResult<UserAchievementDto> | UserAchievementDto[] | AchievementDto[]
>(`/users/${id}/achievements`)
if (Array.isArray(payload)) return payload
return payload.items ?? []
},
async transactions(id: string | number) {
const payload = await apiRequest<PagedResult<CoinTransactionDto> | CoinTransactionDto[]>(
`/users/${id}/transactions`,
)
return extractItems(payload)
},
setRole: (id: string | number, roles: Array<'Student' | 'Teacher' | 'Admin'>) =>
apiRequest<void>(`/users/${id}/role`, {
method: 'PATCH',
body: JSON.stringify(roles),
}),
setActive: (id: string | number, isActive: boolean) =>
apiRequest<void>(`/users/${id}/active`, {
method: 'PATCH',
body: JSON.stringify(isActive),
}),
}
export const achievementsApi = {
async list() {
const payload = await apiRequest<PagedResult<AchievementDto> | AchievementDto[]>(
'/achievements',
)
return extractItems(payload)
},
}
export const notificationsApi = {
async list() {
const payload = await apiRequest<PagedResult<UserNotificationDto> | UserNotificationDto[]>(
'/notifications',
)
return extractItems(payload)
},
markAllRead: () => apiRequest<void>('/notifications/read-all', { method: 'PATCH' }),
}
function normalizePagedResult<T>(
payload: PagedResult<T> | T[] | undefined,
query: { Page?: number; PageSize?: number } = {},
): PagedResult<T> {
if (!Array.isArray(payload) && payload) return payload
const items = payload ?? []
const page = query.Page ?? 1
const pageSize = query.PageSize ?? items.length
const totalPages = pageSize > 0 ? Math.ceil(items.length / pageSize) : 0
return {
items,
totalCount: items.length,
page,
pageSize,
totalPages,
}
}
async function listReviewsPage(query: ReviewQuery = {}) {
const payload = await apiRequest<PagedResult<ReviewDto> | ReviewDto[]>('/reviews', {
query: query as Record<string, unknown>,
})
return normalizePagedResult(payload, query)
}
export const reviewsApi = {
create: (lectureId: string | number, rating: 'Like' | 'Neutral' | 'Dislike', text: string) =>
apiRequest<ReviewDto>('/reviews', {
method: 'POST',
body: JSON.stringify({ lectureId: Number(lectureId), rating, text }),
}),
getPrompt: () => apiRequest<ReviewPromptDto>('/reviews/llm-prompt'),
updatePrompt: (payload: UpdateReviewPromptRequest) =>
apiRequest<ReviewPromptDto>('/reviews/llm-prompt', {
method: 'PUT',
body: JSON.stringify(payload),
}),
listPage: listReviewsPage,
async list(query: ReviewQuery = { PageSize: 100 }) {
return (await listReviewsPage(query)).items
},
reanalyze: (id: string | number) =>
apiRequest<void>(`/reviews/${id}/reanalyze`, { method: 'POST' }),
}
export const coursesApi = {
async list() {
const payload = await apiRequest<PagedResult<CourseDto> | CourseDto[]>('/courses', {
query: { PageSize: 100 },
})
return extractItems(payload)
},
}
export const locationsApi = {
async list() {
const payload = await apiRequest<PagedResult<LocationDto> | LocationDto[]>('/locations')
return extractItems(payload)
},
}
export const tagsApi = {
async list() {
const payload = await apiRequest<PagedResult<TagDto> | TagDto[]>('/tags')
return extractItems(payload)
},
}
export const syncApi = {
status: () => apiRequest<SyncStatusDto>('/sync/status'),
schedule: (request: SyncScheduleRequest) =>
apiRequest<SyncResultDto>('/sync/schedule', {
method: 'POST',
body: JSON.stringify(request),
}),
rooms: () => apiRequest<SyncResultDto>('/sync/rooms', { method: 'POST' }),
}