header rekated fixes

This commit is contained in:
IGNY8 VPS (Salman)
2025-12-27 05:33:05 +00:00
parent fd6e7eb2dd
commit 726d945bda
15 changed files with 414 additions and 232 deletions

View File

@@ -4,7 +4,6 @@
*/
import { useState, useEffect, useMemo, useCallback, useRef } from 'react';
import { Link } from 'react-router-dom';
import TablePageTemplate from '../../templates/TablePageTemplate';
import {
fetchClusters,
@@ -390,20 +389,8 @@ export default function Clusters() {
<>
<PageHeader
title="Clusters"
description="Group keywords into topic clusters"
badge={{ icon: <GroupIcon />, color: 'purple' }}
breadcrumb="Planner"
actions={
<Link
to="/planner/ideas"
className="inline-flex items-center gap-2 px-3 py-1.5 text-sm font-medium text-white bg-brand-500 hover:bg-brand-600 rounded-lg transition-colors"
>
Generate Ideas
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</Link>
}
parent="Planner"
/>
<TablePageTemplate
columns={pageConfig.columns}
@@ -418,6 +405,15 @@ export default function Clusters() {
volumeMin: volumeMin,
volumeMax: volumeMax,
}}
nextAction={selectedIds.length > 0 ? {
label: 'Generate Ideas',
message: `${selectedIds.length} selected`,
onClick: () => handleBulkAction('generate_ideas', selectedIds),
} : clusters.length > 0 ? {
label: 'Generate Ideas',
href: '/planner/ideas',
message: `${clusters.length} clusters`,
} : undefined}
onFilterChange={(key, value) => {
const stringValue = value === null || value === undefined ? '' : String(value);
if (key === 'search') {

View File

@@ -4,7 +4,6 @@
*/
import { useState, useEffect, useMemo, useCallback } from 'react';
import { Link } from 'react-router-dom';
import TablePageTemplate from '../../templates/TablePageTemplate';
import {
fetchContentIdeas,
@@ -301,20 +300,8 @@ export default function Ideas() {
<>
<PageHeader
title="Ideas"
description="Content ideas generated from keywords"
badge={{ icon: <LightBulbIcon />, color: 'yellow' }}
breadcrumb="Planner"
actions={
<Link
to="/writer/queue"
className="inline-flex items-center gap-2 px-3 py-1.5 text-sm font-medium text-white bg-brand-500 hover:bg-brand-600 rounded-lg transition-colors"
>
Start Writing
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</Link>
}
parent="Planner"
/>
<TablePageTemplate
columns={pageConfig.columns}
@@ -329,6 +316,15 @@ export default function Ideas() {
content_structure: structureFilter,
content_type: typeFilter,
}}
nextAction={selectedIds.length > 0 ? {
label: 'Queue to Writer',
message: `${selectedIds.length} selected`,
onClick: () => handleBulkAction('queue_to_writer', selectedIds),
} : ideas.filter(i => i.status === 'approved').length > 0 ? {
label: 'Start Writing',
href: '/writer/queue',
message: `${ideas.filter(i => i.status === 'approved').length} approved`,
} : undefined}
onFilterChange={(key, value) => {
const stringValue = value === null || value === undefined ? '' : String(value);
if (key === 'search') {

View File

@@ -5,7 +5,6 @@
*/
import { useState, useEffect, useRef, useMemo, useCallback } from 'react';
import { Link } from 'react-router-dom';
import TablePageTemplate from '../../templates/TablePageTemplate';
import {
fetchKeywords,
@@ -507,20 +506,6 @@ export default function Keywords() {
};
}, [keywords, totalCount]);
// Determine next step action
const nextStep = useMemo(() => {
if (totalCount === 0) {
return { label: 'Import Keywords', path: '/add-keywords', disabled: false };
}
if (workflowStats.unclustered >= 5) {
return { label: 'Auto-Cluster', action: 'cluster', disabled: false };
}
if (workflowStats.clustered > 0) {
return { label: 'Generate Ideas', path: '/planner/ideas', disabled: false };
}
return { label: 'Add More Keywords', path: '/add-keywords', disabled: false };
}, [totalCount, workflowStats]);
// Handle create/edit
const handleSave = async () => {
try {
@@ -594,37 +579,8 @@ export default function Keywords() {
<>
<PageHeader
title="Keywords"
description="Your target search terms organized for content creation"
badge={{ icon: <ListIcon />, color: 'green' }}
breadcrumb="Planner"
actions={
<div className="flex items-center gap-3">
<span className="text-sm text-gray-500 dark:text-gray-400 hidden md:block">
{workflowStats.clustered}/{workflowStats.total} clustered
</span>
{nextStep.path ? (
<Link
to={nextStep.path}
className="inline-flex items-center gap-2 px-3 py-1.5 text-sm font-medium text-white bg-brand-500 hover:bg-brand-600 rounded-lg transition-colors"
>
{nextStep.label}
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</Link>
) : nextStep.action === 'cluster' ? (
<button
onClick={handleAutoCluster}
className="inline-flex items-center gap-2 px-3 py-1.5 text-sm font-medium text-white bg-brand-500 hover:bg-brand-600 rounded-lg transition-colors"
>
{nextStep.label}
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</button>
) : null}
</div>
}
parent="Planner"
/>
<TablePageTemplate
columns={pageConfig.columns}
@@ -641,6 +597,19 @@ export default function Keywords() {
volumeMin: volumeMin,
volumeMax: volumeMax,
}}
nextAction={selectedIds.length > 0 ? {
label: 'Auto-Cluster Selected',
message: `${selectedIds.length} selected`,
onClick: handleAutoCluster,
} : workflowStats.unclustered >= 5 ? {
label: 'Auto-Cluster All',
message: `${workflowStats.unclustered} unclustered`,
onClick: handleAutoCluster,
} : workflowStats.clustered > 0 ? {
label: 'Generate Ideas',
href: '/planner/ideas',
message: `${workflowStats.clustered} clustered`,
} : undefined}
onFilterChange={(key, value) => {
// Normalize value to string, preserving empty strings
const stringValue = value === null || value === undefined ? '' : String(value);