934682f035
Frontend CI / build-and-check (push) Failing after 5m10s
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 15s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 18s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Successful in 32s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 13s
203 lines
6.1 KiB
TypeScript
203 lines
6.1 KiB
TypeScript
import { apiRequest, extractItems } from './client'
|
|
import type {
|
|
AchievementDto,
|
|
AuthResponse,
|
|
CoinTransactionDto,
|
|
CourseDto,
|
|
CreateLectureRequest,
|
|
LectureDto,
|
|
LectureQuery,
|
|
LocationDto,
|
|
PagedResult,
|
|
ReviewDto,
|
|
ReviewQuery,
|
|
SyncResultDto,
|
|
SyncScheduleRequest,
|
|
SyncStatusDto,
|
|
TagDto,
|
|
UserAchievementDto,
|
|
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<UserDto>('/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 = {
|
|
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)
|
|
}
|
|
|
|
async function listPendingReviewsPage(query: ReviewQuery = {}) {
|
|
const payload = await apiRequest<PagedResult<ReviewDto> | ReviewDto[]>('/reviews/pending', {
|
|
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 }),
|
|
}),
|
|
listPage: listReviewsPage,
|
|
async list(query: ReviewQuery = { PageSize: 100 }) {
|
|
return (await listReviewsPage(query)).items
|
|
},
|
|
pendingPage: listPendingReviewsPage,
|
|
async pending(query: ReviewQuery = { PageSize: 100 }) {
|
|
return (await listPendingReviewsPage(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' }),
|
|
}
|