'use client'; import { Loader2, Mail, MessageSquare, Save, Send, ToggleLeft, ToggleRight } from 'lucide-react'; import { useMemo, useState } from 'react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { PhoneInput, phoneCountries } from '@/components/ui/phone-input'; import { apiFetch, buildSystemSettingPayload, SystemSetting } from '@/lib/api'; import { getSettingMeta, isSettingVisible, MESSAGING_SETTING_KEYS } from '@/lib/system-settings-catalog'; function parseBoolean(value: string) { return ['true', '1', 'yes'].includes(value.trim().toLowerCase()); } interface MessagingSettingsSectionProps { settings: SystemSetting[]; token: string | null; savingKey: string | null; onUpdateValue: (key: string, value: string) => void; onSave: (setting: SystemSetting) => Promise; showToast: (message: string) => void; } function getSettingValue(settings: SystemSetting[], key: string) { return settings.find((item) => item.key === key)?.value ?? ''; } function shouldShowMessagingField(setting: SystemSetting, settings: SystemSetting[]) { if (!isSettingVisible(setting, settings)) return false; const provider = getSettingValue(settings, 'SMS_PROVIDER'); if (setting.key === 'SMS_API_KEY') return provider === 'smsru'; if (setting.key === 'SMS_LOGIN' || setting.key === 'SMS_PASSWORD') return provider === 'smsc'; const emailProvider = getSettingValue(settings, 'EMAIL_PROVIDER'); if (setting.key.startsWith('EMAIL_SMTP_') || setting.key.startsWith('EMAIL_FROM_')) { return parseBoolean(getSettingValue(settings, 'EMAIL_ENABLED')) && emailProvider === 'smtp'; } if (setting.key === 'EMAIL_PROVIDER') { return parseBoolean(getSettingValue(settings, 'EMAIL_ENABLED')); } if (setting.key === 'SMS_PROVIDER') { return parseBoolean(getSettingValue(settings, 'SMS_ENABLED')); } return true; } export function MessagingSettingsSection({ settings, token, savingKey, onUpdateValue, onSave, showToast }: MessagingSettingsSectionProps) { const [testEmail, setTestEmail] = useState(''); const [testPhone, setTestPhone] = useState(''); const [testPhoneCountry, setTestPhoneCountry] = useState(phoneCountries[0]); const [testingChannel, setTestingChannel] = useState<'email' | 'sms' | null>(null); const messagingSettings = useMemo( () => settings.filter((item) => MESSAGING_SETTING_KEYS.includes(item.key)), [settings] ); async function sendTest(channel: 'email' | 'sms') { if (!token) return; const target = channel === 'email' ? testEmail.trim() : `${testPhoneCountry.code}${testPhone}`; if (!target) { showToast(channel === 'email' ? 'Укажите email для теста' : 'Укажите номер телефона для теста'); return; } setTestingChannel(channel); try { const response = await apiFetch<{ message?: string }>( '/admin/settings/messaging/test', { method: 'POST', body: JSON.stringify({ channel, target }) }, token ); showToast(response.message ?? 'Тестовое сообщение отправлено'); } catch (error) { showToast(error instanceof Error ? error.message : 'Не удалось отправить тестовое сообщение'); } finally { setTestingChannel(null); } } const emailEnabled = parseBoolean(getSettingValue(messagingSettings, 'EMAIL_ENABLED')); const smsEnabled = parseBoolean(getSettingValue(messagingSettings, 'SMS_ENABLED')); return (

Email и SMS провайдеры

Настройте SMTP и SMS — OTP-коды при входе и регистрации будут отправляться автоматически.

{messagingSettings.filter((setting) => shouldShowMessagingField(setting, messagingSettings)).map((setting) => { const meta = getSettingMeta(setting.key); const label = meta?.label ?? setting.key; const type = meta?.type ?? 'text'; return (
{label}

{meta?.hint ?? setting.description ?? setting.key}

{type === 'boolean' ? ( ) : type === 'select' ? ( ) : (
onUpdateValue(setting.key, event.target.value)} /> {meta?.unit ? {meta.unit} : null}
)}
); })}
Тест email

{emailEnabled ? 'Отправит тестовый OTP-код через SMTP.' : 'Сначала включите Email и сохраните настройки SMTP.'}

setTestEmail(event.target.value)} />
Тест SMS

{smsEnabled ? 'Отправит тестовый OTP-код через SMS-провайдера.' : 'Сначала включите SMS и сохраните ключ API.'}

); }