'use client'; import { useId, useMemo } from 'react'; import { ResourceInput, SecondaryButton, } from '@/features/shared/components/resource-primitives'; function splitDomainRows(value: string) { const rows = value.split(/\r?\n/); return rows.length > 0 ? rows : ['']; } function buildSuggestionSources(domains: string[]) { const values = new Set(); for (const domain of domains) { const normalized = domain.trim().toLowerCase().replace(/^\*\./, ''); if (!normalized) { continue; } values.add(normalized); const segments = normalized.split('.'); for (let index = 1; index < segments.length - 1; index += 1) { values.add(segments.slice(index).join('.')); } } return Array.from(values); } function buildDomainSuggestions(input: string, sources: string[], rows: string[]) { const normalizedInput = input.trim().toLowerCase(); if (!normalizedInput) { return []; } const existingDomains = new Set( rows .map((row) => row.trim().toLowerCase()) .filter((row) => row && row !== normalizedInput), ); const suggestions: string[] = []; for (const source of sources) { if (source.startsWith(normalizedInput) && source !== normalizedInput) { suggestions.push(source); } const separatorIndex = normalizedInput.lastIndexOf('.'); if (separatorIndex <= 0) { continue; } const prefix = normalizedInput.slice(0, separatorIndex); const suffixInput = normalizedInput.slice(separatorIndex + 1); if (!suffixInput || source.startsWith(suffixInput)) { suggestions.push(`${prefix}.${source}`); } } return suggestions.filter((suggestion, index) => { return ( suggestion !== normalizedInput && !existingDomains.has(suggestion) && suggestions.indexOf(suggestion) === index ); }); } export function DomainListInput({ value, onChange, onBlur, suggestionSources = [], placeholder = 'app.example.com', }: { value: string; onChange: (value: string) => void; onBlur?: () => void; suggestionSources?: string[]; placeholder?: string; }) { const listId = useId(); const rows = splitDomainRows(value); const normalizedSources = useMemo( () => buildSuggestionSources(suggestionSources), [suggestionSources], ); const updateRows = (nextRows: string[]) => { onChange(nextRows.join('\n')); }; return (
{rows.map((row, index) => { const suggestions = buildDomainSuggestions(row, normalizedSources, rows).slice( 0, 4, ); return (
{ const nextRows = rows.slice(); nextRows[index] = event.target.value; updateRows(nextRows); }} /> {suggestions.map((suggestion) => (
{ const nextRows = rows.slice(); nextRows.splice(index + 1, 0, ''); updateRows(nextRows); }} > + { if (rows.length === 1) { updateRows(['']); return; } updateRows(rows.filter((_, rowIndex) => rowIndex !== index)); }} > -
{suggestions.length > 0 ? (
{suggestions.map((suggestion) => ( ))}
) : null}
); })}
); }