147 lines
6 KiB
TypeScript
147 lines
6 KiB
TypeScript
"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"
|
|
import { AvatarSettings } from "@/components/profile/avatar-settings"
|
|
|
|
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(() => {
|
|
// Bio might be in extended user response - check dynamically
|
|
if (user && 'bio' in user && typeof (user as Record<string, unknown>).bio === 'string') {
|
|
setBio((user as Record<string, unknown>).bio as string)
|
|
}
|
|
}, [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>
|
|
}
|
|
|
|
return (
|
|
<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>
|
|
|
|
{/* Avatar Section */}
|
|
<AvatarSettings
|
|
currentBgColor={(user as any)?.avatar_bg_color || "#3B82F6"}
|
|
currentText={(user as any)?.avatar_text || ""}
|
|
username={(user as any)?.email?.split('@')[0] || "User"}
|
|
/>
|
|
|
|
{/* Preferences Section */}
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Preferences</CardTitle>
|
|
<CardDescription>
|
|
Customize your browsing experience.
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="space-y-6">
|
|
<div className="flex items-center justify-between space-x-2">
|
|
<div className="space-y-0.5">
|
|
<Label htmlFor="wiki-mode">Wiki Mode</Label>
|
|
<p className="text-sm text-muted-foreground">
|
|
Hide all social features (comments, ratings, reviews) for a pure archive experience.
|
|
</p>
|
|
</div>
|
|
<Switch
|
|
id="wiki-mode"
|
|
checked={preferences.wiki_mode}
|
|
onChange={(e) => updatePreferences({ wiki_mode: e.target.checked })}
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex items-center justify-between space-x-2">
|
|
<div className="space-y-0.5">
|
|
<Label htmlFor="show-ratings">Show Ratings</Label>
|
|
<p className="text-sm text-muted-foreground">
|
|
Display 1-10 ratings on shows and songs.
|
|
</p>
|
|
</div>
|
|
<Switch
|
|
id="show-ratings"
|
|
checked={preferences.show_ratings}
|
|
disabled={preferences.wiki_mode}
|
|
onChange={(e) => updatePreferences({ show_ratings: e.target.checked })}
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex items-center justify-between space-x-2">
|
|
<div className="space-y-0.5">
|
|
<Label htmlFor="show-comments">Show Comments</Label>
|
|
<p className="text-sm text-muted-foreground">
|
|
Display comment sections on pages.
|
|
</p>
|
|
</div>
|
|
<Switch
|
|
id="show-comments"
|
|
checked={preferences.show_comments}
|
|
disabled={preferences.wiki_mode}
|
|
onChange={(e) => updatePreferences({ show_comments: e.target.checked })}
|
|
/>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
)
|
|
}
|