blob: 4ed94d7d7c4708bf6916e8e98fc094244e033574 [file] [log] [blame]
'use client';
import { useRef, useState } from 'react';
import { Avatar } from 'primereact/avatar';
import { Button } from 'primereact/button';
// 弹窗
import { Dialog } from 'primereact/dialog';
// 头像下拉框
import { OverlayPanel } from 'primereact/overlaypanel';
// 输入框
import { FloatLabel } from "primereact/floatlabel";
import { InputText } from 'primereact/inputtext';
// 页面跳转
import Link from 'next/link';
// 文件上传
import { FileUpload } from 'primereact/fileupload';
// 通知
import { Toast } from 'primereact/toast';
// 接口传输
import axios from 'axios';
// 样式
import './user-avatar.scss';
// 用户下拉框
export default function UserAvatar() {
// 功能选项
const op = useRef<OverlayPanel>(null);
let hoverTimeout: NodeJS.Timeout;
// 通知
const toast = useRef<Toast>(null);
// 控制三个弹窗可见性
const [showEditSignature, setShowEditSignature] = useState(false);
const [showEditAvatar, setShowEditAvatar] = useState(false);
const [showEditPassword, setShowEditPassword] = useState(false);
// 头像URL
const [avatarUrl, setAvatar] = useState<string>('');
// 签名
const [signValue, setSignValue] = useState<string>('');
// 新密码
const [passwardValue, setPasswardValue] = useState<string>('');
const [newPasswardValue, setNewPasswardValue] = useState<string>('');
// 老密码
const [oldPasswardValue, setOldPasswardValue] = useState<string>('');
const handleMouseEnter = (event: React.MouseEvent) => {
clearTimeout(hoverTimeout);
op.current?.show(event, event.currentTarget);
};
const handleMouseLeave = () => {
hoverTimeout = setTimeout(() => {
op.current?.hide();
}, 300);
};
// 修改密码接口
const editPassward = async () => {
try {
await axios.put(process.env.PUBLIC_URL + `/user/password`, {
params: { userId: 22301145, password: oldPasswardValue, newPassword: passwardValue }
});
toast.current?.show({ severity: 'success', summary: 'success', detail: '修改密码成功' });
setShowEditPassword(false);
} catch (err) {
console.error('修改密码失败', err);
toast.current?.show({ severity: 'error', summary: 'error', detail: '修改密码失败' });
}
}
// 修改签名接口
const editSign = async () => {
try {
await axios.put(process.env.PUBLIC_URL + `/user/signature`, {
params: { userId: 22301145, signature: signValue }
});
toast.current?.show({ severity: 'success', summary: 'success', detail: '修改签名成功' });
setShowEditSignature(false);
} catch (err) {
console.error('修改签名失败', err);
toast.current?.show({ severity: 'error', summary: 'error', detail: '修改签名失败' });
}
}
// 修改头像接口
const editAvatar = async () => {
try {
await axios.put(process.env.PUBLIC_URL + `/user/avatar`, {
params: { userId: 22301145, avatar: avatarUrl }
});
toast.current?.show({ severity: 'success', summary: 'success', detail: '修改头像成功' });
setShowEditAvatar(false);
} catch (err) {
console.error('修改头像失败', err);
toast.current?.show({ severity: 'error', summary: 'error', detail: '修改头像失败' });
}
}
return (
<div
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
className="user-avatar-wrapper"
>
<Toast ref={toast}></Toast>
<Link href="/user" className="no-underline">
<Avatar
image="/images/avatar/asiyajavayant.png"
size="large"
shape="circle"
className="user-avatar-link"
/>
</Link>
<OverlayPanel ref={op} dismissable={false}>
<div
onMouseEnter={() => clearTimeout(hoverTimeout)}
onMouseLeave={handleMouseLeave}
className="user-overlay-panel"
>
<Button
text
icon="pi pi-pencil"
label="修改签名"
onClick={() => setShowEditSignature(true)}
/>
<Button
text
icon="pi pi-image"
label="修改头像"
onClick={() => setShowEditAvatar(true)}
/>
<Button
text
icon="pi pi-unlock"
label="修改密码"
onClick={() => setShowEditPassword(true)}
/>
</div>
</OverlayPanel>
{/* 修改签名弹窗 */}
<Dialog
header="修改签名"
visible={showEditSignature}
style={{ width: '30vw' }}
onHide={() => {
setSignValue('');
setShowEditSignature(false);
}}
modal
>
<div className="dialog-container">
<div className="dialog-input-group">
<FloatLabel>
<InputText id="username" value={signValue} onChange={(e) => setSignValue(e.target.value)} />
<label htmlFor="username">个性签名</label>
</FloatLabel>
</div>
<div className="dialog-button-group">
<Button label="确定" className="p-button-sm" onClick={() => editSign()} />
<Button
label="取消"
className="p-button-secondary p-button-sm"
onClick={() => {
setSignValue('');
setShowEditSignature(false);
}}
/>
</div>
</div>
</Dialog>
{/* 修改头像弹窗 */}
<Dialog
header="修改头像"
visible={showEditAvatar}
style={{ display: 'flex', flexDirection: 'column', width: '30vw' }}
onHide={() => {
setAvatar('');
setShowEditAvatar(false);
}}
modal
>
<div className="dialog-container">
<FileUpload
mode="advanced"
name="file"
customUpload
uploadHandler={async (e) => {
const formData = new FormData();
formData.append("file", e.files[0]);
try {
const res = await axios.post(`${process.env.PUBLIC_URL}/file/avatar`, formData);
const fileUrl = res.data.url;
console.log(fileUrl);
setAvatar(fileUrl);
toast.current?.show({ severity: 'success', summary: '上传成功' });
} catch (error) {
console.log(error);
toast.current?.show({ severity: 'error', summary: '上传失败' });
}
}}
auto
accept="image/*"
chooseLabel="上传头像"
/>
<div className="dialog-button-group">
<Button label="确定" className="p-button-sm" onClick={() => editAvatar()} />
<Button
label="取消"
className="p-button-secondary p-button-sm"
onClick={() => setShowEditAvatar(false)}
/>
</div>
</div>
</Dialog>
{/* 修改密码弹窗 */}
<Dialog
header="修改密码"
visible={showEditPassword}
style={{ width: '30vw' }}
onHide={() => {
setOldPasswardValue('');
setPasswardValue('');
setNewPasswardValue('');
setShowEditPassword(false);
}}
modal
>
<div className="dialog-container">
<div className="dialog-input-group">
<FloatLabel>
<InputText id="username" value={oldPasswardValue} onChange={(e) => setOldPasswardValue(e.target.value)} />
<label htmlFor="username">输入旧密码</label>
</FloatLabel>
</div>
<div className="dialog-input-group">
<FloatLabel>
<InputText id="username" value={passwardValue} onChange={(e) => setPasswardValue(e.target.value)} />
<label htmlFor="username">更新密码</label>
</FloatLabel>
</div>
<div className="dialog-input-group">
<FloatLabel>
<InputText id="username" value={newPasswardValue} onChange={(e) => setNewPasswardValue(e.target.value)} />
<label htmlFor="username">确认密码</label>
</FloatLabel>
</div>
<div className="dialog-button-group">
<Button label="确定" className="p-button-sm" onClick={() => {
if (passwardValue !== newPasswardValue) {
toast.current?.show({
severity: 'warn',
summary: '两次密码不一致',
detail: '请确保新密码和确认密码一致',
});
return;
} else {
editPassward();
}
}} />
<Button
label="取消"
className="p-button-secondary p-button-sm"
onClick={() => {
setOldPasswardValue('');
setPasswardValue('');
setNewPasswardValue('');
setShowEditPassword(false);
}}
/>
</div>
</div>
</Dialog>
</div>
);
}