mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-24 05:26:08 +00:00
7ae3ea66d1
- Rename tabs: "Basic" → "Basics", "Config" → "Credentials" - Move reverseTag field from Credentials tab to Basics tab - Move IP log button inline with limitIp field (tooltip button, edit mode only) - Hide random email button when editing an existing client - Add tooltips to totalGB and limitIp fields with descriptive hints - Rename labels: "Total Sent/Received (GB)" → "Traffic Limit (GB)", "Duration" → "Duration (days)" - Add renewDays translation key for auto-renew label with unit hint - Remove redundant filterOption and width style from AutoComplete group selectors - Update all 15 locale files with new and renamed translation keys
78 lines
2.0 KiB
TypeScript
78 lines
2.0 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { AutoComplete, Form, Modal, message } from 'antd';
|
|
|
|
interface BulkAddToGroupModalProps {
|
|
open: boolean;
|
|
count: number;
|
|
groups: string[];
|
|
onOpenChange: (open: boolean) => void;
|
|
onSubmit: (group: string) => Promise<{ affected?: number } | null>;
|
|
}
|
|
|
|
export default function BulkAddToGroupModal({
|
|
open,
|
|
count,
|
|
groups,
|
|
onOpenChange,
|
|
onSubmit,
|
|
}: BulkAddToGroupModalProps) {
|
|
const { t } = useTranslation();
|
|
const [messageApi, messageContextHolder] = message.useMessage();
|
|
const [value, setValue] = useState('');
|
|
const [submitting, setSubmitting] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if (open) setValue('');
|
|
}, [open]);
|
|
|
|
async function submit() {
|
|
const next = value.trim();
|
|
if (!next) return;
|
|
setSubmitting(true);
|
|
try {
|
|
const result = await onSubmit(next);
|
|
if (result) {
|
|
const affected = result.affected ?? 0;
|
|
messageApi.success(t('pages.clients.addToGroupSuccessToast', { count: affected, group: next }));
|
|
onOpenChange(false);
|
|
}
|
|
} finally {
|
|
setSubmitting(false);
|
|
}
|
|
}
|
|
|
|
return (
|
|
<>
|
|
{messageContextHolder}
|
|
<Modal
|
|
open={open}
|
|
title={t('pages.clients.addToGroupTitle', { count })}
|
|
okText={t('add')}
|
|
cancelText={t('cancel')}
|
|
confirmLoading={submitting}
|
|
okButtonProps={{ disabled: !value.trim() }}
|
|
onCancel={() => onOpenChange(false)}
|
|
onOk={submit}
|
|
destroyOnHidden
|
|
>
|
|
<Form layout="vertical">
|
|
<Form.Item
|
|
label={t('pages.clients.group')}
|
|
tooltip={t('pages.clients.addToGroupTooltip')}
|
|
>
|
|
<AutoComplete
|
|
value={value}
|
|
placeholder={t('pages.clients.groupName')}
|
|
options={groups.map((g) => ({ value: g }))}
|
|
onChange={(v) => setValue(v ?? '')}
|
|
allowClear
|
|
autoFocus
|
|
/>
|
|
</Form.Item>
|
|
</Form>
|
|
</Modal>
|
|
</>
|
|
);
|
|
}
|