Changeset 0b502c2 for chapterx-frontend/src/pages/profile/ProfilePage.tsx
- Timestamp:
- 06/23/26 17:20:47 (12 days ago)
- Branches:
- main
- Children:
- 99c1e45
- Parents:
- b373fea
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
chapterx-frontend/src/pages/profile/ProfilePage.tsx
rb373fea r0b502c2 1 import React, { useState } from 'react'1 import React, { useState, useEffect } from 'react' 2 2 import { useParams, useNavigate } from 'react-router-dom' 3 3 import { BookOpen, Heart, Users, Calendar, MessageCircle, Eye } from 'lucide-react' 4 4 import { useAuthStore } from '../../store/authStore' 5 5 import { useStoryStore } from '../../store/storyStore' 6 import { useUIStore } from '../../store/uiStore' 6 7 import { Avatar } from '../../components/ui/Avatar' 7 8 import { RoleBadge, StatusBadge } from '../../components/ui/Badge' 8 9 import { StoryCard } from '../../components/ui/StoryCard' 9 10 import { GenreBadge } from '../../components/ui/Badge' 11 import { Modal } from '../../components/ui/Modal' 12 import { Button } from '../../components/ui/Button' 10 13 11 14 type Tab = 'stories' | 'about' … … 14 17 const { username } = useParams<{ username: string }>() 15 18 const navigate = useNavigate() 16 const { allUsers, currentUser } = useAuthStore()19 const { allUsers, currentUser, fetchAllUsers, updateUser } = useAuthStore() 17 20 const { stories, comments } = useStoryStore() 21 const { addToast } = useUIStore() 18 22 const [tab, setTab] = useState<Tab>('stories') 23 const [loading, setLoading] = useState(false) 24 const [editOpen, setEditOpen] = useState(false) 25 const [editForm, setEditForm] = useState({ username: '', email: '', name: '', surname: '' }) 26 const [saving, setSaving] = useState(false) 27 28 useEffect(() => { 29 if (allUsers.length === 0) { 30 setLoading(true) 31 fetchAllUsers().finally(() => setLoading(false)) 32 } 33 }, []) 19 34 20 35 const user = allUsers.find(u => u.username === username) 36 37 const openEdit = () => { 38 if (!user) return 39 setEditForm({ username: user.username, email: user.email, name: user.name, surname: user.surname }) 40 setEditOpen(true) 41 } 42 43 const handleEditSave = async () => { 44 if (!user) return 45 setSaving(true) 46 try { 47 await updateUser(user.user_id, editForm) 48 addToast('Profile updated successfully!') 49 setEditOpen(false) 50 navigate(`/profile/${editForm.username}`, { replace: true }) 51 } catch (err: any) { 52 addToast(err.response?.data?.message ?? 'Failed to update profile.', 'error') 53 } finally { 54 setSaving(false) 55 } 56 } 57 58 if (loading) { 59 return ( 60 <div className="max-w-4xl mx-auto px-4 py-20 text-center"> 61 <p className="text-slate-400">Loading profile...</p> 62 </div> 63 ) 64 } 21 65 22 66 if (!user) { … … 50 94 <Avatar name={`${user.name} ${user.surname}`} size="xl" className="ring-4 ring-slate-950" /> 51 95 {currentUser?.user_id === user.user_id && ( 52 <button className="mb-2 text-sm text-indigo-400 hover:text-indigo-300 transition-colors">96 <button onClick={openEdit} className="mb-2 text-sm text-indigo-400 hover:text-indigo-300 transition-colors"> 53 97 Edit Profile 54 98 </button> … … 159 203 </div> 160 204 )} 205 206 <Modal isOpen={editOpen} onClose={() => setEditOpen(false)} title="Edit Profile"> 207 <div className="space-y-4"> 208 {[ 209 { label: 'First Name', key: 'name' }, 210 { label: 'Last Name', key: 'surname' }, 211 { label: 'Username', key: 'username' }, 212 { label: 'Email', key: 'email' }, 213 ].map(({ label, key }) => ( 214 <div key={key}> 215 <label className="block text-sm text-slate-400 mb-1.5">{label}</label> 216 <input 217 type={key === 'email' ? 'email' : 'text'} 218 value={editForm[key as keyof typeof editForm]} 219 onChange={e => setEditForm(p => ({ ...p, [key]: e.target.value }))} 220 className="w-full px-4 py-2.5 bg-slate-800 border border-slate-700 rounded-xl text-white placeholder-slate-500 focus:outline-none focus:border-indigo-500" 221 /> 222 </div> 223 ))} 224 <div className="flex gap-3 pt-2"> 225 <Button variant="ghost" className="flex-1" onClick={() => setEditOpen(false)}>Cancel</Button> 226 <Button className="flex-1" loading={saving} onClick={handleEditSave}>Save Changes</Button> 227 </div> 228 </div> 229 </Modal> 161 230 </div> 162 231 )
Note:
See TracChangeset
for help on using the changeset viewer.
