import { useState, useEffect, useRef } from 'react'; import { useNavigate } from 'react-router'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { promoOffersApi, PromoOfferBroadcastRequest, TARGET_SEGMENTS, TargetSegment, OFFER_TYPE_CONFIG, OfferType, } from '../api/promoOffers'; import { adminUsersApi, UserListItem } from '../api/adminUsers'; import { AdminBackButton } from '../components/admin'; // Icons const SendIcon = () => ( ); const CheckIcon = () => ( ); const UsersIcon = () => ( ); const UserIcon = () => ( ); const SearchIcon = () => ( ); const CloseIcon = () => ( ); const getOfferTypeIcon = (offerType: string): string => { return OFFER_TYPE_CONFIG[offerType as OfferType]?.icon || '🎁'; }; export default function AdminPromoOfferSend() { const { t } = useTranslation(); const navigate = useNavigate(); const queryClient = useQueryClient(); const [selectedTemplateId, setSelectedTemplateId] = useState(null); const [sendMode, setSendMode] = useState<'segment' | 'user'>('segment'); const [selectedTarget, setSelectedTarget] = useState('active'); const [userId, setUserId] = useState(''); const [searchQuery, setSearchQuery] = useState(''); const [selectedUser, setSelectedUser] = useState(null); const [showDropdown, setShowDropdown] = useState(false); const searchRef = useRef(null); const [result, setResult] = useState<{ title: string; message: string; isSuccess: boolean; } | null>(null); // Query templates const { data: templatesData, isLoading } = useQuery({ queryKey: ['admin-promo-templates'], queryFn: promoOffersApi.getTemplates, }); const templates = templatesData?.items || []; const activeTemplates = templates.filter((t) => t.is_active); const selectedTemplate = templates.find((t) => t.id === selectedTemplateId); // Set default template when loaded if (!selectedTemplateId && activeTemplates.length > 0) { setSelectedTemplateId(activeTemplates[0].id); } // User search query with debounce const { data: searchResults, isFetching: isSearching } = useQuery({ queryKey: ['admin-users-search', searchQuery], queryFn: () => adminUsersApi.getUsers({ search: searchQuery, limit: 10 }), enabled: searchQuery.length >= 2 && sendMode === 'user', staleTime: 30000, }); // Filter users with telegram_id only const filteredUsers = (searchResults?.users || []).filter((u) => u.telegram_id); // Close dropdown on click outside useEffect(() => { const handleClickOutside = (e: MouseEvent) => { if (searchRef.current && !searchRef.current.contains(e.target as Node)) { setShowDropdown(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); // Handle user selection const handleSelectUser = (user: UserListItem) => { setSelectedUser(user); setUserId(user.telegram_id.toString()); setSearchQuery(''); setShowDropdown(false); }; // Clear selected user const handleClearUser = () => { setSelectedUser(null); setUserId(''); setSearchQuery(''); }; // Broadcast mutation const broadcastMutation = useMutation({ mutationFn: promoOffersApi.broadcastOffer, onSuccess: (data) => { queryClient.invalidateQueries({ queryKey: ['admin-promo-logs'] }); let message = t('admin.promoOffers.result.offersCreated', { count: data.created_offers }); if (data.notifications_sent > 0 || data.notifications_failed > 0) { message += '\n' + t('admin.promoOffers.result.notificationsSent', { count: data.notifications_sent }); if (data.notifications_failed > 0) { message += ' ' + t('admin.promoOffers.result.notificationsFailed', { count: data.notifications_failed, }); } } setResult({ title: t('admin.promoOffers.result.sentTitle'), message, isSuccess: true, }); }, onError: (error: unknown) => { const axiosErr = error as { response?: { data?: { detail?: string } } }; setResult({ title: t('common.error'), message: axiosErr.response?.data?.detail || t('admin.promoOffers.result.sendError'), isSuccess: false, }); }, }); const handleSubmit = () => { if (!selectedTemplateId || !selectedTemplate) return; const data: PromoOfferBroadcastRequest = { notification_type: selectedTemplate.offer_type, valid_hours: selectedTemplate.valid_hours, discount_percent: selectedTemplate.discount_percent, effect_type: selectedTemplate.offer_type === 'test_access' ? 'test_access' : 'percent_discount', extra_data: { template_id: selectedTemplate.id, active_discount_hours: selectedTemplate.active_discount_hours, test_duration_hours: selectedTemplate.test_duration_hours, test_squad_uuids: selectedTemplate.test_squad_uuids, }, send_notification: true, message_text: selectedTemplate.message_text, button_text: selectedTemplate.button_text, }; if (sendMode === 'user') { const id = parseInt(userId); if (!id) return; data.telegram_id = id; } else { data.target = selectedTarget; } broadcastMutation.mutate(data); }; const isValid = () => { if (!selectedTemplateId) return false; if (sendMode === 'user' && !userId.trim()) return false; return true; }; if (isLoading) { return (
); } // Result screen if (result) { return (
{result.isSuccess ? ( ) : ( )}

{result.title}

{result.message}

{result.isSuccess && ( )}
); } return (
{/* Header */}

{t('admin.promoOffers.send.title')}

{activeTemplates.length === 0 ? (

{t('admin.promoOffers.noActiveTemplates')}

) : (
{/* Template Selection */}
{activeTemplates.map((template) => ( ))}
{/* Send Mode */}
{sendMode === 'segment' ? ( ) : (
{selectedUser ? ( // Selected user display
{selectedUser.full_name || selectedUser.username || `ID: ${selectedUser.telegram_id}`}
{selectedUser.username && `@${selectedUser.username} · `} Telegram: {selectedUser.telegram_id}
) : ( // Search input <>
{ setSearchQuery(e.target.value); setShowDropdown(true); }} onFocus={() => setShowDropdown(true)} placeholder={t('admin.promoOffers.send.searchUserPlaceholder')} className="input pl-10" /> {isSearching && (
)}
{/* Dropdown results */} {showDropdown && searchQuery.length >= 2 && (
{filteredUsers.length > 0 ? ( filteredUsers.map((user) => ( )) ) : !isSearching ? (
{t('admin.promoOffers.send.noUsersFound')}
) : null}
)} )}
)}
{/* Preview */} {selectedTemplate && (

{t('admin.promoOffers.send.preview')}

{selectedTemplate.message_text}
{selectedTemplate.button_text}
)} {/* Actions */}
)}
); }