Refactor keyword handling: Replace 'intent' with 'country' across backend and frontend

- Updated AutomationService to include estimated_word_count.
- Increased stage_1_batch_size from 20 to 50 in AutomationViewSet.
- Changed Keywords model to replace 'intent' property with 'country'.
- Adjusted ClusteringService to allow a maximum of 50 keywords for clustering.
- Modified admin and management commands to remove 'intent' and use 'country' instead.
- Updated serializers to reflect the change from 'intent' to 'country'.
- Adjusted views and filters to use 'country' instead of 'intent'.
- Updated frontend forms, filters, and pages to replace 'intent' with 'country'.
- Added migration to remove 'intent' field and add 'country' field to SeedKeyword model.
This commit is contained in:
IGNY8 VPS (Salman)
2025-12-17 07:37:36 +00:00
parent 9f826c92f8
commit 7ad06c6227
30 changed files with 240 additions and 205 deletions

View File

@@ -55,16 +55,19 @@ export const getKeywordFormConfig = (options?: {
required: false,
},
{
key: 'intent',
label: 'Intent',
key: 'country',
label: 'Country',
type: 'select',
value: 'informational',
value: 'US',
onChange: () => {},
options: [
{ value: 'informational', label: 'Informational' },
{ value: 'transactional', label: 'Transactional' },
{ value: 'navigational', label: 'Navigational' },
{ value: 'commercial', label: 'Commercial' },
{ 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' },
],
required: false,
},

View File

@@ -161,7 +161,7 @@ export function useImportExport(
</p>
{filename === 'keywords' && (
<p className="text-xs text-gray-600 dark:text-gray-300 mt-2 p-2 bg-blue-50 dark:bg-blue-900/20 rounded border border-blue-200 dark:border-blue-800">
<strong>Expected columns:</strong> keyword, volume, difficulty, intent, status
<strong>Expected columns:</strong> keyword, volume, difficulty, country, status
</p>
)}
</div>

View File

@@ -11,7 +11,7 @@ import {
keywordColumn,
volumeColumn,
difficultyColumn,
intentColumn,
countryColumn,
clusterColumn,
sectorColumn,
statusColumn,
@@ -106,7 +106,7 @@ export const createKeywordsPageConfig = (
keyword?: string;
volume?: number | null;
difficulty?: number | null;
intent?: string;
country?: string;
cluster_id?: number | null;
status: string;
};
@@ -116,8 +116,8 @@ export const createKeywordsPageConfig = (
setSearchTerm: (value: string) => void;
statusFilter: string;
setStatusFilter: (value: string) => void;
intentFilter: string;
setIntentFilter: (value: string) => void;
countryFilter: string;
setCountryFilter: (value: string) => void;
difficultyFilter: string;
setDifficultyFilter: (value: string) => void;
clusterFilter: string;
@@ -197,28 +197,23 @@ export const createKeywordsPageConfig = (
},
},
{
...intentColumn,
sortable: false, // Backend doesn't support sorting by intent
sortField: 'seed_keyword__intent',
...countryColumn,
sortable: false, // Backend doesn't support sorting by country
sortField: 'seed_keyword__country',
render: (value: string) => {
// Map intent values to badge colors
// Transactional and Commercial → success (green, like active)
// Navigational → warning (amber/yellow, like pending)
// Informational → info (blue)
const getIntentColor = (intent: string) => {
const lowerIntent = intent?.toLowerCase() || '';
if (lowerIntent === 'transactional' || lowerIntent === 'commercial') {
return 'success'; // Green, like active status
} else if (lowerIntent === 'navigational') {
return 'warning'; // Amber/yellow, like pending status
}
return 'info'; // Blue for informational or default
const countryNames: Record<string, string> = {
'US': 'United States',
'CA': 'Canada',
'GB': 'United Kingdom',
'AE': 'United Arab Emirates',
'AU': 'Australia',
'IN': 'India',
'PK': 'Pakistan',
};
const properCase = value ? value.charAt(0).toUpperCase() + value.slice(1) : '-';
const displayName = countryNames[value] || value || '-';
return (
<Badge color={getIntentColor(value)} size="xs" variant="soft">
<span className="text-[11px] font-normal">{properCase}</span>
<Badge color="info" size="xs" variant="soft">
<span className="text-[11px] font-normal">{value || '-'}</span>
</Badge>
);
},
@@ -317,15 +312,18 @@ export const createKeywordsPageConfig = (
],
},
{
key: 'intent',
label: 'Intent',
key: 'country',
label: 'Country',
type: 'select',
options: [
{ value: '', label: 'All Intent' },
{ value: 'informational', label: 'Informational' },
{ value: 'navigational', label: 'Navigational' },
{ value: 'transactional', label: 'Transactional' },
{ value: 'commercial', label: 'Commercial' },
{ 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' },
],
},
{
@@ -541,18 +539,21 @@ export const createKeywordsPageConfig = (
max: 100,
},
{
key: 'intent',
label: 'Search Intent',
key: 'country',
label: 'Country',
type: 'select',
value: handlers.formData.intent || 'informational',
value: handlers.formData.country || 'US',
onChange: (value: any) =>
handlers.setFormData({ ...handlers.formData, intent: value }),
handlers.setFormData({ ...handlers.formData, country: value }),
required: true,
options: [
{ value: 'informational', label: 'Informational' },
{ value: 'navigational', label: 'Navigational' },
{ value: 'transactional', label: 'Transactional' },
{ value: 'commercial', label: 'Commercial' },
{ 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' },
],
},
{

View File

@@ -41,9 +41,9 @@ export const difficultyColumn = {
width: '120px',
};
export const intentColumn = {
key: 'intent',
label: 'Intent',
export const countryColumn = {
key: 'country',
label: 'Country',
sortable: true,
badge: true,
width: '120px',

View File

@@ -15,16 +15,19 @@ export const statusFilter = {
],
};
export const intentFilter = {
key: 'intent',
label: 'Intent',
export const countryFilter = {
key: 'country',
label: 'Country',
type: 'select',
options: [
{ value: '', label: 'All Intent' },
{ value: 'informational', label: 'Informational' },
{ value: 'transactional', label: 'Transactional' },
{ value: 'navigational', label: 'Navigational' },
{ value: 'commercial', label: 'Commercial' },
{ 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' },
],
};