/** * 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 { const params = new URLSearchParams({ q: query, limit: String(limit) }) return apiRequest(`/users?${params.toString()}`) } /** Команда в справочнике команд (страница профиля). */ export interface TeamOption { id: string name: string } /** * Справочник команд для страницы профиля — аутентифицированный эндпоинт, * не зависит от тумблера `registration_team_choice` (в отличие от * `getRegistrationOptions` в `api/auth.ts`, который гасит список команд при * выключенном выборе команды на регистрации). */ export async function listTeams(): Promise { return apiRequest('/teams') } /** Тело правки собственного профиля — ФИО и/или команда, email не редактируется. */ export interface UpdateMePayload { name_user?: string /** `null` — снять с команды. */ team_id?: string | null } /** Частично обновить собственный профиль. */ export async function updateMe(payload: UpdateMePayload): Promise { return apiRequest('/users/me', { method: 'PATCH', body: payload }) } /** * Загрузить аватар текущего пользователя. 200 — полный обновлённый профиль. * 413 — файл больше 2 МБ, 415 — недопустимый тип (разрешены jpeg/png/webp); * оба кода обрабатываются вызывающей стороной через `ApiError.status`. */ export async function uploadMyAvatar(file: File): Promise { const form = new FormData() form.append('file', file) return apiRequest('/users/me/avatar', { method: 'POST', body: form }) } /** Удалить аватар текущего пользователя — 204 без тела; вызывающая сторона сама перечитывает профиль (см. `refreshUser`). */ export async function deleteMyAvatar(): Promise { 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 { await apiRequest('/users/me/password', { method: 'POST', body: payload }) }