import React, { useState, useRef, useEffect } from 'react'; import { useStoreData } from '../hooks/useStoreData'; import { Store } from '../utils/store'; import { userApi } from '../api/user'; import { User, Settings, LogOut, X, Edit2 } from 'lucide-react'; import { GlassCard } from './ui/GlassCard'; import { Button } from './ui/Button'; import clsx from 'clsx'; /** * 用户资料菜单组件 * 显示用户信息、编辑资料和退出登录选项 */ export function UserMenu({ isOpen, onClose, onLogout }) { const data = useStoreData(); const [showEditModal, setShowEditModal] = useState(false); const menuRef = useRef(null); // 每次打开菜单时,重置编辑模态框状态(模仿 PncyssD 的逻辑) // 确保每次打开菜单都显示主菜单界面,而不是编辑界面 useEffect(() => { if (isOpen) { // 菜单打开时,确保编辑模态框是关闭的 setShowEditModal(false); } }, [isOpen]); // 点击外部关闭菜单 useEffect(() => { if (!isOpen) return; const handleClickOutside = (event) => { if (menuRef.current && !menuRef.current.contains(event.target)) { onClose(); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, [isOpen, onClose]); // 如果菜单未打开,不渲染任何内容(除非正在显示编辑模态框) if (!isOpen && !showEditModal) return null; // 如果正在显示编辑模态框,只渲染编辑模态框 if (showEditModal) { return ( { setShowEditModal(false); // 编辑模态框关闭后,如果菜单是打开的,会显示主菜单 }} userProfile={data.userProfile} /> ); } // 显示主菜单(isOpen 为 true 且 showEditModal 为 false) // 显示主菜单 return ( <> {/* 菜单遮罩层 */}
{/* 用户菜单 */}
{/* 用户信息头部 */}
{data.userProfile.nickname?.[0] || 'U'}
{data.userProfile.nickname || '旅人'}
{data.userProfile.mbti || '未知'} · {data.userProfile.zodiac || '未知'}
{/* 统计数据 */}
{data.lifeTimeline?.length || 0}
生命足迹
{data.generatedScripts?.length || 0}
剧本生成
{/* 操作按钮 */}
); } /** * 编辑资料模态框组件 */ function EditProfileModal({ onClose, userProfile }) { const [formData, setFormData] = useState({ nickname: userProfile.nickname || '', mbti: userProfile.mbti || '', zodiac: userProfile.zodiac || '', hobbies: userProfile.hobbies?.join(', ') || '', gender: userProfile.gender || 'secret' }); const [isSaving, setIsSaving] = useState(false); const [error, setError] = useState(''); const handleSave = async () => { setIsSaving(true); setError(''); const updatedProfile = { nickname: formData.nickname, mbti: formData.mbti, zodiac: formData.zodiac, hobbies: formData.hobbies.split(',').map(s => s.trim()).filter(s => s), gender: formData.gender }; try { // 1. 更新本地 Store Store.updateProfile(updatedProfile); // 2. 同步到后端 const currentProfile = await userApi.getCurrentUser(); if (currentProfile.data && currentProfile.data.id) { await userApi.updateUserProfile({ id: currentProfile.data.id, nickname: updatedProfile.nickname, mbti: updatedProfile.mbti, zodiac: updatedProfile.zodiac, hobbies: JSON.stringify(updatedProfile.hobbies), gender: updatedProfile.gender }); } onClose(); } catch (e) { console.error('保存资料失败:', e); setError(e.response?.data?.message || '保存失败,请重试'); } finally { setIsSaving(false); } }; return (
{/* 关闭按钮 */} {/* 标题 */}

编辑资料

调整你的人生航向基础信息

{/* 表单 */}
setFormData({ ...formData, nickname: e.target.value })} placeholder="你想被如何称呼?" className="w-full px-4 py-3 bg-white/5 border border-white/10 rounded-xl text-white placeholder-white/30 focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary/50 transition-all" />
setFormData({ ...formData, mbti: e.target.value })} placeholder="性格色彩" className="w-full px-4 py-3 bg-white/5 border border-white/10 rounded-xl text-white placeholder-white/30 focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary/50 transition-all" />
setFormData({ ...formData, zodiac: e.target.value })} placeholder="星辰指引" className="w-full px-4 py-3 bg-white/5 border border-white/10 rounded-xl text-white placeholder-white/30 focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary/50 transition-all" />
setFormData({ ...formData, hobbies: e.target.value })} placeholder="让灵魂起舞的事物(用逗号分隔)" className="w-full px-4 py-3 bg-white/5 border border-white/10 rounded-xl text-white placeholder-white/30 focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary/50 transition-all" />
{/* 错误提示 */} {error && (
{error}
)}
{/* 操作按钮 */}
); }