This commit is contained in:
IGNY8 VPS (Salman)
2025-11-29 07:20:26 +00:00
parent 341650bddc
commit 4bea79a76d
21 changed files with 443 additions and 1065 deletions

View File

@@ -118,8 +118,8 @@ export const createClustersPageConfig = (
...(showSectorColumn ? [{
...sectorColumn,
render: (value: string, row: Cluster) => (
<Badge color="info" size="sm" variant="light">
{row.sector_name || '-'}
<Badge color="info" size="xs" variant="soft">
<span className="text-[11px] font-normal">{row.sector_name || '-'}</span>
</Badge>
),
}] : []),
@@ -156,7 +156,6 @@ export const createClustersPageConfig = (
align: 'center' as const,
render: (value: number) => {
const difficultyNum = getDifficultyNumber(value);
const difficultyBadgeVariant = 'light';
const difficultyBadgeColor =
typeof difficultyNum === 'number' && difficultyNum === 1
? 'success'
@@ -170,12 +169,8 @@ export const createClustersPageConfig = (
? 'error'
: 'light';
return typeof difficultyNum === 'number' ? (
<Badge
color={difficultyBadgeColor}
variant={difficultyBadgeVariant}
size="sm"
>
{difficultyNum}
<Badge color={difficultyBadgeColor} variant="soft" size="xs">
<span className="text-[11px] font-normal">{difficultyNum}</span>
</Badge>
) : (
difficultyNum
@@ -194,14 +189,14 @@ export const createClustersPageConfig = (
...statusColumn,
sortable: true,
sortField: 'status',
render: (value: string) => (
<Badge
color={value === 'active' ? 'success' : 'warning'}
size="sm"
>
{value}
</Badge>
),
render: (value: string) => {
const properCase = value ? value.charAt(0).toUpperCase() + value.slice(1) : '-';
return (
<Badge color={value === 'active' ? 'success' : 'warning'} size="xs" variant="soft">
<span className="text-[11px] font-normal">{properCase}</span>
</Badge>
);
},
},
{
...createdColumn,

View File

@@ -82,7 +82,7 @@ export const createContentPageConfig = (
statusFilter: string;
setStatusFilter: (value: string) => void;
setCurrentPage: (page: number) => void;
onViewContent?: (row: Content) => void;
onRowClick?: (row: Content) => void;
}
): ContentPageConfig => {
const showSectorColumn = !handlers.activeSector;
@@ -99,14 +99,11 @@ export const createContentPageConfig = (
...titleColumn,
sortable: true,
sortField: 'title',
toggleable: true,
toggleContentKey: 'content_html',
toggleContentLabel: 'Generated Content',
render: (value: string, row: Content) => (
<div>
{handlers.onViewContent ? (
{handlers.onRowClick ? (
<button
onClick={() => handlers.onViewContent!(row)}
onClick={() => handlers.onRowClick!(row)}
className="font-medium text-blue-500 hover:text-blue-600 hover:underline text-left transition-colors"
>
{row.title || `Content #${row.id}`}
@@ -122,69 +119,84 @@ export const createContentPageConfig = (
...(showSectorColumn ? [{
...sectorColumn,
render: (value: string, row: Content) => (
<Badge color="info" size="sm" variant="light">
{row.sector_name || '-'}
<Badge color="info" size="xs" variant="soft">
<span className="text-[11px] font-normal">{row.sector_name || '-'}</span>
</Badge>
),
}] : []),
{
key: 'content_type',
label: 'Content Type',
label: 'Type',
sortable: true,
sortField: 'content_type',
width: '120px',
render: (value: string) => (
<Badge color="primary" size="sm" variant="light">
{TYPE_LABELS[value] || value || '-'}
</Badge>
),
width: '110px',
render: (value: string) => {
const label = TYPE_LABELS[value] || value || '-';
// Proper case: capitalize first letter only
const properCase = label.charAt(0).toUpperCase() + label.slice(1);
return (
<Badge color="blue" size="xs" variant="soft">
<span className="text-[11px] font-normal">{properCase}</span>
</Badge>
);
},
},
{
key: 'content_structure',
label: 'Structure',
sortable: true,
sortField: 'content_structure',
width: '150px',
render: (value: string) => (
<Badge color="info" size="sm" variant="light">
{STRUCTURE_LABELS[value] || value || '-'}
</Badge>
),
width: '130px',
render: (value: string) => {
const label = STRUCTURE_LABELS[value] || value || '-';
// Proper case: capitalize first letter of each word
const properCase = label.split(/[_\s]+/).map(word =>
word.charAt(0).toUpperCase() + word.slice(1)
).join(' ');
return (
<Badge color="purple" size="xs" variant="soft">
<span className="text-[11px] font-normal">{properCase}</span>
</Badge>
);
},
},
{
key: 'cluster_name',
label: 'Cluster',
sortable: false,
width: '150px',
width: '130px',
render: (_value: any, row: Content) => {
const clusterName = row.cluster_name;
if (!clusterName) {
return <span className="text-gray-400 dark:text-gray-500">-</span>;
return <span className="text-gray-400 dark:text-gray-500 text-[11px]">-</span>;
}
return (
<Badge color="primary" size="sm" variant="light">
{clusterName}
<Badge color="indigo" size="xs" variant="soft">
<span className="text-[11px] font-normal">{clusterName}</span>
</Badge>
);
},
},
{
key: 'taxonomy_terms',
label: 'Taxonomy',
label: 'Tags',
sortable: false,
width: '180px',
width: '150px',
render: (_value: any, row: Content) => {
const taxonomyTerms = row.taxonomy_terms;
if (!taxonomyTerms || taxonomyTerms.length === 0) {
return <span className="text-gray-400 dark:text-gray-500">-</span>;
return <span className="text-gray-400 dark:text-gray-500 text-[11px]">-</span>;
}
return (
<div className="flex flex-wrap gap-1">
{taxonomyTerms.map((term) => (
<Badge key={term.id} color="purple" size="sm" variant="light">
{term.name}
{taxonomyTerms.slice(0, 2).map((term) => (
<Badge key={term.id} color="pink" size="xs" variant="soft">
<span className="text-[11px] font-normal">{term.name}</span>
</Badge>
))}
{taxonomyTerms.length > 2 && (
<span className="text-[11px] text-gray-500">+{taxonomyTerms.length - 2}</span>
)}
</div>
);
},
@@ -194,15 +206,16 @@ export const createContentPageConfig = (
sortable: true,
sortField: 'status',
render: (value: string) => {
const statusColors: Record<string, 'warning' | 'success'> = {
draft: 'warning',
const statusColors: Record<string, 'success' | 'amber'> = {
draft: 'amber',
published: 'success',
};
const color = statusColors[value] || 'warning';
const label = value === 'published' ? 'Published' : 'Draft';
const color = statusColors[value] || 'amber';
// Proper case
const label = value ? value.charAt(0).toUpperCase() + value.slice(1) : 'Draft';
return (
<Badge color={color} size="sm" variant="light">
{label}
<Badge color={color} size="xs" variant="soft">
<span className="text-[11px] font-normal">{label}</span>
</Badge>
);
},
@@ -213,20 +226,20 @@ export const createContentPageConfig = (
label: 'Source',
sortable: true,
sortField: 'source',
width: '120px',
width: '90px',
render: (value: any, row: Content) => {
const source = value || row.source || 'igny8';
const sourceColors: Record<string, 'primary' | 'info'> = {
igny8: 'primary',
wordpress: 'info',
const sourceColors: Record<string, 'teal' | 'cyan'> = {
igny8: 'teal',
wordpress: 'cyan',
};
const sourceLabels: Record<string, string> = {
igny8: 'IGNY8',
wordpress: 'WordPress',
igny8: 'Igny8',
wordpress: 'Wp',
};
return (
<Badge color={sourceColors[source] || 'primary'} size="sm" variant="light">
{sourceLabels[source] || source}
<Badge color={sourceColors[source] || 'teal'} size="xs" variant="soft">
<span className="text-[11px] font-normal">{sourceLabels[source] || source}</span>
</Badge>
);
},

View File

@@ -108,8 +108,8 @@ export const createIdeasPageConfig = (
...(showSectorColumn ? [{
...sectorColumn,
render: (value: string, row: ContentIdea) => (
<Badge color="info" size="sm" variant="light">
{row.sector_name || '-'}
<Badge color="info" size="xs" variant="soft">
<span className="text-[11px] font-normal">{row.sector_name || '-'}</span>
</Badge>
),
}] : []),
@@ -118,24 +118,34 @@ export const createIdeasPageConfig = (
label: 'Structure',
sortable: true,
sortField: 'content_structure',
width: '150px',
render: (value: string) => (
<Badge color="info" size="sm" variant="light">
{value?.replace('_', ' ') || '-'}
</Badge>
),
width: '130px',
render: (value: string) => {
const label = value?.replace('_', ' ') || '-';
const properCase = label.split(/[_\s]+/).map(word =>
word.charAt(0).toUpperCase() + word.slice(1)
).join(' ');
return (
<Badge color="purple" size="xs" variant="soft">
<span className="text-[11px] font-normal">{properCase}</span>
</Badge>
);
},
},
{
key: 'content_type',
label: 'Type',
sortable: true,
sortField: 'content_type',
width: '120px',
render: (value: string) => (
<Badge color="info" size="sm" variant="light">
{value?.replace('_', ' ') || '-'}
</Badge>
),
width: '110px',
render: (value: string) => {
const label = value?.replace('_', ' ') || '-';
const properCase = label.charAt(0).toUpperCase() + label.slice(1);
return (
<Badge color="blue" size="xs" variant="soft">
<span className="text-[11px] font-normal">{properCase}</span>
</Badge>
);
},
},
{
key: 'target_keywords',
@@ -161,17 +171,15 @@ export const createIdeasPageConfig = (
sortable: true,
sortField: 'status',
render: (value: string) => {
const statusColors: Record<string, 'success' | 'warning' | 'error'> = {
'new': 'warning',
const statusColors: Record<string, 'success' | 'amber' | 'info'> = {
'new': 'amber',
'scheduled': 'info',
'published': 'success',
};
const properCase = value ? value.charAt(0).toUpperCase() + value.slice(1) : '-';
return (
<Badge
color={statusColors[value] || 'warning'}
size="sm"
>
{value}
<Badge color={statusColors[value] || 'amber'} size="xs" variant="soft">
<span className="text-[11px] font-normal">{properCase}</span>
</Badge>
);
},

View File

@@ -83,10 +83,11 @@ export const createImagesPageConfig = (
key: 'featured_image',
label: 'Featured Image',
sortable: false,
width: '200px',
width: '150px',
render: (_value: any, row: ContentImagesGroup) => (
<ContentImageCell
image={row.featured_image}
showPrompt={false}
onImageClick={handlers.onImageClick ? () => handlers.onImageClick!(row.content_id, 'featured') : undefined}
/>
),
@@ -99,12 +100,13 @@ export const createImagesPageConfig = (
key: `in_article_${i}`,
label: `In-Article ${i}`,
sortable: false,
width: '200px',
width: '150px',
render: (_value: any, row: ContentImagesGroup) => {
const image = row.in_article_images.find(img => img.position === i);
return (
<ContentImageCell
image={image || null}
showPrompt={false}
onImageClick={handlers.onImageClick && image ? () => handlers.onImageClick!(row.content_id, 'in_article', i) : undefined}
/>
);
@@ -112,13 +114,13 @@ export const createImagesPageConfig = (
});
}
// Add overall status column with Generate Images button
// Add status column (separate from generate button)
columns.push({
key: 'overall_status',
label: 'Status',
sortable: true,
sortField: 'overall_status',
width: '180px',
width: '120px',
render: (value: string, row: ContentImagesGroup) => {
const statusColors: Record<string, 'success' | 'warning' | 'error' | 'info'> = {
'complete': 'success',
@@ -133,33 +135,44 @@ export const createImagesPageConfig = (
'failed': 'Failed',
};
return (
<Badge color={statusColors[value] || 'amber'} size="xs" variant="soft">
<span className="text-[11px] font-normal">{labels[value] || value}</span>
</Badge>
);
},
});
// Add generate button column (separate from status)
columns.push({
key: 'generate_action',
label: 'Actions',
sortable: false,
width: '120px',
render: (_value: any, row: ContentImagesGroup) => {
// Check if there are any pending images with prompts
const hasPendingImages =
(row.featured_image?.status === 'pending' && row.featured_image?.prompt) ||
row.in_article_images.some(img => img.status === 'pending' && img.prompt);
return (
<div className="flex items-center gap-2">
<Badge
color={statusColors[value] || 'warning'}
size="sm"
>
{labels[value] || value}
</Badge>
{hasPendingImages && handlers.onGenerateImages && (
<>
{hasPendingImages && handlers.onGenerateImages ? (
<button
onClick={(e) => {
e.stopPropagation();
handlers.onGenerateImages!(row.content_id);
}}
className="inline-flex items-center gap-1 px-2 py-1 text-xs font-medium text-white bg-brand-500 hover:bg-brand-600 rounded transition-colors"
className="inline-flex items-center gap-1 px-3 py-1.5 text-sm font-medium text-white bg-brand-500 hover:bg-brand-600 rounded transition-colors"
title="Generate Images"
>
<BoltIcon className="w-3 h-3" />
<BoltIcon className="w-4 h-4" />
Generate
</button>
) : (
<span className="text-gray-400 dark:text-gray-500 text-sm">-</span>
)}
</div>
</>
);
},
});

View File

@@ -151,8 +151,8 @@ export const createKeywordsPageConfig = (
...(showSectorColumn ? [{
...sectorColumn,
render: (value: string, row: Keyword) => (
<Badge color="info" size="sm" variant="light">
{row.sector_name || '-'}
<Badge color="info" size="xs" variant="soft">
<span className="text-[11px] font-normal">{row.sector_name || '-'}</span>
</Badge>
),
}] : []),
@@ -175,26 +175,21 @@ export const createKeywordsPageConfig = (
align: 'center' as const,
render: (value: number) => {
const difficultyNum = getDifficultyNumber(value);
const difficultyBadgeVariant = 'light';
const difficultyBadgeColor =
typeof difficultyNum === 'number' && difficultyNum === 1
? 'success'
: typeof difficultyNum === 'number' && difficultyNum === 2
? 'success'
: typeof difficultyNum === 'number' && difficultyNum === 3
? 'warning'
? 'amber'
: typeof difficultyNum === 'number' && difficultyNum === 4
? 'error'
: typeof difficultyNum === 'number' && difficultyNum === 5
? 'error'
: 'light';
: 'gray';
return typeof difficultyNum === 'number' ? (
<Badge
color={difficultyBadgeColor}
variant={difficultyBadgeVariant}
size="sm"
>
{difficultyNum}
<Badge color={difficultyBadgeColor} variant="soft" size="xs">
<span className="text-[11px] font-normal">{difficultyNum}</span>
</Badge>
) : (
difficultyNum
@@ -220,13 +215,10 @@ export const createKeywordsPageConfig = (
return 'info'; // Blue for informational or default
};
const properCase = value ? value.charAt(0).toUpperCase() + value.slice(1) : '-';
return (
<Badge
color={getIntentColor(value)}
size="sm"
variant={value?.toLowerCase() === 'informational' ? 'light' : undefined}
>
{value}
<Badge color={getIntentColor(value)} size="xs" variant="soft">
<span className="text-[11px] font-normal">{properCase}</span>
</Badge>
);
},
@@ -236,18 +228,20 @@ export const createKeywordsPageConfig = (
sortable: true,
sortField: 'status',
render: (value: string) => {
const properCase = value ? value.charAt(0).toUpperCase() + value.slice(1) : '-';
return (
<Badge
color={
value === 'active'
? 'success'
: value === 'pending'
? 'warning'
? 'amber'
: 'error'
}
size="sm"
size="xs"
variant="soft"
>
{value}
<span className="text-[11px] font-normal">{properCase}</span>
</Badge>
);
},

View File

@@ -92,14 +92,14 @@ export function createPublishedPageConfig(params: {
sortField: 'status',
width: '120px',
render: (value: string) => {
const statusConfig: Record<string, { color: 'warning' | 'success'; label: string }> = {
draft: { color: 'warning', label: 'Draft' },
const statusConfig: Record<string, { color: 'amber' | 'success'; label: string }> = {
draft: { color: 'amber', label: 'Draft' },
published: { color: 'success', label: 'Published' },
};
const config = statusConfig[value] || { color: 'warning' as const, label: value };
const config = statusConfig[value] || { color: 'amber' as const, label: value };
return (
<Badge color={config.color} size="sm" variant="light">
{config.label}
<Badge color={config.color} size="xs" variant="soft">
<span className="text-[11px] font-normal">{config.label}</span>
</Badge>
);
},
@@ -112,15 +112,15 @@ export function createPublishedPageConfig(params: {
render: (_value: any, row: Content) => {
if (row.external_id && row.external_url) {
return (
<Badge color="success" size="sm" variant="light">
<Badge color="success" size="xs" variant="soft">
<CheckCircleIcon className="w-3 h-3 mr-1" />
Published
<span className="text-[11px] font-normal">Published</span>
</Badge>
);
}
return (
<Badge color="warning" size="sm" variant="light">
Not Published
<Badge color="amber" size="xs" variant="soft">
<span className="text-[11px] font-normal">Not Published</span>
</Badge>
);
},
@@ -130,24 +130,34 @@ export function createPublishedPageConfig(params: {
label: 'Type',
sortable: true,
sortField: 'content_type',
width: '120px',
render: (value: string) => (
<Badge color="primary" size="sm" variant="light">
{TYPE_LABELS[value] || value || '-'}
</Badge>
),
width: '110px',
render: (value: string) => {
const label = TYPE_LABELS[value] || value || '-';
const properCase = label.charAt(0).toUpperCase() + label.slice(1);
return (
<Badge color="blue" size="xs" variant="soft">
<span className="text-[11px] font-normal">{properCase}</span>
</Badge>
);
},
},
{
key: 'content_structure',
label: 'Structure',
sortable: true,
sortField: 'content_structure',
width: '150px',
render: (value: string) => (
<Badge color="info" size="sm" variant="light">
{STRUCTURE_LABELS[value] || value || '-'}
</Badge>
),
width: '130px',
render: (value: string) => {
const label = STRUCTURE_LABELS[value] || value || '-';
const properCase = label.split(/[_\s]+/).map(word =>
word.charAt(0).toUpperCase() + word.slice(1)
).join(' ');
return (
<Badge color="purple" size="xs" variant="soft">
<span className="text-[11px] font-normal">{properCase}</span>
</Badge>
);
},
},
{
key: 'word_count',

View File

@@ -52,87 +52,104 @@ export function createReviewPageConfig(params: {
setStatusFilter: (value: string) => void;
setCurrentPage: (page: number) => void;
activeSector: { id: number; name: string } | null;
onRowClick?: (row: Content) => void;
}): ReviewPageConfig {
const showSectorColumn = !params.activeSector;
const columns: ColumnConfig[] = [
{
key: 'categories',
label: 'Categories',
sortable: false,
width: '180px',
render: (_value: any, row: Content) => {
const categories = row.taxonomy_terms_data?.filter((t: any) => t.taxonomy_type === 'category') || [];
if (!categories.length) return <span className="text-gray-400 dark:text-gray-500">-</span>;
return (
<div className="flex flex-wrap gap-1">
{categories.map((cat: any) => (
<span key={cat.id} className="px-2 py-0.5 bg-purple-50 dark:bg-purple-900/20 text-purple-700 dark:text-purple-300 rounded-full text-xs font-medium">{cat.name}</span>
))}
</div>
);
},
toggleable: true,
defaultVisible: false,
},
{
key: 'tags',
label: 'Tags',
sortable: false,
width: '180px',
render: (_value: any, row: Content) => {
const tags = row.taxonomy_terms_data?.filter((t: any) => t.taxonomy_type === 'tag') || [];
if (!tags.length) return <span className="text-gray-400 dark:text-gray-500">-</span>;
return (
<div className="flex flex-wrap gap-1">
{tags.map((tag: any) => (
<span key={tag.id} className="px-2 py-0.5 bg-brand-50 dark:bg-brand-900/20 text-brand-700 dark:text-brand-300 rounded-full text-xs font-medium">{tag.name}</span>
))}
</div>
);
},
toggleable: true,
defaultVisible: false,
},
{
key: 'title',
label: 'Title',
sortable: true,
sortField: 'title',
toggleable: true,
toggleContentKey: 'content_html',
toggleContentLabel: 'Generated Content',
render: (value: string, row: Content) => (
<div className="flex items-center gap-2">
<span className="font-medium text-gray-900 dark:text-white">
{value || `Content #${row.id}`}
</span>
{params.onRowClick ? (
<button
onClick={() => params.onRowClick!(row)}
className="font-medium text-blue-500 hover:text-blue-600 hover:underline text-left transition-colors"
>
{value || `Content #${row.id}`}
</button>
) : (
<span className="font-medium text-gray-900 dark:text-white">
{value || `Content #${row.id}`}
</span>
)}
</div>
),
},
{
key: 'categories',
label: 'Categories',
sortable: false,
width: '180px',
render: (_value: any, row: Content) => {
const categories = row.taxonomy_terms_data?.filter((t: any) => t.taxonomy_type === 'category') || [];
if (!categories.length) return <span className="text-gray-400 dark:text-gray-500">-</span>;
return (
<div className="flex flex-wrap gap-1">
{categories.map((cat: any) => (
<span key={cat.id} className="px-2 py-0.5 bg-purple-50 dark:bg-purple-900/20 text-purple-700 dark:text-purple-300 rounded-full text-xs font-medium">{cat.name}</span>
))}
</div>
);
},
toggleable: true,
defaultVisible: true,
},
{
key: 'tags',
label: 'Tags',
sortable: false,
width: '180px',
render: (_value: any, row: Content) => {
const tags = row.taxonomy_terms_data?.filter((t: any) => t.taxonomy_type === 'tag') || [];
if (!tags.length) return <span className="text-gray-400 dark:text-gray-500">-</span>;
return (
<div className="flex flex-wrap gap-1">
{tags.map((tag: any) => (
<span key={tag.id} className="px-2 py-0.5 bg-brand-50 dark:bg-brand-900/20 text-brand-700 dark:text-brand-300 rounded-full text-xs font-medium">{tag.name}</span>
))}
</div>
);
},
toggleable: true,
defaultVisible: true,
},
{
key: 'content_type',
label: 'Type',
sortable: true,
sortField: 'content_type',
width: '120px',
render: (value: string) => (
<Badge color="primary" size="sm" variant="light">
{TYPE_LABELS[value] || value || '-'}
</Badge>
),
width: '110px',
render: (value: string) => {
const label = TYPE_LABELS[value] || value || '-';
const properCase = label.charAt(0).toUpperCase() + label.slice(1);
return (
<Badge color="blue" size="xs" variant="soft">
<span className="text-[11px] font-normal">{properCase}</span>
</Badge>
);
},
},
{
key: 'content_structure',
label: 'Structure',
sortable: true,
sortField: 'content_structure',
width: '150px',
render: (value: string) => (
<Badge color="info" size="sm" variant="light">
{STRUCTURE_LABELS[value] || value || '-'}
</Badge>
),
width: '130px',
render: (value: string) => {
const label = STRUCTURE_LABELS[value] || value || '-';
const properCase = label.split(/[_\s]+/).map(word =>
word.charAt(0).toUpperCase() + word.slice(1)
).join(' ');
return (
<Badge color="purple" size="xs" variant="soft">
<span className="text-[11px] font-normal">{properCase}</span>
</Badge>
);
},
},
{
key: 'cluster_name',
@@ -145,8 +162,8 @@ export function createReviewPageConfig(params: {
return <span className="text-gray-400 dark:text-gray-500">-</span>;
}
return (
<Badge color="primary" size="sm" variant="light">
{clusterName}
<Badge color="indigo" size="xs" variant="soft">
<span className="text-[11px] font-normal">{clusterName}</span>
</Badge>
);
},
@@ -186,8 +203,8 @@ export function createReviewPageConfig(params: {
sortable: false,
width: '120px',
render: (value: string, row: Content) => (
<Badge color="info" size="sm" variant="light">
{row.sector_name || '-'}
<Badge color="info" size="xs" variant="soft">
<span className="text-[11px] font-normal">{row.sector_name || '-'}</span>
</Badge>
),
});

View File

@@ -116,8 +116,8 @@ export const createTasksPageConfig = (
{displayTitle}
</span>
{isSiteBuilder && (
<Badge color="purple" size="sm" variant="light">
Site Builder
<Badge color="purple" size="xs" variant="soft">
<span className="text-[11px] font-normal">Site Builder</span>
</Badge>
)}
</div>
@@ -128,8 +128,8 @@ export const createTasksPageConfig = (
...(showSectorColumn ? [{
...sectorColumn,
render: (value: string, row: Task) => (
<Badge color="info" size="sm" variant="light">
{row.sector_name || '-'}
<Badge color="info" size="xs" variant="soft">
<span className="text-[11px] font-normal">{row.sector_name || '-'}</span>
</Badge>
),
}] : []),
@@ -153,53 +153,60 @@ export const createTasksPageConfig = (
return <span className="text-gray-400 dark:text-gray-500">-</span>;
}
return (
<Badge color="purple" size="sm" variant="light">
{taxonomyName}
<Badge color="purple" size="xs" variant="soft">
<span className="text-[11px] font-normal">{taxonomyName}</span>
</Badge>
);
},
},
{
key: 'content_type',
label: 'Content Type',
label: 'Type',
sortable: true,
sortField: 'content_type',
width: '120px',
render: (value: string) => (
<Badge color="primary" size="sm" variant="light">
{TYPE_LABELS[value] || value || '-'}
</Badge>
),
width: '110px',
render: (value: string) => {
const label = TYPE_LABELS[value] || value || '-';
const properCase = label.charAt(0).toUpperCase() + label.slice(1);
return (
<Badge color="blue" size="xs" variant="soft">
<span className="text-[11px] font-normal">{properCase}</span>
</Badge>
);
},
},
{
key: 'content_structure',
label: 'Structure',
sortable: true,
sortField: 'content_structure',
width: '150px',
render: (value: string) => (
<Badge color="info" size="sm" variant="light">
{STRUCTURE_LABELS[value] || value || '-'}
</Badge>
),
width: '130px',
render: (value: string) => {
const label = STRUCTURE_LABELS[value] || value || '-';
const properCase = label.split(/[_\s]+/).map(word =>
word.charAt(0).toUpperCase() + word.slice(1)
).join(' ');
return (
<Badge color="purple" size="xs" variant="soft">
<span className="text-[11px] font-normal">{properCase}</span>
</Badge>
);
},
},
{
...statusColumn,
sortable: true,
sortField: 'status',
render: (value: string) => {
const statusColors: Record<string, 'success' | 'warning'> = {
queued: 'warning',
const statusColors: Record<string, 'success' | 'amber'> = {
queued: 'amber',
completed: 'success',
};
const label = value ? value.replace('_', ' ') : '';
const formatted = label ? label.charAt(0).toUpperCase() + label.slice(1) : '';
return (
<Badge
color={statusColors[value] || 'warning'}
size="sm"
>
{formatted}
<Badge color={statusColors[value] || 'amber'} size="xs" variant="soft">
<span className="text-[11px] font-normal">{formatted}</span>
</Badge>
);
},