feat: переделал все клиентские запросы на другие endpoint для безопастности
Backend CI / build-and-test (push) Successful in 48s
Frontend CI / build-and-check (push) Failing after 5m13s
🚀 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 1m9s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Successful in 26s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 14s
Backend CI / build-and-test (push) Successful in 48s
Frontend CI / build-and-check (push) Failing after 5m13s
🚀 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 1m9s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Successful in 26s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 14s
This commit is contained in:
@@ -59,6 +59,32 @@ export const lecturesApi = {
|
||||
}
|
||||
|
||||
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'),
|
||||
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', {
|
||||
|
||||
@@ -33,7 +33,6 @@ function getDefaultActiveRole(roles: UserRole[]): UserRole {
|
||||
export function mapApiUser(user: UserAuthDto | UserDto | CurrentUserDto, stats?: UserStatsDto): User {
|
||||
const roles = mapApiRoles(user.roles)
|
||||
return {
|
||||
id: String(user.id),
|
||||
name: user.displayName || user.email || 'Пользователь UniVerse',
|
||||
email: user.email || '',
|
||||
roles,
|
||||
|
||||
@@ -29,13 +29,13 @@ export interface LoginMicrosoftRequest {
|
||||
}
|
||||
|
||||
export interface UserAuthDto {
|
||||
id: number
|
||||
email: string
|
||||
displayName?: string | null
|
||||
roles: ApiUserRole[]
|
||||
}
|
||||
|
||||
export interface UserDto extends UserAuthDto {
|
||||
id: number
|
||||
avatarUrl?: string | null
|
||||
isActive: boolean
|
||||
xp: number
|
||||
|
||||
@@ -46,17 +46,17 @@ export const useLecturesStore = defineStore('lectures', () => {
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchRegisteredForUser(userId: string) {
|
||||
async function fetchRegisteredForCurrentUser() {
|
||||
try {
|
||||
const enrollments = await usersApi.enrollments(userId)
|
||||
const enrollments = await usersApi.myEnrollments()
|
||||
const mapped = enrollments.map(mapApiLecture)
|
||||
registered.value = mapped.map(lecture => lecture.id)
|
||||
if (mapped.length) {
|
||||
mapped.forEach(lecture => {
|
||||
const index = lectures.value.findIndex(item => item.id === lecture.id)
|
||||
if (index >= 0) lectures.value[index] = { ...lectures.value[index], ...lecture, registered: true }
|
||||
else lectures.value.push({ ...lecture, registered: true })
|
||||
})
|
||||
registered.value = mapped.map(lecture => lecture.id)
|
||||
}
|
||||
} catch {
|
||||
// Some backend builds return an empty 200 for this endpoint; catalog detail still carries isEnrolled.
|
||||
@@ -108,7 +108,7 @@ export const useLecturesStore = defineStore('lectures', () => {
|
||||
registeredLectures,
|
||||
fetchLectures,
|
||||
fetchLecture,
|
||||
fetchRegisteredForUser,
|
||||
fetchRegisteredForCurrentUser,
|
||||
fetchReviews,
|
||||
register,
|
||||
unregister,
|
||||
|
||||
@@ -12,18 +12,17 @@ export const useUserStore = defineStore('user', () => {
|
||||
const loading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
|
||||
async function fetchStudentData(userId?: string) {
|
||||
async function fetchStudentData() {
|
||||
const auth = useAuthStore()
|
||||
const id = userId ?? auth.user?.id
|
||||
if (!id) return
|
||||
if (!auth.user) return
|
||||
|
||||
loading.value = true
|
||||
error.value = null
|
||||
try {
|
||||
const [stats, achievementPayload, transactions] = await Promise.all([
|
||||
usersApi.stats(id),
|
||||
usersApi.achievements(id),
|
||||
usersApi.transactions(id),
|
||||
usersApi.myStats(),
|
||||
usersApi.myAchievements(),
|
||||
usersApi.myTransactions(),
|
||||
])
|
||||
const [achievementCatalog, notificationPayload] = await Promise.all([
|
||||
achievementsApi.list(),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
export type UserRole = 'student' | 'teacher' | 'admin'
|
||||
|
||||
export interface User {
|
||||
id: string
|
||||
name: string
|
||||
email: string
|
||||
roles: UserRole[]
|
||||
|
||||
@@ -11,7 +11,7 @@ const unlocked = computed(() => userStore.achievements.filter(a => a.unlocked))
|
||||
const locked = computed(() => userStore.achievements.filter(a => !a.unlocked))
|
||||
|
||||
onMounted(() => {
|
||||
if (auth.user) void userStore.fetchStudentData(auth.user.id)
|
||||
if (auth.user) void userStore.fetchStudentData()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -56,9 +56,9 @@ const levelProgressText = computed(() =>
|
||||
onMounted(async () => {
|
||||
await Promise.all([
|
||||
lectures.all.length ? Promise.resolve() : lectures.fetchLectures(),
|
||||
userStore.fetchStudentData(user.value.id),
|
||||
userStore.fetchStudentData(),
|
||||
])
|
||||
await lectures.fetchRegisteredForUser(user.value.id)
|
||||
await lectures.fetchRegisteredForCurrentUser()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ const history = computed(() => lecturesStore.all.filter(l => l.status === 'compl
|
||||
|
||||
onMounted(async () => {
|
||||
if (!lecturesStore.all.length) await lecturesStore.fetchLectures()
|
||||
if (auth.user) await lecturesStore.fetchRegisteredForUser(auth.user.id)
|
||||
if (auth.user) await lecturesStore.fetchRegisteredForCurrentUser()
|
||||
})
|
||||
|
||||
function openCancel(id: string) {
|
||||
|
||||
@@ -53,7 +53,7 @@ const interestTags = ref([
|
||||
const notificationSettings = ref({ email: true })
|
||||
|
||||
onMounted(() => {
|
||||
void userStore.fetchStudentData(user.value.id)
|
||||
void userStore.fetchStudentData()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user