mirror of
https://github.com/fromchat-messenger/web.git
synced 2026-09-22 19:15:08 +03:00
Fix profile
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user