"use client"; import { useState, useEffect, useRef, useMemo } from "react"; import { useTranslations } from "next-intl"; import { X, ShieldCheck, Search, Trash2, Plus } from "lucide-react"; import { Avatar } from "@/components/ui/avatar"; import { useSettingsStore } from "@/stores/settings-store"; import { cn } from "@/lib/utils"; interface TrustedSendersModalProps { isOpen: boolean; onClose: () => void; } export function TrustedSendersModal({ isOpen, onClose }: TrustedSendersModalProps) { const t = useTranslations("settings.email_behavior.trusted_senders"); const modalRef = useRef(null); const inputRef = useRef(null); const { trustedSenders, addTrustedSender, removeTrustedSender } = useSettingsStore(); const [searchQuery, setSearchQuery] = useState(""); const [isAdding, setIsAdding] = useState(false); const [newEmail, setNewEmail] = useState(""); const [emailError, setEmailError] = useState(""); // Filter senders based on search query const filteredSenders = useMemo(() => { if (!searchQuery.trim()) return trustedSenders; const query = searchQuery.toLowerCase(); return trustedSenders.filter((email) => email.toLowerCase().includes(query)); }, [trustedSenders, searchQuery]); // Show search only when 5+ senders const showSearch = trustedSenders.length >= 5; // Close on Escape key useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === "Escape") { if (isAdding) { setIsAdding(false); setNewEmail(""); setEmailError(""); } else { onClose(); } } }; if (isOpen) { window.addEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown); } }, [isOpen, isAdding, onClose]); // Close on click outside useEffect(() => { const handleClickOutside = (e: MouseEvent) => { if (modalRef.current && !modalRef.current.contains(e.target as Node)) { onClose(); } }; if (isOpen) { document.addEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside); } }, [isOpen, onClose]); // Focus input when adding mode is enabled useEffect(() => { if (isAdding && inputRef.current) { inputRef.current.focus(); } }, [isAdding]); // Reset state when modal closes useEffect(() => { if (!isOpen) { setSearchQuery(""); setIsAdding(false); setNewEmail(""); setEmailError(""); } }, [isOpen]); const validateEmail = (email: string): boolean => { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); }; const handleAddSender = () => { const trimmedEmail = newEmail.trim().toLowerCase(); if (!trimmedEmail) { setEmailError(t("invalid_email")); return; } if (!validateEmail(trimmedEmail)) { setEmailError(t("invalid_email")); return; } if (trustedSenders.includes(trimmedEmail)) { setEmailError(t("already_added")); return; } addTrustedSender(trimmedEmail); setNewEmail(""); setIsAdding(false); setEmailError(""); }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter") { handleAddSender(); } }; if (!isOpen) return null; return (
{/* Header */}

{t("modal_title")}

{/* Search (only when 5+ senders) */} {showSearch && (
setSearchQuery(e.target.value)} className="w-full pl-9 pr-3 py-2 text-sm bg-muted border border-border rounded-md focus:outline-none focus:ring-2 focus:ring-primary/50" />
)} {/* Content */}
{trustedSenders.length === 0 ? ( /* Empty State */

{t("empty_title")}

{t("empty_description")}

) : filteredSenders.length === 0 ? ( /* No search results */

{t("no_results")}

) : ( /* Sender list */
{filteredSenders.map((email) => (
{email}
))}
)}
{/* Footer - Add sender */} {trustedSenders.length > 0 && (
{isAdding ? (
{ setNewEmail(e.target.value); setEmailError(""); }} onKeyDown={handleKeyDown} className={cn( "flex-1 px-3 py-2 text-sm bg-background border rounded-md focus:outline-none focus:ring-2 focus:ring-primary/50", emailError ? "border-destructive" : "border-border" )} />
{emailError && (

{emailError}

)}
) : ( )}
)}
); }