diff --git a/backend/UniVerse.Api/UniVerse.Api.csproj b/backend/UniVerse.Api/UniVerse.Api.csproj index e6b73df..498c052 100644 --- a/backend/UniVerse.Api/UniVerse.Api.csproj +++ b/backend/UniVerse.Api/UniVerse.Api.csproj @@ -17,7 +17,6 @@ - diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts index 16e7bf9..d7230f8 100644 --- a/frontend/src/api/index.ts +++ b/frontend/src/api/index.ts @@ -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(`/users/${id}`), + async list(query: UserQuery = {}) { + const payload = await apiRequest | UserDto[]>('/users', { + query: query as Record, + }) + return extractItems(payload) + }, stats: (id: string | number) => apiRequest(`/users/${id}/stats`), async enrollments(id: string | number) { const payload = await apiRequest | LectureDto[] | undefined>(`/users/${id}/enrollments`) @@ -59,6 +70,10 @@ export const usersApi = { ) return extractItems(payload) }, + setRole: (id: string | number, role: 'Student' | 'Teacher' | 'Admin') => + apiRequest(`/users/${id}/role`, { method: 'PATCH', body: JSON.stringify(role) }), + setActive: (id: string | number, isActive: boolean) => + apiRequest(`/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 | ReviewDto[]>('/reviews/pending') + return extractItems(payload) + }, + reanalyze: (id: string | number) => apiRequest(`/reviews/${id}/reanalyze`, { method: 'POST' }), +} + +export const coursesApi = { + async list() { + const payload = await apiRequest | CourseDto[]>('/courses', { query: { PageSize: 100 } }) + return extractItems(payload) + }, +} + +export const locationsApi = { + async list() { + const payload = await apiRequest | LocationDto[]>('/locations') + return extractItems(payload) + }, +} + +export const tagsApi = { + async list() { + const payload = await apiRequest | TagDto[]>('/tags') + return extractItems(payload) + }, +} + +export const syncApi = { + status: () => apiRequest('/sync/status'), } diff --git a/frontend/src/api/types.ts b/frontend/src/api/types.ts index 2f9ede9..ea6f23c 100644 --- a/frontend/src/api/types.ts +++ b/frontend/src/api/types.ts @@ -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 diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index 54cb61b..7c22f41 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -45,6 +45,11 @@ router.beforeEach(async (to) => { if (!to.meta.public && !auth.isAuthenticated) { return '/login' } + if (to.meta.role && auth.user && auth.user.role !== to.meta.role) { + if (auth.user.role === 'teacher') return '/teacher' + if (auth.user.role === 'admin') return '/admin' + return '/' + } }) export default router diff --git a/frontend/src/views/admin/AdminDashboardView.vue b/frontend/src/views/admin/AdminDashboardView.vue index 66db735..fd63518 100644 --- a/frontend/src/views/admin/AdminDashboardView.vue +++ b/frontend/src/views/admin/AdminDashboardView.vue @@ -1,8 +1,11 @@