feat: добавил кабинеты преподавателя и администратора
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 8s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 38s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Successful in 18s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 6s

This commit is contained in:
2026-05-11 01:58:09 +03:00
parent 779b6aba77
commit 610c15c9fd
11 changed files with 399 additions and 90 deletions
+45
View File
@@ -3,12 +3,17 @@ import type {
AchievementDto,
AuthResponse,
CoinTransactionDto,
CourseDto,
LectureDto,
LectureQuery,
LocationDto,
PagedResult,
ReviewDto,
SyncStatusDto,
TagDto,
UserAchievementDto,
UserDto,
UserQuery,
UserStatsDto,
} from './types'
@@ -41,6 +46,12 @@ export const lecturesApi = {
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`)
@@ -59,6 +70,10 @@ export const usersApi = {
)
return extractItems(payload)
},
setRole: (id: string | number, role: 'Student' | 'Teacher' | 'Admin') =>
apiRequest<void>(`/users/${id}/role`, { method: 'PATCH', body: JSON.stringify(role) }),
setActive: (id: string | number, isActive: boolean) =>
apiRequest<void>(`/users/${id}/active`, { method: 'PATCH', body: JSON.stringify(isActive) }),
}
export const reviewsApi = {
@@ -67,4 +82,34 @@ export const reviewsApi = {
method: 'POST',
body: JSON.stringify({ lectureId: Number(lectureId), rating, text }),
}),
async pending() {
const payload = await apiRequest<PagedResult<ReviewDto> | ReviewDto[]>('/reviews/pending')
return extractItems(payload)
},
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'),
}
+47
View File
@@ -44,6 +44,14 @@ export interface UserDto extends UserAuthDto {
createdAt: string
}
export interface UserQuery {
Search?: string
Role?: ApiUserRole
IsActive?: boolean
Page?: number
PageSize?: number
}
export interface UserStatsDto {
totalLectures: number
attendedLectures: number
@@ -102,6 +110,45 @@ export interface AchievementDto {
createdAt: string
}
export interface CourseDto {
id: number
name?: string | null
description?: string | null
isSynced: boolean
tags?: TagDto[] | null
createdAt: string
}
export interface LocationDto {
id: number
name?: string | null
building?: string | null
room?: string | null
address?: string | null
createdAt: string
}
export type ApiTagType = 'Institute' | 'Faculty' | 'Subject' | 'Organization' | 'Topic' | 'Other'
export interface TagDto {
id: number
name?: string | null
type: ApiTagType
parentId?: number | null
createdAt: string
}
export interface SyncStatusDto {
lastSyncAt?: string | null
status?: string | null
lastResult?: {
created: number
updated: number
skipped: number
error?: string | null
} | null
}
export interface UserAchievementDto {
id: number
achievement: AchievementDto