feat: Add profile editing (bio) to settings page
This commit is contained in:
parent
3575ac4700
commit
f9cdd626f4
2 changed files with 86 additions and 0 deletions
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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 <div>Loading settings...</div>
|
||||
|
|
@ -16,6 +54,32 @@ export default function SettingsPage() {
|
|||
<div className="max-w-2xl mx-auto space-y-6">
|
||||
<h1 className="text-3xl font-bold tracking-tight">Settings</h1>
|
||||
|
||||
{/* Profile Section */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Profile</CardTitle>
|
||||
<CardDescription>
|
||||
Tell other fans about yourself.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="bio">Bio</Label>
|
||||
<Textarea
|
||||
id="bio"
|
||||
placeholder="Been following the band since 2019..."
|
||||
value={bio}
|
||||
onChange={(e) => setBio(e.target.value)}
|
||||
rows={3}
|
||||
/>
|
||||
</div>
|
||||
<Button onClick={handleSaveProfile} disabled={saving}>
|
||||
{saving ? "Saving..." : saved ? "Saved ✓" : "Save Profile"}
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Preferences Section */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Preferences</CardTitle>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue