mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-12 07:36:07 +00:00
ac89ec724f
Settings and Xray Configs are now expandable sidebar submenus that list their sections; clicking a section opens it via the URL hash (e.g. #general, #basic) and the in-page top tab bar is removed on both pages. Within each section the collapse groups become horizontal tabs, each with an icon; on mobile only the icon shows with the label in a tooltip, via a shared catTabLabel helper used by both settings and xray. Subscription Formats: the nested collapses in Fragment/Noises/Mux/Direct are replaced with a cleaner layout - framed field groups, and each noise is a card with a delete button plus a dashed add button. Xray: the Reset to Default button is now a solid danger button so its hover state is visible.
100 lines
4.5 KiB
TypeScript
100 lines
4.5 KiB
TypeScript
import { useMemo } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { Input, InputNumber, Select, Switch, Tabs } from 'antd';
|
|
import { BellOutlined, SettingOutlined } from '@ant-design/icons';
|
|
import { LanguageManager } from '@/utils';
|
|
import type { AllSetting } from '@/models/setting';
|
|
import { SettingListItem } from '@/components/ui';
|
|
import { useMediaQuery } from '@/hooks/useMediaQuery';
|
|
import { catTabLabel } from './catTabLabel';
|
|
|
|
interface TelegramTabProps {
|
|
allSetting: AllSetting;
|
|
updateSetting: (patch: Partial<AllSetting>) => void;
|
|
}
|
|
|
|
export default function TelegramTab({ allSetting, updateSetting }: TelegramTabProps) {
|
|
const { t } = useTranslation();
|
|
const { isMobile } = useMediaQuery();
|
|
|
|
const langOptions = useMemo(
|
|
() => LanguageManager.supportedLanguages.map((l: { value: string; name: string; icon: string }) => ({
|
|
value: l.value,
|
|
label: (
|
|
<>
|
|
<span role="img" aria-label={l.name}>{l.icon}</span>
|
|
<span>{l.name}</span>
|
|
</>
|
|
),
|
|
})),
|
|
[],
|
|
);
|
|
|
|
return (
|
|
<Tabs defaultActiveKey="1" items={[
|
|
{
|
|
key: '1',
|
|
label: catTabLabel(<SettingOutlined />, t('pages.settings.panelSettings'), isMobile),
|
|
children: (
|
|
<>
|
|
<SettingListItem paddings="small" title={t('pages.settings.telegramBotEnable')} description={t('pages.settings.telegramBotEnableDesc')}>
|
|
<Switch checked={allSetting.tgBotEnable} onChange={(v) => updateSetting({ tgBotEnable: v })} />
|
|
</SettingListItem>
|
|
|
|
<SettingListItem
|
|
paddings="small"
|
|
title={t('pages.settings.telegramToken')}
|
|
description={allSetting.hasTgBotToken ? 'Configured; leave blank to keep current token.' : t('pages.settings.telegramTokenDesc')}
|
|
>
|
|
<Input.Password
|
|
value={allSetting.tgBotToken}
|
|
placeholder={allSetting.hasTgBotToken ? 'Configured - enter a new token to replace' : ''}
|
|
onChange={(e) => updateSetting({ tgBotToken: e.target.value })}
|
|
/>
|
|
</SettingListItem>
|
|
|
|
<SettingListItem paddings="small" title={t('pages.settings.telegramChatId')} description={t('pages.settings.telegramChatIdDesc')}>
|
|
<Input value={allSetting.tgBotChatId} onChange={(e) => updateSetting({ tgBotChatId: e.target.value })} />
|
|
</SettingListItem>
|
|
|
|
<SettingListItem paddings="small" title={t('pages.settings.telegramBotLanguage')}>
|
|
<Select
|
|
value={allSetting.tgLang}
|
|
onChange={(v) => updateSetting({ tgLang: v })}
|
|
style={{ width: '100%' }}
|
|
options={langOptions}
|
|
/>
|
|
</SettingListItem>
|
|
|
|
<SettingListItem paddings="small" title={t('pages.settings.telegramAPIServer')} description={t('pages.settings.telegramAPIServerDesc')}>
|
|
<Input value={allSetting.tgBotAPIServer} placeholder="https://api.example.com"
|
|
onChange={(e) => updateSetting({ tgBotAPIServer: e.target.value })} />
|
|
</SettingListItem>
|
|
</>
|
|
),
|
|
},
|
|
{
|
|
key: '2',
|
|
label: catTabLabel(<BellOutlined />, t('pages.settings.notifications'), isMobile),
|
|
children: (
|
|
<>
|
|
<SettingListItem paddings="small" title={t('pages.settings.telegramNotifyTime')} description={t('pages.settings.telegramNotifyTimeDesc')}>
|
|
<Input value={allSetting.tgRunTime} onChange={(e) => updateSetting({ tgRunTime: e.target.value })} />
|
|
</SettingListItem>
|
|
<SettingListItem paddings="small" title={t('pages.settings.tgNotifyBackup')} description={t('pages.settings.tgNotifyBackupDesc')}>
|
|
<Switch checked={allSetting.tgBotBackup} onChange={(v) => updateSetting({ tgBotBackup: v })} />
|
|
</SettingListItem>
|
|
<SettingListItem paddings="small" title={t('pages.settings.tgNotifyLogin')} description={t('pages.settings.tgNotifyLoginDesc')}>
|
|
<Switch checked={allSetting.tgBotLoginNotify} onChange={(v) => updateSetting({ tgBotLoginNotify: v })} />
|
|
</SettingListItem>
|
|
<SettingListItem paddings="small" title={t('pages.settings.tgNotifyCpu')} description={t('pages.settings.tgNotifyCpuDesc')}>
|
|
<InputNumber value={allSetting.tgCpu} min={0} max={100} style={{ width: '100%' }}
|
|
onChange={(v) => updateSetting({ tgCpu: Number(v) || 0 })} />
|
|
</SettingListItem>
|
|
</>
|
|
),
|
|
},
|
|
]} />
|
|
);
|
|
}
|