/* Copyright (C) 2025 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ import React, { useEffect, useState, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { API, showError, showSuccess, renderQuota, renderQuotaWithPrompt, } from '../../../../helpers'; import { useIsMobile } from '../../../../hooks/common/useIsMobile'; import { Button, Modal, SideSheet, Space, Spin, Typography, Card, Tag, Form, Avatar, Row, Col, Input, InputNumber, } from '@douyinfe/semi-ui'; import { IconUser, IconSave, IconClose, IconLink, IconUserGroup, IconPlus, } from '@douyinfe/semi-icons'; const { Text, Title } = Typography; const EditUserModal = (props) => { const { t } = useTranslation(); const userId = props.editingUser.id; const [loading, setLoading] = useState(true); const [addQuotaModalOpen, setIsModalOpen] = useState(false); const [addQuotaLocal, setAddQuotaLocal] = useState(''); const isMobile = useIsMobile(); const [groupOptions, setGroupOptions] = useState([]); const formApiRef = useRef(null); const isEdit = Boolean(userId); const getInitValues = () => ({ username: '', display_name: '', password: '', github_id: '', oidc_id: '', discord_id: '', wechat_id: '', telegram_id: '', email: '', quota: 0, group: 'default', remark: '', }); const fetchGroups = async () => { try { let res = await API.get(`/api/group/`); setGroupOptions(res.data.data.map((g) => ({ label: g, value: g }))); } catch (e) { showError(e.message); } }; const handleCancel = () => props.handleClose(); const loadUser = async () => { setLoading(true); const url = userId ? `/api/user/${userId}` : `/api/user/self`; const res = await API.get(url); const { success, message, data } = res.data; if (success) { data.password = ''; formApiRef.current?.setValues({ ...getInitValues(), ...data }); } else { showError(message); } setLoading(false); }; useEffect(() => { loadUser(); if (userId) fetchGroups(); }, [props.editingUser.id]); /* ----------------------- submit ----------------------- */ const submit = async (values) => { setLoading(true); let payload = { ...values }; if (typeof payload.quota === 'string') payload.quota = parseInt(payload.quota) || 0; if (userId) { payload.id = parseInt(userId); } const url = userId ? `/api/user/` : `/api/user/self`; const res = await API.put(url, payload); const { success, message } = res.data; if (success) { showSuccess(t('用户信息更新成功!')); props.refresh(); props.handleClose(); } else { showError(message); } setLoading(false); }; /* --------------------- quota helper -------------------- */ const addLocalQuota = () => { const current = parseInt(formApiRef.current?.getValue('quota') || 0); const delta = parseInt(addQuotaLocal) || 0; formApiRef.current?.setValue('quota', current + delta); }; /* --------------------------- UI --------------------------- */ return ( <> {t(isEdit ? '编辑' : '新建')} {isEdit ? t('编辑用户') : t('创建用户')} } bodyStyle={{ padding: 0 }} visible={props.visible} width={isMobile ? '100%' : 600} footer={
} closeIcon={null} onCancel={handleCancel} >
(formApiRef.current = api)} onSubmit={submit} > {({ values }) => (
{/* 基本信息 */}
{t('基本信息')}
{t('用户的基本账户信息')}
{/* 权限设置 */} {userId && (
{t('权限设置')}
{t('用户分组和额度管理')}
)}
{/* 添加额度模态框 */} { addLocalQuota(); setIsModalOpen(false); }} onCancel={() => setIsModalOpen(false)} closable={null} title={
{t('添加额度')}
} >
{(() => { const current = formApiRef.current?.getValue('quota') || 0; return ( {`${t('新额度:')}${renderQuota(current)} + ${renderQuota(addQuotaLocal)} = ${renderQuota(current + parseInt(addQuotaLocal || 0))}`} ); })()}
); }; export default EditUserModal;