Ignore:
Timestamp:
06/23/26 17:20:47 (12 days ago)
Author:
kikisrbinoska <srbinoskakristina07@…>
Branches:
main
Children:
99c1e45
Parents:
b373fea
Message:

Fixed user profile and reading lists

File:
1 edited

Legend:

Unmodified
Added
Removed
  • chapterx-frontend/src/pages/profile/ProfilePage.tsx

    rb373fea r0b502c2  
    1 import React, { useState } from 'react'
     1import React, { useState, useEffect } from 'react'
    22import { useParams, useNavigate } from 'react-router-dom'
    33import { BookOpen, Heart, Users, Calendar, MessageCircle, Eye } from 'lucide-react'
    44import { useAuthStore } from '../../store/authStore'
    55import { useStoryStore } from '../../store/storyStore'
     6import { useUIStore } from '../../store/uiStore'
    67import { Avatar } from '../../components/ui/Avatar'
    78import { RoleBadge, StatusBadge } from '../../components/ui/Badge'
    89import { StoryCard } from '../../components/ui/StoryCard'
    910import { GenreBadge } from '../../components/ui/Badge'
     11import { Modal } from '../../components/ui/Modal'
     12import { Button } from '../../components/ui/Button'
    1013
    1114type Tab = 'stories' | 'about'
     
    1417  const { username } = useParams<{ username: string }>()
    1518  const navigate = useNavigate()
    16   const { allUsers, currentUser } = useAuthStore()
     19  const { allUsers, currentUser, fetchAllUsers, updateUser } = useAuthStore()
    1720  const { stories, comments } = useStoryStore()
     21  const { addToast } = useUIStore()
    1822  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  }, [])
    1934
    2035  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  }
    2165
    2266  if (!user) {
     
    5094          <Avatar name={`${user.name} ${user.surname}`} size="xl" className="ring-4 ring-slate-950" />
    5195          {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">
    5397              Edit Profile
    5498            </button>
     
    159203        </div>
    160204      )}
     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>
    161230    </div>
    162231  )
Note: See TracChangeset for help on using the changeset viewer.