forked from quant-speed-AI/Scoring-System
125 lines
3.5 KiB
JavaScript
125 lines
3.5 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import { Modal, Form, Input, Upload, Button, message, Avatar } from 'antd';
|
|
import { UserOutlined, UploadOutlined, LoadingOutlined } from '@ant-design/icons';
|
|
import { useAuth } from '../context/AuthContext';
|
|
import { updateUserInfo, uploadUserAvatar } from '../api';
|
|
|
|
const ProfileModal = ({ visible, onClose }) => {
|
|
const { user, updateUser } = useAuth();
|
|
const [form] = Form.useForm();
|
|
const [loading, setLoading] = useState(false);
|
|
const [uploading, setUploading] = useState(false);
|
|
const [avatarUrl, setAvatarUrl] = useState('');
|
|
|
|
useEffect(() => {
|
|
if (visible && user) {
|
|
form.setFieldsValue({
|
|
nickname: user.nickname,
|
|
});
|
|
setAvatarUrl(user.avatar_url);
|
|
}
|
|
}, [visible, user, form]);
|
|
|
|
const handleUpload = async (file) => {
|
|
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
|
|
if (!isJpgOrPng) {
|
|
message.error('You can only upload JPG/PNG file!');
|
|
return Upload.LIST_IGNORE;
|
|
}
|
|
const isLt2M = file.size / 1024 / 1024 < 2;
|
|
if (!isLt2M) {
|
|
message.error('Image must smaller than 2MB!');
|
|
return Upload.LIST_IGNORE;
|
|
}
|
|
|
|
const formData = new FormData();
|
|
formData.append('file', file);
|
|
|
|
setUploading(true);
|
|
try {
|
|
const res = await uploadUserAvatar(formData);
|
|
if (res.data.success) {
|
|
setAvatarUrl(res.data.file_url);
|
|
message.success('头像上传成功');
|
|
} else {
|
|
message.error('头像上传失败: ' + (res.data.message || '未知错误'));
|
|
}
|
|
} catch (error) {
|
|
console.error('Upload failed:', error);
|
|
message.error('头像上传失败');
|
|
} finally {
|
|
setUploading(false);
|
|
}
|
|
return false; // Prevent default auto upload
|
|
};
|
|
|
|
const handleOk = async () => {
|
|
try {
|
|
const values = await form.validateFields();
|
|
setLoading(true);
|
|
|
|
const updateData = {
|
|
nickname: values.nickname,
|
|
avatar_url: avatarUrl
|
|
};
|
|
|
|
const res = await updateUserInfo(updateData);
|
|
updateUser(res.data);
|
|
message.success('个人信息更新成功');
|
|
onClose();
|
|
} catch (error) {
|
|
console.error('Update failed:', error);
|
|
message.error('更新失败');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Modal
|
|
title="个人设置"
|
|
open={visible}
|
|
onOk={handleOk}
|
|
onCancel={onClose}
|
|
confirmLoading={loading}
|
|
centered
|
|
>
|
|
<Form
|
|
form={form}
|
|
layout="vertical"
|
|
style={{ marginTop: 20 }}
|
|
>
|
|
<Form.Item label="头像" style={{ textAlign: 'center' }}>
|
|
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 15 }}>
|
|
<Avatar
|
|
size={100}
|
|
src={avatarUrl}
|
|
icon={<UserOutlined />}
|
|
/>
|
|
<Upload
|
|
name="avatar"
|
|
showUploadList={false}
|
|
beforeUpload={handleUpload}
|
|
accept="image/*"
|
|
>
|
|
<Button icon={uploading ? <LoadingOutlined /> : <UploadOutlined />} loading={uploading}>
|
|
{uploading ? '上传中...' : '更换头像'}
|
|
</Button>
|
|
</Upload>
|
|
</div>
|
|
</Form.Item>
|
|
|
|
<Form.Item
|
|
name="nickname"
|
|
label="昵称"
|
|
rules={[{ required: true, message: '请输入昵称' }]}
|
|
>
|
|
<Input placeholder="请输入昵称" maxLength={20} />
|
|
</Form.Item>
|
|
</Form>
|
|
</Modal>
|
|
);
|
|
};
|
|
|
|
export default ProfileModal;
|