/** * @file SmsCityRulesPanel.jsx * @description Управление SMS-отправкой по городам. * Админ может: * - Включить/выключить SMS для города × кампания (постоянно) * - Указать период (с/по дату) — временно * - Добавить комментарий * - «Все города» (*) или «Все кампании» (*) — массовое правило */ import React, { useState, useEffect, useCallback } from "react"; import { Panel } from "../UI/Panel"; import { supabase } from "../../supabaseClient"; import { CRIMEAN_CITIES } from "../../constants/cities.js"; const CAMPAIGN_LABELS = { first_sms: "1-е SMS", second_sms: "2-е SMS", paid_storage: "Платное хранение", "*": "Все кампании", }; const CITY_ALL = "*"; export const SmsCityRulesPanel = () => { const [rules, setRules] = useState([]); const [loading, setLoading] = useState(true); const [showForm, setShowForm] = useState(false); const [saving, setSaving] = useState(false); const [message, setMessage] = useState(""); // Form state const [formCity, setFormCity] = useState("Ялта"); const [formCampaign, setFormCampaign] = useState("*"); const [formEnabled, setFormEnabled] = useState(false); const [formFrom, setFormFrom] = useState(""); const [formUntil, setFormUntil] = useState(""); const [formNote, setFormNote] = useState(""); const fetchRules = useCallback(async () => { setLoading(true); try { const { data, error } = await supabase .from("sms_city_rules") .select("*") .order("city", { ascending: true }) .order("campaign_type", { ascending: true }); if (error) throw error; setRules(data || []); } catch (e) { console.error("fetch sms_city_rules error", e); } finally { setLoading(false); } }, []); useEffect(() => { fetchRules(); }, [fetchRules]); const handleSave = async () => { setSaving(true); try { const { error } = await supabase.from("sms_city_rules").insert({ city: formCity, campaign_type: formCampaign, enabled: formEnabled, valid_from: formFrom || null, valid_until: formUntil || null, note: formNote || "", }); if (error) throw error; setShowForm(false); setFormNote(""); setFormFrom(""); setFormUntil(""); setMessage("✅ Правило добавлено"); fetchRules(); setTimeout(() => setMessage(""), 3000); } catch (e) { setMessage("❌ Ошибка: " + e.message); } finally { setSaving(false); } }; const handleToggle = async (rule) => { try { const { error } = await supabase .from("sms_city_rules") .update({ enabled: !rule.enabled }) .eq("id", rule.id); if (error) throw error; fetchRules(); } catch (e) { console.error("toggle error", e); } }; const handleDelete = async (id) => { try { const { error } = await supabase .from("sms_city_rules") .delete() .eq("id", id); if (error) throw error; fetchRules(); } catch (e) { console.error("delete error", e); } }; const fmtDate = (d) => { if (!d) return "—"; try { return new Date(d).toLocaleDateString("ru-RU", { day: "2-digit", month: "short", year: "numeric" }); } catch { return d; } }; return (
Управление отправкой SMS по городам и кампаниям. Выключенное правило = SMS не отправляется.
Пустые даты = правило действует постоянно. Указав даты, можно временно отключить SMS на период.
Загрузка...
) : rules.length === 0 ? (Правил пока нет. SMS отправляются во все города.
Нажмите «+ Правило» чтобы отключить SMS для конкретного города.