Files
vidconf/frontend/src/api/users.ts
Max Ronzhin 8757bec8ac
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
first commit
2026-07-23 02:38:05 +03:00

81 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* API-функции профиля текущего пользователя и поиска зарегистрированных
* пользователей (участники конференций, профиль).
*/
import { apiRequest } from '@/api/client'
import type { CurrentUser } from '@/api/auth'
/** Элемент результата поиска пользователей (пикер участников конференции) — без email, только для отображения/выбора по `id`. */
export interface UserSearchResult {
id: string
display_name: string
avatar_url: string | null
}
/** Поиск зарегистрированных пользователей по имени/email — для пикера участников конференции. */
export async function searchUsers(query: string, limit = 8): Promise<UserSearchResult[]> {
const params = new URLSearchParams({ q: query, limit: String(limit) })
return apiRequest<UserSearchResult[]>(`/users?${params.toString()}`)
}
/** Команда в справочнике команд (страница профиля). */
export interface TeamOption {
id: string
name: string
}
/**
* Справочник команд для страницы профиля — аутентифицированный эндпоинт,
* не зависит от тумблера `registration_team_choice` (в отличие от
* `getRegistrationOptions` в `api/auth.ts`, который гасит список команд при
* выключенном выборе команды на регистрации).
*/
export async function listTeams(): Promise<TeamOption[]> {
return apiRequest<TeamOption[]>('/teams')
}
/** Тело правки собственного профиля — ФИО и/или команда, email не редактируется. */
export interface UpdateMePayload {
name_user?: string
/** `null` — снять с команды. */
team_id?: string | null
}
/** Частично обновить собственный профиль. */
export async function updateMe(payload: UpdateMePayload): Promise<CurrentUser> {
return apiRequest<CurrentUser>('/users/me', { method: 'PATCH', body: payload })
}
/**
* Загрузить аватар текущего пользователя. 200 — полный обновлённый профиль.
* 413 — файл больше 2 МБ, 415 — недопустимый тип (разрешены jpeg/png/webp);
* оба кода обрабатываются вызывающей стороной через `ApiError.status`.
*/
export async function uploadMyAvatar(file: File): Promise<CurrentUser> {
const form = new FormData()
form.append('file', file)
return apiRequest<CurrentUser>('/users/me/avatar', { method: 'POST', body: form })
}
/** Удалить аватар текущего пользователя — 204 без тела; вызывающая сторона сама перечитывает профиль (см. `refreshUser`). */
export async function deleteMyAvatar(): Promise<void> {
await apiRequest('/users/me/avatar', { method: 'DELETE' })
}
/** Тело смены пароля текущего пользователя. */
export interface PasswordChangePayload {
current_password: string
new_password: string
}
/**
* Сменить пароль текущего пользователя. 204 без тела. 400 `invalid_current_password` —
* неверный текущий пароль, 422 — новый пароль короче 8 символов.
*
* Refresh-сессии сознательно не отзываются backend'ом (минимальный дифф —
* см. ADR-005, отзыв запланирован вместе со сбросом пароля по email в v0.1.0).
*/
export async function changePassword(payload: PasswordChangePayload): Promise<void> {
await apiRequest('/users/me/password', { method: 'POST', body: payload })
}