keywrods library fixes
This commit is contained in:
@@ -25,6 +25,8 @@ import {
|
||||
fetchSectorStats,
|
||||
SectorStats,
|
||||
SectorStatsItem,
|
||||
fetchKeywordsLibraryFilterOptions,
|
||||
FilterOption,
|
||||
} from '../../services/api';
|
||||
import Badge from '../../components/ui/badge/Badge';
|
||||
import { BoltIcon, ShootingStarIcon } from '../../icons';
|
||||
@@ -41,7 +43,7 @@ import Label from '../../components/form/Label';
|
||||
import Input from '../../components/form/input/InputField';
|
||||
import { Card } from '../../components/ui/card';
|
||||
import { SectorMetricGrid, StatType } from '../../components/keywords-library/SectorMetricCard';
|
||||
import SmartSuggestions, { buildSmartSuggestions } from '../../components/keywords-library/SmartSuggestions';
|
||||
import SmartSuggestions from '../../components/keywords-library/SmartSuggestions';
|
||||
import SectorCardsGrid from '../../components/keywords-library/SectorCardsGrid';
|
||||
import BulkAddConfirmation from '../../components/keywords-library/BulkAddConfirmation';
|
||||
|
||||
@@ -72,9 +74,7 @@ export default function IndustriesSectorsKeywords() {
|
||||
const [bulkAddKeywordIds, setBulkAddKeywordIds] = useState<number[]>([]);
|
||||
const [bulkAddStatLabel, setBulkAddStatLabel] = useState<string | undefined>();
|
||||
const [pendingBulkAddKey, setPendingBulkAddKey] = useState<string | null>(null);
|
||||
const [pendingBulkAddGroup, setPendingBulkAddGroup] = useState<'stat' | 'suggestion' | null>(null);
|
||||
const [addedStatActions, setAddedStatActions] = useState<Set<string>>(new Set());
|
||||
const [addedSuggestionActions, setAddedSuggestionActions] = useState<Set<string>>(new Set());
|
||||
|
||||
// Ahrefs banner state
|
||||
const [showAhrefsBanner, setShowAhrefsBanner] = useState(true);
|
||||
@@ -95,6 +95,10 @@ export default function IndustriesSectorsKeywords() {
|
||||
const [showNotAddedOnly, setShowNotAddedOnly] = useState(false);
|
||||
const [volumeMin, setVolumeMin] = useState('');
|
||||
const [volumeMax, setVolumeMax] = useState('');
|
||||
|
||||
// Dynamic filter options (cascading)
|
||||
const [countryOptions, setCountryOptions] = useState<FilterOption[] | undefined>(undefined);
|
||||
const [difficultyOptions, setDifficultyOptions] = useState<FilterOption[] | undefined>(undefined);
|
||||
|
||||
// Keyword count tracking
|
||||
const [addedCount, setAddedCount] = useState(0);
|
||||
@@ -267,7 +271,6 @@ export default function IndustriesSectorsKeywords() {
|
||||
setCurrentPage(1);
|
||||
setSelectedIds([]);
|
||||
setAddedStatActions(new Set());
|
||||
setAddedSuggestionActions(new Set());
|
||||
}, [activeSite?.id]);
|
||||
|
||||
// Reset pagination/selection when sector changes
|
||||
@@ -275,8 +278,44 @@ export default function IndustriesSectorsKeywords() {
|
||||
setActiveStatFilter(null);
|
||||
setCurrentPage(1);
|
||||
setSelectedIds([]);
|
||||
setAddedStatActions(new Set());
|
||||
}, [activeSector?.id]);
|
||||
|
||||
// Load cascading filter options based on current filters
|
||||
const loadFilterOptions = useCallback(async () => {
|
||||
if (!activeSite?.industry) return;
|
||||
|
||||
const difficultyLabel = difficultyFilter ? getDifficultyLabelFromNumber(parseInt(difficultyFilter, 10)) : null;
|
||||
const difficultyRange = difficultyLabel ? getDifficultyRange(difficultyLabel) : null;
|
||||
|
||||
try {
|
||||
const options = await fetchKeywordsLibraryFilterOptions({
|
||||
industry_id: activeSite.industry,
|
||||
sector_id: activeSector?.industry_sector || undefined,
|
||||
country: countryFilter || undefined,
|
||||
difficulty_min: difficultyRange?.min,
|
||||
difficulty_max: difficultyRange?.max,
|
||||
volume_min: volumeMin ? Number(volumeMin) : undefined,
|
||||
volume_max: volumeMax ? Number(volumeMax) : undefined,
|
||||
search: searchTerm || undefined,
|
||||
});
|
||||
|
||||
setCountryOptions(options.countries || []);
|
||||
setDifficultyOptions(
|
||||
(options.difficulty?.levels || []).map((level) => ({
|
||||
value: String(level.level),
|
||||
label: `${level.level} - ${level.label}`,
|
||||
}))
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Failed to load filter options:', error);
|
||||
}
|
||||
}, [activeSite?.industry, activeSector?.industry_sector, countryFilter, difficultyFilter, volumeMin, volumeMax, searchTerm]);
|
||||
|
||||
useEffect(() => {
|
||||
loadFilterOptions();
|
||||
}, [loadFilterOptions]);
|
||||
|
||||
// Load counts on mount and when site/sector changes
|
||||
useEffect(() => {
|
||||
if (activeSite) {
|
||||
@@ -297,31 +336,39 @@ export default function IndustriesSectorsKeywords() {
|
||||
setShowContent(false);
|
||||
|
||||
try {
|
||||
// Get already-attached keywords for marking (lightweight check)
|
||||
// Get already-attached keywords for marking (paginate to ensure persistence)
|
||||
const attachedSeedKeywordIds = new Set<number>();
|
||||
try {
|
||||
const sectors = await fetchSiteSectors(activeSite.id);
|
||||
|
||||
// Check keywords in all sectors (needed for isAdded flag)
|
||||
for (const sector of sectors) {
|
||||
try {
|
||||
const keywordsData = await fetchKeywords({
|
||||
site_id: activeSite.id,
|
||||
sector_id: sector.id,
|
||||
page_size: 1000,
|
||||
});
|
||||
(keywordsData.results || []).forEach((k: any) => {
|
||||
const seedKeywordId = k.seed_keyword_id || (k.seed_keyword && k.seed_keyword.id);
|
||||
if (seedKeywordId) {
|
||||
attachedSeedKeywordIds.add(Number(seedKeywordId));
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.warn(`Could not fetch attached keywords for sector ${sector.id}:`, err);
|
||||
const fetchAttachedSeedKeywordIds = async (siteId: number, sectorId?: number) => {
|
||||
const pageSize = 500;
|
||||
let page = 1;
|
||||
while (true) {
|
||||
const keywordsData = await fetchKeywords({
|
||||
site_id: siteId,
|
||||
sector_id: sectorId,
|
||||
page,
|
||||
page_size: pageSize,
|
||||
});
|
||||
(keywordsData.results || []).forEach((k: any) => {
|
||||
const seedKeywordId = k.seed_keyword_id || (k.seed_keyword && k.seed_keyword.id);
|
||||
if (seedKeywordId) {
|
||||
attachedSeedKeywordIds.add(Number(seedKeywordId));
|
||||
}
|
||||
});
|
||||
if (!keywordsData.next || (keywordsData.results || []).length < pageSize) {
|
||||
break;
|
||||
}
|
||||
page += 1;
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
if (activeSector?.id) {
|
||||
await fetchAttachedSeedKeywordIds(activeSite.id, activeSector.id);
|
||||
} else {
|
||||
await fetchAttachedSeedKeywordIds(activeSite.id);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('Could not fetch sectors or attached keywords:', err);
|
||||
console.warn('Could not fetch attached keywords:', err);
|
||||
}
|
||||
|
||||
// Keep attached IDs available for bulk add actions
|
||||
@@ -342,8 +389,24 @@ export default function IndustriesSectorsKeywords() {
|
||||
|
||||
if (searchTerm) filters.search = searchTerm;
|
||||
if (countryFilter) filters.country = countryFilter;
|
||||
if (volumeMin) filters.volume_min = parseInt(volumeMin);
|
||||
if (volumeMax) filters.volume_max = parseInt(volumeMax);
|
||||
if (volumeMin !== '') {
|
||||
const parsed = Number(volumeMin);
|
||||
if (!Number.isNaN(parsed)) {
|
||||
filters.volume_min = parsed;
|
||||
}
|
||||
}
|
||||
if (volumeMax !== '') {
|
||||
const parsed = Number(volumeMax);
|
||||
if (!Number.isNaN(parsed)) {
|
||||
filters.volume_max = parsed;
|
||||
}
|
||||
}
|
||||
|
||||
const useServerAvailableFilter = Boolean(showNotAddedOnly && activeSite?.id);
|
||||
if (useServerAvailableFilter) {
|
||||
filters.site_id = activeSite.id;
|
||||
filters.available_only = true;
|
||||
}
|
||||
|
||||
// Apply difficulty filter (if API supports it, otherwise we'll filter client-side)
|
||||
if (difficultyFilter) {
|
||||
@@ -386,15 +449,19 @@ export default function IndustriesSectorsKeywords() {
|
||||
setAddedCount(totalAdded);
|
||||
setAvailableCount(actualAvailable);
|
||||
|
||||
// Apply "not yet added" filter client-side (if API doesn't support it)
|
||||
// Apply "not yet added" filter client-side only when server filtering isn't used
|
||||
let filteredResults = results;
|
||||
if (showNotAddedOnly) {
|
||||
if (showNotAddedOnly && !useServerAvailableFilter) {
|
||||
filteredResults = results.filter(sk => !sk.isAdded);
|
||||
}
|
||||
|
||||
const effectiveTotalCount = useServerAvailableFilter
|
||||
? apiTotalCount
|
||||
: (showNotAddedOnly && activeSite ? Math.max(apiTotalCount - attachedSeedKeywordIds.size, 0) : apiTotalCount);
|
||||
|
||||
setSeedKeywords(filteredResults);
|
||||
setTotalCount(apiTotalCount);
|
||||
setTotalPages(Math.ceil(apiTotalCount / pageSizeNum));
|
||||
setTotalCount(effectiveTotalCount);
|
||||
setTotalPages(Math.ceil(effectiveTotalCount / pageSizeNum));
|
||||
|
||||
setShowContent(true);
|
||||
} catch (error: any) {
|
||||
@@ -409,6 +476,42 @@ export default function IndustriesSectorsKeywords() {
|
||||
}
|
||||
}, [activeSite, activeSector, currentPage, pageSize, searchTerm, countryFilter, volumeMin, volumeMax, difficultyFilter, showNotAddedOnly, sortBy, sortDirection, toast]);
|
||||
|
||||
const getAddedStatStorageKey = useCallback(() => {
|
||||
if (!activeSite?.id) return null;
|
||||
const sectorKey = activeSector?.id ? `sector-${activeSector.id}` : 'sector-all';
|
||||
return `keywordsLibrary:addedStatActions:${activeSite.id}:${sectorKey}`;
|
||||
}, [activeSite?.id, activeSector?.id]);
|
||||
|
||||
useEffect(() => {
|
||||
const storageKey = getAddedStatStorageKey();
|
||||
if (!storageKey) {
|
||||
setAddedStatActions(new Set());
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const raw = localStorage.getItem(storageKey);
|
||||
if (raw) {
|
||||
const parsed = JSON.parse(raw) as string[];
|
||||
setAddedStatActions(new Set(parsed));
|
||||
} else {
|
||||
setAddedStatActions(new Set());
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to load added stat actions:', error);
|
||||
setAddedStatActions(new Set());
|
||||
}
|
||||
}, [getAddedStatStorageKey]);
|
||||
|
||||
useEffect(() => {
|
||||
const storageKey = getAddedStatStorageKey();
|
||||
if (!storageKey) return;
|
||||
try {
|
||||
localStorage.setItem(storageKey, JSON.stringify(Array.from(addedStatActions)));
|
||||
} catch (error) {
|
||||
console.warn('Failed to persist added stat actions:', error);
|
||||
}
|
||||
}, [addedStatActions, getAddedStatStorageKey]);
|
||||
|
||||
// Load data when site/sector/filters change (show table by default per plan)
|
||||
useEffect(() => {
|
||||
if (activeSite) {
|
||||
@@ -621,6 +724,32 @@ export default function IndustriesSectorsKeywords() {
|
||||
const pageConfig = useMemo(() => {
|
||||
const showSectorColumn = !activeSector;
|
||||
|
||||
const defaultCountryOptions: FilterOption[] = [
|
||||
{ value: 'US', label: 'United States' },
|
||||
{ value: 'CA', label: 'Canada' },
|
||||
{ value: 'GB', label: 'United Kingdom' },
|
||||
{ value: 'AE', label: 'United Arab Emirates' },
|
||||
{ value: 'AU', label: 'Australia' },
|
||||
{ value: 'IN', label: 'India' },
|
||||
{ value: 'PK', label: 'Pakistan' },
|
||||
];
|
||||
|
||||
const countryFilterOptions = countryOptions && countryOptions.length > 0
|
||||
? countryOptions
|
||||
: defaultCountryOptions;
|
||||
|
||||
const defaultDifficultyOptions: FilterOption[] = [
|
||||
{ value: '1', label: '1 - Very Easy' },
|
||||
{ value: '2', label: '2 - Easy' },
|
||||
{ value: '3', label: '3 - Medium' },
|
||||
{ value: '4', label: '4 - Hard' },
|
||||
{ value: '5', label: '5 - Very Hard' },
|
||||
];
|
||||
|
||||
const difficultyFilterOptions = difficultyOptions && difficultyOptions.length > 0
|
||||
? difficultyOptions
|
||||
: defaultDifficultyOptions;
|
||||
|
||||
return {
|
||||
columns: [
|
||||
{
|
||||
@@ -782,13 +911,7 @@ export default function IndustriesSectorsKeywords() {
|
||||
type: 'select' as const,
|
||||
options: [
|
||||
{ value: '', label: 'All Countries' },
|
||||
{ value: 'US', label: 'United States' },
|
||||
{ value: 'CA', label: 'Canada' },
|
||||
{ value: 'GB', label: 'United Kingdom' },
|
||||
{ value: 'AE', label: 'United Arab Emirates' },
|
||||
{ value: 'AU', label: 'Australia' },
|
||||
{ value: 'IN', label: 'India' },
|
||||
{ value: 'PK', label: 'Pakistan' },
|
||||
...countryFilterOptions,
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -797,11 +920,7 @@ export default function IndustriesSectorsKeywords() {
|
||||
type: 'select' as const,
|
||||
options: [
|
||||
{ value: '', label: 'All Difficulty' },
|
||||
{ value: '1', label: '1 - Very Easy' },
|
||||
{ value: '2', label: '2 - Easy' },
|
||||
{ value: '3', label: '3 - Medium' },
|
||||
{ value: '4', label: '4 - Hard' },
|
||||
{ value: '5', label: '5 - Very Hard' },
|
||||
...difficultyFilterOptions,
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -822,13 +941,7 @@ export default function IndustriesSectorsKeywords() {
|
||||
},
|
||||
],
|
||||
};
|
||||
}, [activeSector, handleAddToWorkflow, sectors]);
|
||||
|
||||
// Build smart suggestions from sector stats
|
||||
const smartSuggestions = useMemo(() => {
|
||||
if (!sectorStats) return [];
|
||||
return buildSmartSuggestions(sectorStats, { showOnlyWithResults: true });
|
||||
}, [sectorStats]);
|
||||
}, [activeSector, handleAddToWorkflow, sectors, countryOptions, difficultyOptions, volumeMin, volumeMax]);
|
||||
|
||||
// Helper: word count for keyword string
|
||||
const getWordCount = useCallback((keyword: string) => {
|
||||
@@ -839,18 +952,10 @@ export default function IndustriesSectorsKeywords() {
|
||||
return `${statType}:${count}`;
|
||||
}, []);
|
||||
|
||||
const buildSuggestionActionKey = useCallback((suggestionId: string, count: number) => {
|
||||
return `${suggestionId}:${count}`;
|
||||
}, []);
|
||||
|
||||
const isStatActionAdded = useCallback((statType: StatType, count: number) => {
|
||||
return addedStatActions.has(buildStatActionKey(statType, count));
|
||||
}, [addedStatActions, buildStatActionKey]);
|
||||
|
||||
const isSuggestionActionAdded = useCallback((suggestionId: string, count: number) => {
|
||||
return addedSuggestionActions.has(buildSuggestionActionKey(suggestionId, count));
|
||||
}, [addedSuggestionActions, buildSuggestionActionKey]);
|
||||
|
||||
const fetchBulkKeywords = useCallback(async (options: {
|
||||
ordering: string;
|
||||
difficultyMax?: number;
|
||||
@@ -900,7 +1005,6 @@ export default function IndustriesSectorsKeywords() {
|
||||
label: string;
|
||||
ids: number[];
|
||||
actionKey: string;
|
||||
group: 'stat' | 'suggestion';
|
||||
}) => {
|
||||
if (payload.ids.length === 0) {
|
||||
toast.error('No matching keywords found for this selection');
|
||||
@@ -910,7 +1014,6 @@ export default function IndustriesSectorsKeywords() {
|
||||
setBulkAddKeywordIds(payload.ids);
|
||||
setBulkAddStatLabel(payload.label);
|
||||
setPendingBulkAddKey(payload.actionKey);
|
||||
setPendingBulkAddGroup(payload.group);
|
||||
setShowBulkAddModal(true);
|
||||
}, [toast]);
|
||||
|
||||
@@ -985,48 +1088,6 @@ export default function IndustriesSectorsKeywords() {
|
||||
}
|
||||
}, [activeStatFilter, sectorStats]);
|
||||
|
||||
const handleSuggestionClick = useCallback((suggestion: any) => {
|
||||
setActiveStatFilter(null);
|
||||
setCurrentPage(1);
|
||||
setSelectedIds([]);
|
||||
|
||||
const difficultyMax = suggestion.filterParams?.difficulty_max;
|
||||
const volumeMinValue = suggestion.filterParams?.volume_min;
|
||||
const availableOnly = Boolean(suggestion.filterParams?.available_only);
|
||||
|
||||
if (availableOnly) {
|
||||
setShowNotAddedOnly(true);
|
||||
} else {
|
||||
setShowNotAddedOnly(false);
|
||||
}
|
||||
|
||||
if (volumeMinValue) {
|
||||
setVolumeMin(String(volumeMinValue));
|
||||
} else {
|
||||
setVolumeMin('');
|
||||
}
|
||||
setVolumeMax('');
|
||||
|
||||
if (difficultyMax !== undefined) {
|
||||
if (difficultyMax <= 20) {
|
||||
setDifficultyFilter('1');
|
||||
} else if (difficultyMax <= 40) {
|
||||
setDifficultyFilter('2');
|
||||
} else {
|
||||
setDifficultyFilter('');
|
||||
}
|
||||
} else {
|
||||
setDifficultyFilter('');
|
||||
}
|
||||
|
||||
if (suggestion.id === 'quick_wins') {
|
||||
setSortBy('difficulty');
|
||||
setSortDirection('asc');
|
||||
} else {
|
||||
setSortBy('volume');
|
||||
setSortDirection('desc');
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Handle sector card click
|
||||
const handleSectorSelect = useCallback((sector: Sector | null) => {
|
||||
@@ -1117,74 +1178,9 @@ export default function IndustriesSectorsKeywords() {
|
||||
label: statLabelMap[statType],
|
||||
ids,
|
||||
actionKey,
|
||||
group: 'stat',
|
||||
});
|
||||
}, [activeSite, activeSector, addedStatActions, buildStatActionKey, fetchBulkKeywords, prepareBulkAdd, sectorStats, toast]);
|
||||
|
||||
// Handle bulk add from suggestions
|
||||
const handleSuggestionBulkAdd = useCallback(async (suggestion: any, count: number) => {
|
||||
if (!activeSite || !activeSector?.industry_sector) {
|
||||
toast.error('Please select a site and sector first');
|
||||
return;
|
||||
}
|
||||
|
||||
const actionKey = buildSuggestionActionKey(suggestion.id, count);
|
||||
if (addedSuggestionActions.has(actionKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const suggestionThresholds = {
|
||||
quick_wins: sectorStats?.quick_wins.threshold ?? 1000,
|
||||
long_tail: sectorStats?.long_tail.threshold ?? 1000,
|
||||
premium_traffic: sectorStats?.premium_traffic.threshold ?? 50000,
|
||||
};
|
||||
|
||||
let ids: number[] = [];
|
||||
if (suggestion.id === 'quick_wins') {
|
||||
ids = await fetchBulkKeywords({
|
||||
ordering: 'difficulty',
|
||||
difficultyMax: 20,
|
||||
minVolume: suggestionThresholds.quick_wins,
|
||||
availableOnly: true,
|
||||
count,
|
||||
});
|
||||
} else if (suggestion.id === 'long_tail') {
|
||||
ids = await fetchBulkKeywords({
|
||||
ordering: '-volume',
|
||||
minVolume: suggestionThresholds.long_tail,
|
||||
longTail: true,
|
||||
availableOnly: true,
|
||||
count,
|
||||
});
|
||||
} else if (suggestion.id === 'premium_traffic') {
|
||||
ids = await fetchBulkKeywords({
|
||||
ordering: '-volume',
|
||||
minVolume: suggestionThresholds.premium_traffic,
|
||||
availableOnly: true,
|
||||
count,
|
||||
});
|
||||
} else if (suggestion.id === 'available') {
|
||||
ids = await fetchBulkKeywords({
|
||||
ordering: '-volume',
|
||||
availableOnly: true,
|
||||
count,
|
||||
});
|
||||
} else {
|
||||
ids = await fetchBulkKeywords({
|
||||
ordering: '-volume',
|
||||
availableOnly: true,
|
||||
count,
|
||||
});
|
||||
}
|
||||
|
||||
await prepareBulkAdd({
|
||||
label: suggestion.label,
|
||||
ids,
|
||||
actionKey,
|
||||
group: 'suggestion',
|
||||
});
|
||||
}, [activeSite, activeSector, addedSuggestionActions, buildSuggestionActionKey, fetchBulkKeywords, prepareBulkAdd, sectorStats, toast]);
|
||||
|
||||
const handleConfirmBulkAdd = useCallback(async () => {
|
||||
if (!activeSite || !activeSector) {
|
||||
throw new Error('Please select a site and sector first');
|
||||
@@ -1206,16 +1202,10 @@ export default function IndustriesSectorsKeywords() {
|
||||
}
|
||||
|
||||
if (pendingBulkAddKey) {
|
||||
if (pendingBulkAddGroup === 'stat') {
|
||||
setAddedStatActions((prev) => new Set([...prev, pendingBulkAddKey]));
|
||||
}
|
||||
if (pendingBulkAddGroup === 'suggestion') {
|
||||
setAddedSuggestionActions((prev) => new Set([...prev, pendingBulkAddKey]));
|
||||
}
|
||||
setAddedStatActions((prev) => new Set([...prev, pendingBulkAddKey]));
|
||||
}
|
||||
|
||||
setPendingBulkAddKey(null);
|
||||
setPendingBulkAddGroup(null);
|
||||
setShowBulkAddModal(false);
|
||||
|
||||
if (activeSite) {
|
||||
@@ -1229,7 +1219,7 @@ export default function IndustriesSectorsKeywords() {
|
||||
skipped: result.skipped || 0,
|
||||
total_requested: bulkAddKeywordIds.length,
|
||||
};
|
||||
}, [activeSite, activeSector, bulkAddKeywordIds, loadKeywordCounts, loadSectorStats, loadSeedKeywords, pendingBulkAddGroup, pendingBulkAddKey]);
|
||||
}, [activeSite, activeSector, bulkAddKeywordIds, loadKeywordCounts, loadSectorStats, loadSeedKeywords, pendingBulkAddKey]);
|
||||
|
||||
// Show WorkflowGuide if no sites
|
||||
if (sites.length === 0) {
|
||||
@@ -1269,33 +1259,21 @@ export default function IndustriesSectorsKeywords() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Sector Metric Cards - Show when site is selected */}
|
||||
{activeSite && (
|
||||
<div className="mx-6 mt-6">
|
||||
<SectorMetricGrid
|
||||
stats={sectorStats}
|
||||
activeStatType={activeStatFilter}
|
||||
onStatClick={handleStatClick}
|
||||
onBulkAdd={activeSector ? handleMetricBulkAdd : undefined}
|
||||
isAddedAction={isStatActionAdded}
|
||||
clickable={true}
|
||||
sectorName={activeSector?.name}
|
||||
isLoading={loadingSectorStats}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Smart Suggestions Panel - Always show when site is selected */}
|
||||
{activeSite && sectorStats && (
|
||||
<div className="mx-6 mt-6">
|
||||
<SmartSuggestions
|
||||
suggestions={smartSuggestions}
|
||||
onSuggestionClick={handleSuggestionClick}
|
||||
onBulkAdd={activeSector ? handleSuggestionBulkAdd : undefined}
|
||||
isAddedAction={isSuggestionActionAdded}
|
||||
enableFilterClick={true}
|
||||
isLoading={loadingSectorStats}
|
||||
/>
|
||||
<SmartSuggestions isLoading={loadingSectorStats}>
|
||||
<SectorMetricGrid
|
||||
stats={sectorStats}
|
||||
activeStatType={activeStatFilter}
|
||||
onStatClick={handleStatClick}
|
||||
onBulkAdd={activeSector ? handleMetricBulkAdd : undefined}
|
||||
isAddedAction={isStatActionAdded}
|
||||
clickable={true}
|
||||
sectorName={activeSector?.name}
|
||||
isLoading={false}
|
||||
/>
|
||||
</SmartSuggestions>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1512,7 +1490,6 @@ export default function IndustriesSectorsKeywords() {
|
||||
setBulkAddKeywordIds([]);
|
||||
setBulkAddStatLabel(undefined);
|
||||
setPendingBulkAddKey(null);
|
||||
setPendingBulkAddGroup(null);
|
||||
}}
|
||||
onConfirm={handleConfirmBulkAdd}
|
||||
keywordCount={bulkAddKeywordIds.length}
|
||||
|
||||
Reference in New Issue
Block a user