From f9cdd626f49aaf9f33731ccb3ea6dcb083f00d33 Mon Sep 17 00:00:00 2001 From: fullsizemalt <106900403+fullsizemalt@users.noreply.github.com> Date: Sat, 20 Dec 2025 02:36:05 -0800 Subject: [PATCH] feat: Add profile editing (bio) to settings page --- backend/routers/users.py | 22 ++++++++++++ frontend/app/settings/page.tsx | 64 ++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/backend/routers/users.py b/backend/routers/users.py index 93e2c90..6962cd2 100644 --- a/backend/routers/users.py +++ b/backend/routers/users.py @@ -1,6 +1,7 @@ from typing import List, Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlmodel import Session, select, func +from pydantic import BaseModel from database import get_session from models import User, Review, Attendance, Group, GroupMember, Show from schemas import UserRead, ReviewRead, ShowRead, GroupRead @@ -8,6 +9,27 @@ from auth import get_current_user router = APIRouter(prefix="/users", tags=["users"]) +class UserProfileUpdate(BaseModel): + bio: Optional[str] = None + avatar: Optional[str] = None + +@router.patch("/me", response_model=UserRead) +def update_my_profile( + update: UserProfileUpdate, + current_user: User = Depends(get_current_user), + session: Session = Depends(get_session) +): + """Update current user's bio and avatar""" + if update.bio is not None: + current_user.bio = update.bio + if update.avatar is not None: + current_user.avatar = update.avatar + + session.add(current_user) + session.commit() + session.refresh(current_user) + return current_user + # --- User Stats --- @router.get("/{user_id}/stats") diff --git a/frontend/app/settings/page.tsx b/frontend/app/settings/page.tsx index bff7053..2d7eba1 100644 --- a/frontend/app/settings/page.tsx +++ b/frontend/app/settings/page.tsx @@ -1,12 +1,50 @@ "use client" +import { useState, useEffect } from "react" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Label } from "@/components/ui/label" import { Switch } from "@/components/ui/switch" +import { Input } from "@/components/ui/input" +import { Textarea } from "@/components/ui/textarea" +import { Button } from "@/components/ui/button" import { usePreferences } from "@/contexts/preferences-context" +import { useAuth } from "@/contexts/auth-context" +import { getApiUrl } from "@/lib/api-config" export default function SettingsPage() { const { preferences, updatePreferences, loading } = usePreferences() + const { user } = useAuth() + const [bio, setBio] = useState("") + const [saving, setSaving] = useState(false) + const [saved, setSaved] = useState(false) + + useEffect(() => { + if (user?.bio) { + setBio(user.bio) + } + }, [user]) + + const handleSaveProfile = async () => { + setSaving(true) + setSaved(false) + const token = localStorage.getItem("token") + try { + await fetch(`${getApiUrl()}/users/me`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${token}` + }, + body: JSON.stringify({ bio }) + }) + setSaved(true) + setTimeout(() => setSaved(false), 2000) + } catch (e) { + console.error(e) + } finally { + setSaving(false) + } + } if (loading) { return
Loading settings...
@@ -16,6 +54,32 @@ export default function SettingsPage() {

Settings

+ {/* Profile Section */} + + + Profile + + Tell other fans about yourself. + + + +
+ +