frontend-refactor-1

This commit is contained in:
alorig
2025-11-20 08:58:38 +05:00
parent a0de0cf6b1
commit 8e7afa76cd
18 changed files with 1810 additions and 975 deletions

View File

@@ -161,14 +161,8 @@ export default function App() {
</Suspense>
} />
{/* Planner Module */}
<Route path="/planner" element={
<Suspense fallback={null}>
<ModuleGuard module="planner">
<PlannerDashboard />
</ModuleGuard>
</Suspense>
} />
{/* Planner Module - Redirect dashboard to keywords */}
<Route path="/planner" element={<Navigate to="/planner/keywords" replace />} />
<Route path="/planner/keywords" element={
<Suspense fallback={null}>
<ModuleGuard module="planner">
@@ -191,14 +185,8 @@ export default function App() {
</Suspense>
} />
{/* Writer Module */}
<Route path="/writer" element={
<Suspense fallback={null}>
<ModuleGuard module="writer">
<WriterDashboard />
</ModuleGuard>
</Suspense>
} />
{/* Writer Module - Redirect dashboard to content */}
<Route path="/writer" element={<Navigate to="/writer/content" replace />} />
<Route path="/writer/tasks" element={
<Suspense fallback={null}>
<ModuleGuard module="writer">
@@ -238,14 +226,8 @@ export default function App() {
</Suspense>
} />
{/* Linker Module */}
<Route path="/linker" element={
<Suspense fallback={null}>
<ModuleGuard module="linker">
<LinkerDashboard />
</ModuleGuard>
</Suspense>
} />
{/* Linker Module - Redirect dashboard to content */}
<Route path="/linker" element={<Navigate to="/linker/content" replace />} />
<Route path="/linker/content" element={
<Suspense fallback={null}>
<ModuleGuard module="linker">
@@ -254,14 +236,8 @@ export default function App() {
</Suspense>
} />
{/* Optimizer Module */}
<Route path="/optimizer" element={
<Suspense fallback={null}>
<ModuleGuard module="optimizer">
<OptimizerDashboard />
</ModuleGuard>
</Suspense>
} />
{/* Optimizer Module - Redirect dashboard to content */}
<Route path="/optimizer" element={<Navigate to="/optimizer/content" replace />} />
<Route path="/optimizer/content" element={
<Suspense fallback={null}>
<ModuleGuard module="optimizer">
@@ -355,14 +331,8 @@ export default function App() {
</Suspense>
} />
{/* Other Pages */}
<Route path="/automation" element={
<Suspense fallback={null}>
<ModuleGuard module="automation">
<AutomationDashboard />
</ModuleGuard>
</Suspense>
} />
{/* Automation Module - Redirect dashboard to rules */}
<Route path="/automation" element={<Navigate to="/automation/rules" replace />} />
<Route path="/automation/rules" element={
<Suspense fallback={null}>
<ModuleGuard module="automation">

View File

@@ -0,0 +1,85 @@
/**
* ModuleMetricsFooter - Compact metrics footer for table pages
* Shows module-specific metrics at the bottom of table pages
* Uses standard EnhancedMetricCard and ProgressBar components
* Follows standard app design system and color scheme
*/
import React from 'react';
import EnhancedMetricCard, { MetricCardProps } from './EnhancedMetricCard';
import { ProgressBar } from '../ui/progress';
export interface MetricItem {
title: string;
value: string | number;
subtitle?: string;
icon: React.ReactNode;
accentColor: MetricCardProps['accentColor'];
href?: string;
onClick?: () => void;
}
export interface ProgressMetric {
label: string;
value: number; // 0-100
color?: 'primary' | 'success' | 'warning' | 'purple';
}
interface ModuleMetricsFooterProps {
metrics: MetricItem[];
progress?: ProgressMetric;
className?: string;
}
export default function ModuleMetricsFooter({
metrics,
progress,
className = ''
}: ModuleMetricsFooterProps) {
if (metrics.length === 0 && !progress) return null;
const progressColors = {
primary: 'bg-[var(--color-primary)]',
success: 'bg-[var(--color-success)]',
warning: 'bg-[var(--color-warning)]',
purple: 'bg-[var(--color-purple)]',
};
return (
<div className={`mt-8 pt-6 border-t border-gray-200 dark:border-gray-800 ${className}`}>
<div className="space-y-4">
{/* Metrics Grid */}
{metrics.length > 0 && (
<div className={`grid grid-cols-1 sm:grid-cols-2 ${metrics.length > 2 ? 'lg:grid-cols-3' : 'lg:grid-cols-2'} ${metrics.length > 3 ? 'xl:grid-cols-4' : ''} gap-4`}>
{metrics.map((metric, index) => (
<EnhancedMetricCard
key={index}
title={metric.title}
value={metric.value}
subtitle={metric.subtitle}
icon={metric.icon}
accentColor={metric.accentColor}
href={metric.href}
onClick={metric.onClick}
/>
))}
</div>
)}
{/* Progress Bar */}
{progress && (
<div className="space-y-2">
<ProgressBar
value={progress.value}
color={progress.color === 'success' ? 'success' : progress.color === 'warning' ? 'warning' : 'primary'}
size="md"
showLabel={true}
label={progress.label}
/>
</div>
)}
</div>
</div>
);
}

View File

@@ -0,0 +1,66 @@
/**
* ModuleNavigationTabs - Reusable in-page tab navigation component
* Used across Planner, Writer, Linker, Optimizer, Thinker, Automation, Sites modules
* Follows standard app design system and color scheme
*/
import React from 'react';
import { Link, useLocation } from 'react-router';
import { Tabs, TabList, Tab } from '../ui/tabs/Tabs';
export interface NavigationTab {
label: string;
path: string;
icon?: React.ReactNode;
}
interface ModuleNavigationTabsProps {
tabs: NavigationTab[];
className?: string;
}
export default function ModuleNavigationTabs({ tabs, className = '' }: ModuleNavigationTabsProps) {
const location = useLocation();
// Find active tab based on current path
const activeTab = tabs.find(tab => {
if (tab.path === location.pathname) return true;
// Handle nested routes (e.g., /planner/keywords/123 should match /planner/keywords)
return location.pathname.startsWith(tab.path + '/');
});
const activeTabId = activeTab?.path || tabs[0]?.path || '';
return (
<div className={`mb-6 ${className}`}>
<Tabs defaultTab={activeTabId}>
{(activeTabId, setActiveTab) => (
<TabList className="bg-gray-100 dark:bg-gray-900">
{tabs.map((tab) => {
const isActive = activeTabId === tab.path || location.pathname.startsWith(tab.path + '/');
return (
<Link
key={tab.path}
to={tab.path}
onClick={() => setActiveTab(tab.path)}
className="flex-1"
>
<Tab
tabId={tab.path}
isActive={isActive}
className="flex items-center justify-center gap-2"
>
{tab.icon && <span className="flex-shrink-0">{tab.icon}</span>}
<span>{tab.label}</span>
</Tab>
</Link>
);
})}
</TabList>
)}
</Tabs>
</div>
);
}

View File

@@ -78,132 +78,102 @@ const AppSidebar: React.FC = () => {
// Define menu sections with useMemo to prevent recreation on every render
// Filter out disabled modules based on module enable settings
// New structure: Dashboard (standalone) → SETUP → WORKFLOW → SETTINGS
const menuSections: MenuSection[] = useMemo(() => {
const workflowItems: NavItem[] = [
// SETUP section items (single items, no dropdowns - submenus shown as in-page navigation)
const setupItems: NavItem[] = [
{
icon: <PlugInIcon />,
name: "Setup",
subItems: [
{ name: "Keywords Opportunities", path: "/planner/keyword-opportunities" },
],
icon: <DocsIcon />,
name: "Industry, Sectors & Keywords",
path: "/setup/industries-sectors-keywords", // Merged page
},
{
icon: <GridIcon />,
name: "Sites",
path: "/sites", // Submenus shown as in-page navigation
},
];
// Add Automation if enabled (single item, no dropdown)
if (moduleEnabled('automation')) {
setupItems.push({
icon: <BoltIcon />,
name: "Automation",
path: "/automation/rules", // Default to rules, submenus shown as in-page navigation
});
}
// Add Thinker if enabled (single item, no dropdown)
if (moduleEnabled('thinker')) {
setupItems.push({
icon: <BoltIcon />,
name: "Thinker",
path: "/thinker/prompts", // Default to prompts, submenus shown as in-page navigation
});
}
// WORKFLOW section items (single items, no dropdowns - submenus shown as in-page navigation)
const workflowItems: NavItem[] = [];
// Add Planner if enabled
// Add Planner if enabled (single item, no dropdown)
if (moduleEnabled('planner')) {
workflowItems.push({
icon: <ListIcon />,
name: "Planner",
subItems: [
{ name: "Dashboard", path: "/planner" },
{ name: "Keywords", path: "/planner/keywords" },
{ name: "Clusters", path: "/planner/clusters" },
{ name: "Ideas", path: "/planner/ideas" },
],
path: "/planner/keywords", // Default to keywords, submenus shown as in-page navigation
});
}
// Add Writer if enabled
// Add Writer if enabled (single item, no dropdown)
if (moduleEnabled('writer')) {
workflowItems.push({
icon: <TaskIcon />,
name: "Writer",
subItems: [
{ name: "Dashboard", path: "/writer" },
{ name: "Tasks", path: "/writer/tasks" },
{ name: "Content", path: "/writer/content" },
{ name: "Images", path: "/writer/images" },
{ name: "Published", path: "/writer/published" },
],
path: "/writer/content", // Default to content, submenus shown as in-page navigation
});
}
// Add Thinker if enabled
if (moduleEnabled('thinker')) {
workflowItems.push({
icon: <BoltIcon />,
name: "Thinker",
subItems: [
{ name: "Dashboard", path: "/thinker" },
{ name: "Prompts", path: "/thinker/prompts" },
{ name: "Author Profiles", path: "/thinker/author-profiles" },
{ name: "Strategies", path: "/thinker/strategies" },
{ name: "Image Testing", path: "/thinker/image-testing" },
],
});
}
// Add Linker if enabled
// Add Linker if enabled (single item, no dropdown)
if (moduleEnabled('linker')) {
workflowItems.push({
icon: <PlugInIcon />,
name: "Linker",
subItems: [
{ name: "Dashboard", path: "/linker" },
{ name: "Content", path: "/linker/content" },
],
path: "/linker/content",
});
}
// Add Optimizer if enabled
// Add Optimizer if enabled (single item, no dropdown)
if (moduleEnabled('optimizer')) {
workflowItems.push({
icon: <BoltIcon />,
name: "Optimizer",
subItems: [
{ name: "Dashboard", path: "/optimizer" },
{ name: "Content", path: "/optimizer/content" },
],
path: "/optimizer/content",
});
}
// Add Automation if enabled
if (moduleEnabled('automation')) {
workflowItems.push({
icon: <BoltIcon />,
name: "Automation",
subItems: [
{ name: "Dashboard", path: "/automation" },
{ name: "Rules", path: "/automation/rules" },
{ name: "Tasks", path: "/automation/tasks" },
],
});
}
// Add Sites menu (always available)
workflowItems.push({
icon: <GridIcon />,
name: "Sites",
subItems: [
{ name: "All Sites", path: "/sites" },
{ name: "Create Site", path: "/sites/builder" },
{ name: "Blueprints", path: "/sites/blueprints" },
],
});
return [
// Dashboard is standalone (no section header)
{
label: "OVERVIEW",
label: "", // Empty label for standalone Dashboard
items: [
{
icon: <GridIcon />,
name: "Dashboard",
path: "/",
},
{
icon: <DocsIcon />,
name: "Industry / Sectors",
path: "/reference/industries",
},
],
},
{
label: "WORKFLOWS",
label: "SETUP",
items: setupItems,
},
{
label: "WORKFLOW",
items: workflowItems,
},
{
label: "ACCOUNT & SETTINGS",
items: [
{
label: "SETTINGS",
items: [
{
icon: <PlugInIcon />,
name: "Settings",
@@ -215,28 +185,23 @@ const AppSidebar: React.FC = () => {
{ name: "Import / Export", path: "/settings/import-export" },
],
},
{
icon: <DollarLineIcon />,
name: "Billing",
subItems: [
{ name: "Credits", path: "/billing/credits" },
{ name: "Transactions", path: "/billing/transactions" },
{ name: "Usage", path: "/billing/usage" },
],
},
],
},
{
label: "HELP",
items: [
{
icon: <DocsIcon />,
name: "Help & Documentation",
path: "/help",
},
],
},
];
{
icon: <DollarLineIcon />,
name: "Billing",
subItems: [
{ name: "Credits", path: "/billing/credits" },
{ name: "Transactions", path: "/billing/transactions" },
{ name: "Usage", path: "/billing/usage" },
],
},
{
icon: <DocsIcon />,
name: "Help & Documentation",
path: "/help",
},
],
},
];
}, [moduleEnabled]);
// Admin section - only shown for users in aws-admin account
@@ -585,20 +550,22 @@ const AppSidebar: React.FC = () => {
<nav className="mb-6">
<div className="flex flex-col gap-2">
{allSections.map((section, sectionIndex) => (
<div key={section.label}>
<h2
className={`mb-4 text-xs uppercase flex leading-[20px] text-gray-400 ${
!isExpanded && !isHovered
? "lg:justify-center"
: "justify-start"
}`}
>
{isExpanded || isHovered || isMobileOpen ? (
section.label
) : (
<HorizontaLDots className="size-6" />
)}
</h2>
<div key={section.label || `section-${sectionIndex}`}>
{section.label && (
<h2
className={`mb-4 text-xs uppercase flex leading-[20px] text-gray-400 ${
!isExpanded && !isHovered
? "lg:justify-center"
: "justify-start"
}`}
>
{isExpanded || isHovered || isMobileOpen ? (
section.label
) : (
<HorizontaLDots className="size-6" />
)}
</h2>
)}
{renderMenuItems(section.items, sectionIndex)}
</div>
))}

View File

@@ -5,9 +5,10 @@ import PageHeader from '../../components/common/PageHeader';
import ComponentCard from '../../components/common/ComponentCard';
import { automationApi, AutomationRule } from '../../api/automation.api';
import { useToast } from '../../components/ui/toast/ToastContainer';
import { BoltIcon, PlusIcon, TrashBinIcon, PencilIcon, PaperPlaneIcon, CloseIcon } from '../../icons';
import { BoltIcon, PlusIcon, TrashBinIcon, PencilIcon, PaperPlaneIcon, CloseIcon, TaskIcon, ClockIcon } from '../../icons';
import { useSiteStore } from '../../store/siteStore';
import { useSectorStore } from '../../store/sectorStore';
import ModuleNavigationTabs from '../../components/navigation/ModuleNavigationTabs';
export default function AutomationRules() {
const navigate = useNavigate();
@@ -109,6 +110,12 @@ export default function AutomationRules() {
);
};
// Automation navigation tabs
const automationTabs = [
{ label: 'Rules', path: '/automation/rules', icon: <BoltIcon /> },
{ label: 'Tasks', path: '/automation/tasks', icon: <ClockIcon /> },
];
return (
<>
<PageMeta title="Automation Rules" />

View File

@@ -4,9 +4,10 @@ import PageHeader from '../../components/common/PageHeader';
import ComponentCard from '../../components/common/ComponentCard';
import { automationApi, ScheduledTask } from '../../api/automation.api';
import { useToast } from '../../components/ui/toast/ToastContainer';
import { ClockIcon, CheckCircleIcon, XCircleIcon, ArrowRightIcon } from '../../icons';
import { ClockIcon, CheckCircleIcon, XCircleIcon, ArrowRightIcon, BoltIcon } from '../../icons';
import { useSiteStore } from '../../store/siteStore';
import { useSectorStore } from '../../store/sectorStore';
import ModuleNavigationTabs from '../../components/navigation/ModuleNavigationTabs';
export default function AutomationTasks() {
const toast = useToast();
@@ -95,6 +96,12 @@ export default function AutomationTasks() {
return true;
});
// Automation navigation tabs
const automationTabs = [
{ label: 'Rules', path: '/automation/rules', icon: <BoltIcon /> },
{ label: 'Tasks', path: '/automation/tasks', icon: <ClockIcon /> },
];
return (
<>
<PageMeta title="Scheduled Tasks" />
@@ -107,6 +114,7 @@ export default function AutomationTasks() {
color: 'blue',
}}
/>
<ModuleNavigationTabs tabs={automationTabs} />
<div className="flex items-center gap-4">
<div className="flex-1">

View File

@@ -21,12 +21,13 @@ import FormModal from '../../components/common/FormModal';
import ProgressModal from '../../components/common/ProgressModal';
import { useProgressModal } from '../../hooks/useProgressModal';
import { useToast } from '../../components/ui/toast/ToastContainer';
import { GroupIcon, PlusIcon, DownloadIcon } from '../../icons';
import { GroupIcon, PlusIcon, DownloadIcon, ListIcon, BoltIcon } from '../../icons';
import { createClustersPageConfig } from '../../config/pages/clusters.config';
import { useSectorStore } from '../../store/sectorStore';
import { usePageSizeStore } from '../../store/pageSizeStore';
import { getDifficultyLabelFromNumber, getDifficultyRange } from '../../utils/difficulty';
import PageHeader from '../../components/common/PageHeader';
import ModuleNavigationTabs from '../../components/navigation/ModuleNavigationTabs';
export default function Clusters() {
const toast = useToast();
@@ -383,12 +384,20 @@ export default function Clusters() {
}
};
// Planner navigation tabs
const plannerTabs = [
{ label: 'Keywords', path: '/planner/keywords', icon: <ListIcon /> },
{ label: 'Clusters', path: '/planner/clusters', icon: <GroupIcon /> },
{ label: 'Ideas', path: '/planner/ideas', icon: <BoltIcon /> },
];
return (
<>
<PageHeader
title="Keyword Clusters"
badge={{ icon: <GroupIcon />, color: 'purple' }}
/>
<ModuleNavigationTabs tabs={plannerTabs} />
<TablePageTemplate
columns={pageConfig.columns}
data={clusters}

View File

@@ -23,11 +23,12 @@ import FormModal from '../../components/common/FormModal';
import ProgressModal from '../../components/common/ProgressModal';
import { useProgressModal } from '../../hooks/useProgressModal';
import { useToast } from '../../components/ui/toast/ToastContainer';
import { BoltIcon, PlusIcon, DownloadIcon } from '../../icons';
import { BoltIcon, PlusIcon, DownloadIcon, ListIcon, GroupIcon } from '../../icons';
import { createIdeasPageConfig } from '../../config/pages/ideas.config';
import { useSectorStore } from '../../store/sectorStore';
import { usePageSizeStore } from '../../store/pageSizeStore';
import PageHeader from '../../components/common/PageHeader';
import ModuleNavigationTabs from '../../components/navigation/ModuleNavigationTabs';
export default function Ideas() {
const toast = useToast();
@@ -295,12 +296,20 @@ export default function Ideas() {
}
};
// Planner navigation tabs
const plannerTabs = [
{ label: 'Keywords', path: '/planner/keywords', icon: <ListIcon /> },
{ label: 'Clusters', path: '/planner/clusters', icon: <GroupIcon /> },
{ label: 'Ideas', path: '/planner/ideas', icon: <BoltIcon /> },
];
return (
<>
<PageHeader
title="Content Ideas"
badge={{ icon: <BoltIcon />, color: 'orange' }}
/>
<ModuleNavigationTabs tabs={plannerTabs} />
<TablePageTemplate
columns={pageConfig.columns}
data={ideas}

View File

@@ -27,13 +27,14 @@ import { useSiteStore } from '../../store/siteStore';
import { useSectorStore } from '../../store/sectorStore';
import { usePageSizeStore } from '../../store/pageSizeStore';
import PageHeader from '../../components/common/PageHeader';
import ModuleNavigationTabs from '../../components/navigation/ModuleNavigationTabs';
import { getDifficultyLabelFromNumber, getDifficultyRange } from '../../utils/difficulty';
import FormModal from '../../components/common/FormModal';
import ProgressModal from '../../components/common/ProgressModal';
import { useProgressModal } from '../../hooks/useProgressModal';
import { useResourceDebug } from '../../hooks/useResourceDebug';
import { useToast } from '../../components/ui/toast/ToastContainer';
import { ArrowUpIcon, PlusIcon, ListIcon, DownloadIcon } from '../../icons';
import { ArrowUpIcon, PlusIcon, ListIcon, DownloadIcon, GroupIcon, BoltIcon } from '../../icons';
import { useKeywordsImportExport } from '../../config/import-export.config';
import { createKeywordsPageConfig } from '../../config/pages/keywords.config';
@@ -750,12 +751,20 @@ export default function Keywords() {
setIsModalOpen(true);
}, []);
// Planner navigation tabs
const plannerTabs = [
{ label: 'Keywords', path: '/planner/keywords', icon: <ListIcon /> },
{ label: 'Clusters', path: '/planner/clusters', icon: <GroupIcon /> },
{ label: 'Ideas', path: '/planner/ideas', icon: <BoltIcon /> },
];
return (
<>
<PageHeader
title="Keywords"
badge={{ icon: <ListIcon />, color: 'green' }}
/>
<ModuleNavigationTabs tabs={plannerTabs} />
<TablePageTemplate
columns={pageConfig.columns}
data={keywords}

View File

@@ -1,12 +1,14 @@
import { useState, useEffect } from 'react';
import PageMeta from '../../components/common/PageMeta';
import PageHeader from '../../components/common/PageHeader';
import ModuleNavigationTabs from '../../components/navigation/ModuleNavigationTabs';
import { useToast } from '../../components/ui/toast/ToastContainer';
import { fetchAuthorProfiles, createAuthorProfile, updateAuthorProfile, deleteAuthorProfile, AuthorProfile } from '../../services/api';
import { Card } from '../../components/ui/card';
import Button from '../../components/ui/button/Button';
import FormModal, { FormField } from '../../components/common/FormModal';
import Badge from '../../components/ui/badge/Badge';
import { PlusIcon } from '../../icons';
import { PlusIcon, BoltIcon, UserIcon, ShootingStarIcon, ImageIcon } from '../../icons';
export default function AuthorProfiles() {
const toast = useToast();
@@ -97,14 +99,23 @@ export default function AuthorProfiles() {
{ name: 'is_active', label: 'Active', type: 'checkbox', required: false },
];
// Thinker navigation tabs
const thinkerTabs = [
{ label: 'Prompts', path: '/thinker/prompts', icon: <BoltIcon /> },
{ label: 'Author Profiles', path: '/thinker/author-profiles', icon: <UserIcon /> },
{ label: 'Strategies', path: '/thinker/strategies', icon: <ShootingStarIcon /> },
{ label: 'Image Testing', path: '/thinker/image-testing', icon: <ImageIcon /> },
];
return (
<div className="p-6">
<PageMeta title="Author Profiles" />
<PageHeader
title="Author Profiles"
badge={{ icon: <UserIcon />, color: 'blue' }}
/>
<ModuleNavigationTabs tabs={thinkerTabs} />
<div className="mb-6 flex justify-between items-center">
<div>
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">Author Profiles</h1>
<p className="text-gray-600 dark:text-gray-400 mt-1">Manage writing style profiles</p>
</div>
<Button onClick={handleCreate} variant="primary">
<PlusIcon className="w-4 h-4 mr-2" />
Create Profile

View File

@@ -1,11 +1,26 @@
import PageMeta from "../../components/common/PageMeta";
import PageHeader from "../../components/common/PageHeader";
import ModuleNavigationTabs from "../../components/navigation/ModuleNavigationTabs";
import ComponentCard from "../../components/common/ComponentCard";
import { BoltIcon, UserIcon, ShootingStarIcon, ImageIcon } from "../../icons";
export default function ImageTesting() {
// Thinker navigation tabs
const thinkerTabs = [
{ label: 'Prompts', path: '/thinker/prompts', icon: <BoltIcon /> },
{ label: 'Author Profiles', path: '/thinker/author-profiles', icon: <UserIcon /> },
{ label: 'Strategies', path: '/thinker/strategies', icon: <ShootingStarIcon /> },
{ label: 'Image Testing', path: '/thinker/image-testing', icon: <ImageIcon /> },
];
return (
<>
<PageMeta title="Image Testing - IGNY8" description="AI image testing" />
<PageHeader
title="Image Testing"
badge={{ icon: <ImageIcon />, color: 'indigo' }}
/>
<ModuleNavigationTabs tabs={thinkerTabs} />
<ComponentCard title="Coming Soon" desc="AI image testing">
<div className="text-center py-8">
<p className="text-gray-600 dark:text-gray-400">

View File

@@ -1,9 +1,11 @@
import { useState, useEffect } from 'react';
import PageMeta from '../../components/common/PageMeta';
import PageHeader from '../../components/common/PageHeader';
import ModuleNavigationTabs from '../../components/navigation/ModuleNavigationTabs';
import Button from '../../components/ui/button/Button';
import TextArea from '../../components/form/input/TextArea';
import { useToast } from '../../components/ui/toast/ToastContainer';
import { BoltIcon } from '../../icons';
import { BoltIcon, UserIcon, ShootingStarIcon, ImageIcon } from '../../icons';
import { fetchAPI } from '../../services/api';
interface PromptData {
@@ -197,23 +199,23 @@ export default function Prompts() {
);
}
// Thinker navigation tabs
const thinkerTabs = [
{ label: 'Prompts', path: '/thinker/prompts', icon: <BoltIcon /> },
{ label: 'Author Profiles', path: '/thinker/author-profiles', icon: <UserIcon /> },
{ label: 'Strategies', path: '/thinker/strategies', icon: <ShootingStarIcon /> },
{ label: 'Image Testing', path: '/thinker/image-testing', icon: <ImageIcon /> },
];
return (
<>
<PageMeta title="Prompts - IGNY8" description="AI prompts management" />
<PageHeader
title="AI Prompts Management"
badge={{ icon: <BoltIcon />, color: 'orange' }}
/>
<ModuleNavigationTabs tabs={thinkerTabs} />
<div className="p-6">
{/* Page Header */}
<div className="mb-6">
<div className="flex items-center gap-3 mb-2">
<BoltIcon className="text-primary-500 size-6" />
<h1 className="text-2xl font-semibold text-gray-800 dark:text-white">
AI Prompts Management
</h1>
</div>
<p className="text-gray-600 dark:text-gray-400">
Configure AI prompt templates for clustering, idea generation, content writing, and image generation
</p>
</div>
{/* Planner Prompts Section */}
<div className="mb-8">

View File

@@ -1,11 +1,26 @@
import PageMeta from "../../components/common/PageMeta";
import PageHeader from "../../components/common/PageHeader";
import ModuleNavigationTabs from "../../components/navigation/ModuleNavigationTabs";
import ComponentCard from "../../components/common/ComponentCard";
import { BoltIcon, UserIcon, ShootingStarIcon, ImageIcon } from "../../icons";
export default function Strategies() {
// Thinker navigation tabs
const thinkerTabs = [
{ label: 'Prompts', path: '/thinker/prompts', icon: <BoltIcon /> },
{ label: 'Author Profiles', path: '/thinker/author-profiles', icon: <UserIcon /> },
{ label: 'Strategies', path: '/thinker/strategies', icon: <ShootingStarIcon /> },
{ label: 'Image Testing', path: '/thinker/image-testing', icon: <ImageIcon /> },
];
return (
<>
<PageMeta title="Strategies - IGNY8" description="Content strategies" />
<PageHeader
title="Content Strategies"
badge={{ icon: <ShootingStarIcon />, color: 'purple' }}
/>
<ModuleNavigationTabs tabs={thinkerTabs} />
<ComponentCard title="Coming Soon" desc="Content strategies">
<div className="text-center py-8">
<p className="text-gray-600 dark:text-gray-400">

View File

@@ -14,13 +14,14 @@ import {
import { optimizerApi } from '../../api/optimizer.api';
import { useNavigate } from 'react-router';
import { useToast } from '../../components/ui/toast/ToastContainer';
import { FileIcon } from '../../icons';
import { FileIcon, TaskIcon, ImageIcon, CheckCircleIcon } from '../../icons';
import { createContentPageConfig } from '../../config/pages/content.config';
import { useSectorStore } from '../../store/sectorStore';
import { usePageSizeStore } from '../../store/pageSizeStore';
import ProgressModal from '../../components/common/ProgressModal';
import { useProgressModal } from '../../hooks/useProgressModal';
import PageHeader from '../../components/common/PageHeader';
import ModuleNavigationTabs from '../../components/navigation/ModuleNavigationTabs';
export default function Content() {
const toast = useToast();
@@ -197,12 +198,21 @@ export default function Content() {
}
}, [toast, progressModal, loadContent, navigate]);
// Writer navigation tabs
const writerTabs = [
{ label: 'Tasks', path: '/writer/tasks', icon: <TaskIcon /> },
{ label: 'Content', path: '/writer/content', icon: <FileIcon /> },
{ label: 'Images', path: '/writer/images', icon: <ImageIcon /> },
{ label: 'Published', path: '/writer/published', icon: <CheckCircleIcon /> },
];
return (
<>
<PageHeader
title="Content"
badge={{ icon: <FileIcon />, color: 'purple' }}
/>
<ModuleNavigationTabs tabs={writerTabs} />
<TablePageTemplate
columns={pageConfig.columns}
data={content}

View File

@@ -15,12 +15,13 @@ import {
ContentImage,
} from '../../services/api';
import { useToast } from '../../components/ui/toast/ToastContainer';
import { FileIcon, DownloadIcon, BoltIcon } from '../../icons';
import { FileIcon, DownloadIcon, BoltIcon, TaskIcon, ImageIcon, CheckCircleIcon } from '../../icons';
import { createImagesPageConfig } from '../../config/pages/images.config';
import ImageQueueModal, { ImageQueueItem } from '../../components/common/ImageQueueModal';
import SingleRecordStatusUpdateModal from '../../components/common/SingleRecordStatusUpdateModal';
import { useResourceDebug } from '../../hooks/useResourceDebug';
import PageHeader from '../../components/common/PageHeader';
import ModuleNavigationTabs from '../../components/navigation/ModuleNavigationTabs';
import { Modal } from '../../components/ui/modal';
export default function Images() {
@@ -460,12 +461,21 @@ export default function Images() {
}));
}, [pageConfig?.headerMetrics, images, totalCount]);
// Writer navigation tabs
const writerTabs = [
{ label: 'Tasks', path: '/writer/tasks', icon: <TaskIcon /> },
{ label: 'Content', path: '/writer/content', icon: <FileIcon /> },
{ label: 'Images', path: '/writer/images', icon: <ImageIcon /> },
{ label: 'Published', path: '/writer/published', icon: <CheckCircleIcon /> },
];
return (
<>
<PageHeader
title="Content Images"
badge={{ icon: <FileIcon />, color: 'orange' }}
/>
<ModuleNavigationTabs tabs={writerTabs} />
<TablePageTemplate
columns={pageConfig.columns}
data={images}

View File

@@ -25,11 +25,12 @@ import ProgressModal from '../../components/common/ProgressModal';
import { useProgressModal } from '../../hooks/useProgressModal';
import { useResourceDebug } from '../../hooks/useResourceDebug';
import { useToast } from '../../components/ui/toast/ToastContainer';
import { TaskIcon, PlusIcon, DownloadIcon } from '../../icons';
import { TaskIcon, PlusIcon, DownloadIcon, FileIcon, ImageIcon, CheckCircleIcon } from '../../icons';
import { createTasksPageConfig } from '../../config/pages/tasks.config';
import { useSectorStore } from '../../store/sectorStore';
import { usePageSizeStore } from '../../store/pageSizeStore';
import PageHeader from '../../components/common/PageHeader';
import ModuleNavigationTabs from '../../components/navigation/ModuleNavigationTabs';
export default function Tasks() {
const toast = useToast();
@@ -559,12 +560,21 @@ export default function Tasks() {
}
};
// Writer navigation tabs
const writerTabs = [
{ label: 'Tasks', path: '/writer/tasks', icon: <TaskIcon /> },
{ label: 'Content', path: '/writer/content', icon: <FileIcon /> },
{ label: 'Images', path: '/writer/images', icon: <ImageIcon /> },
{ label: 'Published', path: '/writer/published', icon: <CheckCircleIcon /> },
];
return (
<>
<PageHeader
title="Tasks"
badge={{ icon: <TaskIcon />, color: 'indigo' }}
/>
<ModuleNavigationTabs tabs={writerTabs} />
<TablePageTemplate
columns={pageConfig.columns}
data={tasks}