Compare commits

..

No commits in common. "835174c60490d26c8dc6fc467444057ce21a7419" and "542e4b52e12beb95bd471f3527517bdc01a239e8" have entirely different histories.

View file

@ -38,8 +38,7 @@ export const SettingsPage: React.FC = () => {
setDispName(res.data.disp_name || ""); setDispName(res.data.disp_name || "");
setUserDesc(res.data.user_desc || ""); setUserDesc(res.data.user_desc || "");
setAvatarId(res.data.image?.id ?? null); setAvatarId(res.data.image?.id ?? null);
const path = res.data.image?.image_path; setAvatarUrl(res.data.image?.image_path ?? null);
setAvatarUrl(path ? (path.startsWith('http') ? path : `/media/${path}`) : null);
} }
} catch (err) { } catch (err) {
console.error("Failed to fetch user:", err); console.error("Failed to fetch user:", err);
@ -55,46 +54,40 @@ const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
setUploading(true); setUploading(true);
setError(null); setError(null);
setSuccess(null);
// Создаем стандартный объект FormData
const formData = new FormData(); const formData = new FormData();
// Ключ "image" соответствует вашему OpenAPI
formData.append("image", file); formData.append("image", file);
try { try {
// 1. Загружаем файл на сервер (POST) // Используем нативный fetch вместо сгенерированного postMediaUpload
const uploadRes = await fetch("/api/v1/media/upload", { const response = await fetch("/api/v1/media/upload", {
method: "POST", method: "POST",
body: formData, body: formData,
headers: { headers: {
// Важно: НЕ УКАЗЫВАЕМ Content-Type.
// Браузер сам добавит multipart/form-data и сгенерирует boundary.
"X-XSRF-TOKEN": xsrfToken || "", "X-XSRF-TOKEN": xsrfToken || "",
}, },
}); });
if (!uploadRes.ok) throw new Error("Failed to upload image to storage"); if (!response.ok) {
const errorText = await response.text();
throw new Error(errorText || "Upload failed");
}
const uploadData = await uploadRes.json(); // Ответ должен соответствовать схеме Image.yaml
const newAvatarId = uploadData.id; const data = await response.json();
if (newAvatarId) { if (data && data.id) {
// 2. СРАЗУ отправляем PATCH запрос для обновления профиля пользователя setAvatarId(data.id);
await updateUser({ setAvatarUrl(data.image_path ?? null);
path: { user_id: userId }, setSuccess("Image uploaded!");
body: {
avatar_id: newAvatarId, // Привязываем новый ID к юзеру
},
headers: { "X-XSRF-TOKEN": xsrfToken },
});
// 3. Обновляем локальный стейт для отображения
setAvatarId(newAvatarId);
const path = uploadData.image_path;
setAvatarUrl(path ? (path.startsWith("/") ? path : `/media/${path}`) : null);
setSuccess("Avatar updated successfully!");
} }
} catch (err: any) { } catch (err: any) {
console.error("Upload & Patch error:", err); console.error("Upload error:", err);
setError(err.message || "Failed to update avatar"); setError(err.message || "Failed to upload image");
} finally { } finally {
setUploading(false); setUploading(false);
} }