Fix profile

This commit is contained in:
2025-09-06 12:19:21 +03:00
Unverified
parent 7f0d2b66f4
commit ca3336b0cc
4 changed files with 95 additions and 8 deletions
+56
View File
@@ -8,9 +8,15 @@ import io
from dependencies import get_db, get_current_user
from models import User, UpdateBioRequest, UserProfileResponse
from pydantic import BaseModel
router = APIRouter()
# Request models
class UpdateProfileRequest(BaseModel):
nickname: str | None = None
description: str | None = None
# Create uploads directory if it doesn't exist
PROFILE_PICTURES_DIR = Path("data/uploads/pfp")
@@ -98,6 +104,56 @@ async def get_user_profile(
"created_at": current_user.created_at
}
@router.put("/user/profile")
async def update_user_profile(
request: UpdateProfileRequest,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""
Update current user's profile information
"""
updated = False
# Update username if provided
if request.nickname is not None:
nickname = request.nickname.strip()
if len(nickname) < 3:
raise HTTPException(status_code=400, detail="Username must be at least 3 characters long")
if len(nickname) > 50:
raise HTTPException(status_code=400, detail="Username must be 50 characters or less")
# Check if username is already taken by another user
existing_user = db.query(User).filter(User.username == nickname, User.id != current_user.id).first()
if existing_user:
raise HTTPException(status_code=400, detail="Username already taken")
current_user.username = nickname
updated = True
# Update bio if provided
if request.description is not None:
bio = request.description.strip()
if len(bio) > 500:
raise HTTPException(status_code=400, detail="Bio must be 500 characters or less")
current_user.bio = bio
updated = True
if updated:
db.commit()
return {
"message": "Profile updated successfully",
"username": current_user.username,
"bio": current_user.bio
}
else:
return {
"message": "No changes made",
"username": current_user.username,
"bio": current_user.bio
}
@router.put("/user/bio")
async def update_user_bio(
+18 -3
View File
@@ -25,7 +25,13 @@ export async function loadProfile(): Promise<ProfileData | null> {
});
if (response.ok) {
return await response.json();
const data = await response.json();
// Map backend fields to frontend fields
return {
profile_picture: data.profile_picture,
nickname: data.username,
description: data.bio
};
}
return null;
@@ -83,10 +89,19 @@ export async function uploadProfilePicture(file: Blob): Promise<UploadResponse |
*/
export async function updateProfile(data: Partial<ProfileData>): Promise<boolean> {
try {
// Map frontend fields to backend fields
const backendData = {
nickname: data.nickname,
description: data.description
};
const response = await fetch('/api/user/profile', {
method: 'PUT',
headers: getAuthHeaders(),
body: JSON.stringify(data)
headers: {
...getAuthHeaders(),
'Content-Type': 'application/json'
},
body: JSON.stringify(backendData)
});
return response.ok;
+18 -3
View File
@@ -22,7 +22,13 @@ export async function loadProfile(token: string): Promise<ProfileData | null> {
});
if (response.ok) {
return await response.json();
const data = await response.json();
// Map backend fields to frontend fields
return {
profile_picture: data.profile_picture,
nickname: data.username,
description: data.bio
};
}
return null;
@@ -61,10 +67,19 @@ export async function uploadProfilePicture(token: string, file: Blob): Promise<U
*/
export async function updateProfile(token: string, data: Partial<ProfileData>): Promise<boolean> {
try {
// Map frontend fields to backend fields
const backendData = {
nickname: data.nickname,
description: data.description
};
const response = await fetch(`${API_BASE_URL}/user/profile`, {
method: 'PUT',
headers: getAuthHeaders(token),
body: JSON.stringify(data)
headers: {
...getAuthHeaders(token),
'Content-Type': 'application/json'
},
body: JSON.stringify(backendData)
});
return response.ok;
@@ -9,8 +9,9 @@ import { MaterialTextField } from "../core/TextField";
export function ProfileDialog({ isOpen, onOpenChange }: DialogProps) {
const { profileData, isLoading, isUpdating, updateProfileData, uploadProfilePictureData } = useProfile();
const [username, setUsername] = useState("");
const [description, setDescription] = useState("");
const [username, setUsername] = useState(profileData?.nickname ?? "");
const [description, setDescription] = useState(profileData?.description ?? "");
const [selectedImage, setSelectedImage] = useState<File | null>(null);
const [showCropper, setShowCropper] = useState(false);