'use client';
import React, { useMemo, useState } from 'react';
import { SettingsCards } from '../settings/SettingsCard';
import { Input } from '@/components/ui/inputs';
import { Button } from '@/components/ui/buttons';
import { Text } from '@/components/ui/typography';
import { Plus, Dots, Trash } from '@/components/ui/icons';
import { useBusterNotifications } from '@/context/BusterNotifications';
import { Dropdown } from '@/components/ui/dropdown';
import {
useGetApprovedDomains,
useAddApprovedDomain,
useRemoveApprovedDomain
} from '@/api/buster_rest/security/queryRequests';
import pluralize from 'pluralize';
import { useMemoizedFn } from '@/hooks';
import { formatDate } from '@/lib/date';
interface ApprovedDomain {
domain: string;
created_at: string;
}
export const ApprovedEmailDomains = React.memo(() => {
const { data: approvedDomains = [] } = useGetApprovedDomains();
const { mutateAsync: removeDomain } = useRemoveApprovedDomain();
const domainCount = approvedDomains.length;
const [isEnabledAddDomain, setIsEnabledAddDomain] = useState(false);
const { openInfoMessage, openErrorMessage } = useBusterNotifications();
const countText = pluralize('approved email domain', domainCount, true);
const handleRemoveDomain = useMemoizedFn(async (domain: string) => {
try {
await removeDomain({ domains: [domain] });
openInfoMessage('Domain removed successfully');
} catch (error) {
openErrorMessage('Failed to remove domain');
}
});
const sections = useMemo(
() =>
[
// Header section with count and add button
{countText}
,
// Add domain input section (when adding)
isEnabledAddDomain && (
),
// Domain list sections
...approvedDomains.map((domainData) => (
))
].filter(Boolean),
[countText, isEnabledAddDomain, approvedDomains, handleRemoveDomain]
);
return (
);
});
ApprovedEmailDomains.displayName = 'ApprovedEmailDomains';
const AddDomainInput = React.memo(
({ setIsEnabledAddDomain }: { setIsEnabledAddDomain: (isEnabledAddDomain: boolean) => void }) => {
const { mutateAsync: addDomain } = useAddApprovedDomain();
const { openInfoMessage, openErrorMessage } = useBusterNotifications();
const [newDomain, setNewDomain] = useState('');
const handleAddDomain = useMemoizedFn(async () => {
const domain = newDomain.trim();
if (!domain) return;
const domainRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]\.[a-zA-Z]{2,}$/;
if (!domainRegex.test(domain)) {
openErrorMessage('Please enter a valid domain name');
return;
}
try {
await addDomain({ domains: [newDomain.trim()] });
setNewDomain('');
setIsEnabledAddDomain(false);
openInfoMessage('Domain added successfully');
} catch (error) {
openErrorMessage('Failed to add domain');
}
});
return (
setNewDomain(e.target.value)}
placeholder="Enter domain (e.g., company.com)"
onKeyDown={(e) => {
if (e.key === 'Enter') {
handleAddDomain();
} else if (e.key === 'Escape') {
setIsEnabledAddDomain(false);
setNewDomain('');
}
}}
autoFocus
/>
);
}
);
AddDomainInput.displayName = 'AddDomainInput';
const DomainListItem = React.memo<{
domainData: ApprovedDomain;
onRemove: (domain: string) => Promise;
}>(({ domainData, onRemove }) => {
const items = useMemo(
() => [
{
label: 'Remove domain',
value: 'remove',
icon: ,
onClick: () => onRemove(domainData.domain)
}
],
[domainData.domain, onRemove]
);
return (
{domainData.domain}
Added {formatDate({ date: domainData.created_at, format: 'LL' })}
} />
);
});
DomainListItem.displayName = 'DomainListItem';