ALwrity version 0.5.5

This commit is contained in:
ajaysi
2025-08-19 21:48:33 +05:30
parent 5f104bf427
commit 74e22b421a
97 changed files with 16770 additions and 5000 deletions

View File

@@ -0,0 +1,282 @@
import React from 'react';
import { useNavigate } from 'react-router-dom';
export interface StrategyContext {
strategyId: string;
strategyData: any;
activationStatus: 'pending' | 'confirmed' | 'active';
activationTimestamp: string;
userPreferences: any;
strategicIntelligence: any;
}
export interface CalendarContext {
strategyContext: StrategyContext | null;
autoPopulatedData: any;
userModifications: any;
generationProgress: number;
}
export interface WorkflowProgress {
currentStep: 'strategy' | 'activation' | 'calendar' | 'generation';
completedSteps: string[];
totalSteps: number;
progressPercentage: number;
}
export interface NavigationState {
fromStrategy: boolean;
preservedContext: StrategyContext | null;
returnPath: string | null;
}
class NavigationOrchestrator {
private static instance: NavigationOrchestrator;
private contextStorage: Map<string, any> = new Map();
private progressTracking: WorkflowProgress = {
currentStep: 'strategy',
completedSteps: [],
totalSteps: 4,
progressPercentage: 0
};
private constructor() {}
static getInstance(): NavigationOrchestrator {
if (!NavigationOrchestrator.instance) {
NavigationOrchestrator.instance = new NavigationOrchestrator();
}
return NavigationOrchestrator.instance;
}
/**
* Navigate from strategy activation to calendar wizard
*/
navigateToCalendarWizard(strategyId: string, strategyContext: StrategyContext): void {
console.log('🎯 Navigation Orchestrator: Navigating to calendar wizard', { strategyId });
// Preserve strategy context
this.preserveContext('strategy', strategyContext);
// Update progress
this.updateProgress('activation');
// Store navigation state
this.contextStorage.set('navigationState', {
fromStrategy: true,
preservedContext: strategyContext,
returnPath: '/content-planning'
});
// Also store in session storage for context restoration
sessionStorage.setItem('strategyCalendarContext', JSON.stringify({
strategyContext,
lastUpdated: new Date().toISOString()
}));
// Navigate to calendar wizard with context
const navigate = this.getNavigateFunction();
if (navigate) {
navigate('/content-planning', {
state: {
activeTab: 4, // Create tab (where Calendar Wizard is located)
strategyContext,
fromStrategyActivation: true
}
});
}
}
/**
* Preserve context for later restoration
*/
preserveContext(key: string, context: any): void {
console.log('💾 Navigation Orchestrator: Preserving context', { key });
this.contextStorage.set(key, {
data: context,
timestamp: new Date().toISOString(),
expiresAt: new Date(Date.now() + 30 * 60 * 1000).toISOString() // 30 minutes
});
}
/**
* Restore context by key
*/
restoreContext(key: string): any | null {
const stored = this.contextStorage.get(key);
if (!stored) {
console.log('⚠️ Navigation Orchestrator: No context found for key', { key });
return null;
}
// Check if context has expired
if (new Date() > new Date(stored.expiresAt)) {
console.log('⏰ Navigation Orchestrator: Context expired for key', { key });
this.contextStorage.delete(key);
return null;
}
console.log('🔄 Navigation Orchestrator: Restoring context', { key });
return stored.data;
}
/**
* Clear context by key
*/
clearContext(key: string): void {
console.log('🗑️ Navigation Orchestrator: Clearing context', { key });
this.contextStorage.delete(key);
}
/**
* Clear all contexts
*/
clearAllContexts(): void {
console.log('🗑️ Navigation Orchestrator: Clearing all contexts');
this.contextStorage.clear();
}
/**
* Update workflow progress
*/
updateProgress(step: WorkflowProgress['currentStep']): void {
const steps = ['strategy', 'activation', 'calendar', 'generation'];
const currentIndex = steps.indexOf(step);
this.progressTracking = {
currentStep: step,
completedSteps: steps.slice(0, currentIndex),
totalSteps: steps.length,
progressPercentage: ((currentIndex + 1) / steps.length) * 100
};
console.log('📊 Navigation Orchestrator: Progress updated', this.progressTracking);
}
/**
* Get current progress
*/
getProgress(): WorkflowProgress {
return { ...this.progressTracking };
}
/**
* Track navigation event
*/
trackNavigation(from: string, to: string, context?: any): void {
console.log('🧭 Navigation Orchestrator: Navigation tracked', { from, to, hasContext: !!context });
// Store navigation history
const history = this.contextStorage.get('navigationHistory') || [];
history.push({
from,
to,
timestamp: new Date().toISOString(),
context: context ? Object.keys(context) : []
});
// Keep only last 10 navigation events
if (history.length > 10) {
history.splice(0, history.length - 10);
}
this.contextStorage.set('navigationHistory', history);
}
/**
* Get navigation state
*/
getNavigationState(): NavigationState | null {
return this.contextStorage.get('navigationState') || null;
}
/**
* Check if navigation is from strategy activation
*/
isFromStrategyActivation(): boolean {
const state = this.getNavigationState();
return state?.fromStrategy || false;
}
/**
* Get preserved strategy context
*/
getPreservedStrategyContext(): StrategyContext | null {
return this.restoreContext('strategy');
}
/**
* Handle strategy activation success
*/
handleStrategyActivationSuccess(strategyId: string, strategyData: any): void {
console.log('✅ Navigation Orchestrator: Strategy activation successful', { strategyId });
const strategyContext: StrategyContext = {
strategyId,
strategyData,
activationStatus: 'active',
activationTimestamp: new Date().toISOString(),
userPreferences: strategyData.userPreferences || {},
strategicIntelligence: strategyData.strategicIntelligence || {}
};
// Navigate to calendar wizard
this.navigateToCalendarWizard(strategyId, strategyContext);
}
/**
* Handle calendar generation completion
*/
handleCalendarGenerationComplete(calendarData: any): void {
console.log('✅ Navigation Orchestrator: Calendar generation complete');
// Update progress
this.updateProgress('generation');
// Clear strategy context as workflow is complete
this.clearContext('strategy');
// Navigate to calendar view
const navigate = this.getNavigateFunction();
if (navigate) {
navigate('/content-planning', {
state: {
activeTab: 1, // Calendar tab
showGeneratedCalendar: true,
calendarData
}
});
}
}
/**
* Get navigate function (to be set by components)
*/
private getNavigateFunction(): any {
// Return the stored navigate function
return (this as any).navigate;
}
/**
* Set navigate function (called by components)
*/
setNavigateFunction(navigate: any): void {
// Store navigate function for internal use
(this as any).navigate = navigate;
}
}
// Export singleton instance
export const navigationOrchestrator = NavigationOrchestrator.getInstance();
// Hook for components to use the orchestrator
export const useNavigationOrchestrator = () => {
const navigate = useNavigate();
// Set navigate function in orchestrator only once
React.useEffect(() => {
navigationOrchestrator.setNavigateFunction(navigate);
}, [navigate]);
return navigationOrchestrator;
};

View File

@@ -0,0 +1,259 @@
import { apiClient } from '../api/client';
import { useState } from 'react';
export interface MonitoringTask {
component: string;
title: string;
description: string;
assignee: 'ALwrity' | 'Human';
frequency: string;
metric: string;
measurementMethod: string;
successCriteria: string;
alertThreshold: string;
actionableInsights: string;
}
export interface MonitoringComponent {
name: string;
icon: string;
tasks: MonitoringTask[];
}
export interface MonitoringPlan {
totalTasks: number;
alwrityTasks: number;
humanTasks: number;
metricsCount: number;
monitoringTasks: MonitoringTask[];
monitoringSchedule?: any;
successMetrics?: any;
metadata?: any;
}
export const strategyMonitoringApi = {
/**
* Generate monitoring plan for a strategy
*/
async generateMonitoringPlan(strategyId: number): Promise<{ success: boolean; data: MonitoringPlan; message: string }> {
try {
const response = await apiClient.post(`/api/content-planning/strategy/${strategyId}/generate-monitoring-plan`);
return response.data;
} catch (error: any) {
console.error('Error generating monitoring plan:', error);
throw new Error(error.response?.data?.detail || 'Failed to generate monitoring plan');
}
},
/**
* Activate strategy with monitoring plan
*/
async activateStrategyWithMonitoring(strategyId: number, monitoringPlan: MonitoringPlan): Promise<{ success: boolean; message: string; strategy_id: number }> {
try {
const response = await apiClient.post(`/api/content-planning/strategy/${strategyId}/activate-with-monitoring`, monitoringPlan);
return response.data;
} catch (error: any) {
console.error('Error activating strategy with monitoring:', error);
throw new Error(error.response?.data?.detail || 'Failed to activate strategy with monitoring');
}
},
/**
* Get monitoring plan for a strategy
*/
async getMonitoringPlan(strategyId: number): Promise<{ success: boolean; data: any }> {
try {
const response = await apiClient.get(`/api/content-planning/strategy/${strategyId}/monitoring-plan`);
return response.data;
} catch (error: any) {
console.error('Error getting monitoring plan:', error);
throw new Error(error.response?.data?.detail || 'Failed to get monitoring plan');
}
},
/**
* Update monitoring plan
*/
async updateMonitoringPlan(strategyId: number, monitoringPlan: Partial<MonitoringPlan>): Promise<{ success: boolean; message: string }> {
try {
const response = await apiClient.put(`/api/content-planning/strategy/${strategyId}/monitoring-plan`, monitoringPlan);
return response.data;
} catch (error: any) {
console.error('Error updating monitoring plan:', error);
throw new Error(error.response?.data?.detail || 'Failed to update monitoring plan');
}
},
/**
* Get performance history for a strategy
*/
async getPerformanceHistory(strategyId: number, days: number = 30): Promise<{ success: boolean; data: any }> {
try {
const response = await apiClient.get(`/content-planning/strategy/${strategyId}/performance-history?days=${days}`);
return response.data;
} catch (error: any) {
console.error('Error getting performance history:', error);
throw new Error(error.response?.data?.detail || 'Failed to get performance history');
}
},
/**
* Deactivate a strategy
*/
async deactivateStrategy(strategyId: number, userId: number = 1): Promise<{ success: boolean; message: string }> {
try {
const response = await apiClient.post(`/api/content-planning/strategy/${strategyId}/deactivate`, { user_id: userId });
return response.data;
} catch (error: any) {
console.error('Error deactivating strategy:', error);
throw new Error(error.response?.data?.detail || 'Failed to deactivate strategy');
}
},
/**
* Pause a strategy
*/
async pauseStrategy(strategyId: number, userId: number = 1): Promise<{ success: boolean; message: string }> {
try {
const response = await apiClient.post(`/api/content-planning/strategy/${strategyId}/pause`, { user_id: userId });
return response.data;
} catch (error: any) {
console.error('Error pausing strategy:', error);
throw new Error(error.response?.data?.detail || 'Failed to pause strategy');
}
},
/**
* Resume a strategy
*/
async resumeStrategy(strategyId: number, userId: number = 1): Promise<{ success: boolean; message: string }> {
try {
const response = await apiClient.post(`/api/content-planning/strategy/${strategyId}/resume`, { user_id: userId });
return response.data;
} catch (error: any) {
console.error('Error resuming strategy:', error);
throw new Error(error.response?.data?.detail || 'Failed to resume strategy');
}
},
/**
* Get performance metrics for a strategy
*/
async getPerformanceMetrics(strategyId: number): Promise<{ success: boolean; data: any; message: string }> {
try {
const response = await apiClient.get(`/api/content-planning/strategy/${strategyId}/performance-metrics`);
return response.data;
} catch (error: any) {
console.error('Error getting performance metrics:', error);
throw new Error(error.response?.data?.detail || 'Failed to get performance metrics');
}
},
/**
* Get trend data for a strategy
*/
async getTrendData(strategyId: number, timeRange: string = '30d'): Promise<{ success: boolean; data: any; message: string }> {
try {
const response = await apiClient.get(`/api/content-planning/strategy/${strategyId}/trend-data?time_range=${timeRange}`);
return response.data;
} catch (error: any) {
console.error('Error getting trend data:', error);
throw new Error(error.response?.data?.detail || 'Failed to get trend data');
}
},
// New API calls for transparency data
async getTransparencyData(strategyId: number): Promise<{ success: boolean; data: any; message: string }> {
try {
const response = await apiClient.get(`/api/content-planning/strategy/${strategyId}/transparency-data`);
return response.data;
} catch (error: any) {
console.error('Error fetching transparency data:', error);
throw new Error(error.response?.data?.detail || 'Failed to fetch transparency data');
}
},
async getMonitoringTasks(strategyId: number): Promise<{ success: boolean; data: any; message: string }> {
try {
const response = await apiClient.get(`/api/content-planning/strategy/${strategyId}/monitoring-tasks`);
return response.data;
} catch (error: any) {
console.error('Error fetching monitoring tasks:', error);
throw new Error(error.response?.data?.detail || 'Failed to fetch monitoring tasks');
}
},
async getDataFreshness(strategyId: number): Promise<{ success: boolean; data: any; message: string }> {
try {
const response = await apiClient.get(`/api/content-planning/strategy/${strategyId}/data-freshness`);
return response.data;
} catch (error: any) {
console.error('Error fetching data freshness:', error);
throw new Error(error.response?.data?.detail || 'Failed to fetch data freshness');
}
},
// Quality Analysis API methods
async getQualityAnalysis(strategyId: number): Promise<{ success: boolean; data: any; message: string }> {
try {
const response = await apiClient.post(`/api/content-planning/quality-analysis/${strategyId}/analyze`);
return response.data;
} catch (error: any) {
console.error('Error fetching quality analysis:', error);
throw new Error(error.response?.data?.detail || 'Failed to fetch quality analysis');
}
},
async getQualityMetrics(strategyId: number): Promise<{ success: boolean; data: any; message: string }> {
try {
const response = await apiClient.get(`/api/content-planning/quality-analysis/${strategyId}/metrics`);
return response.data;
} catch (error: any) {
console.error('Error fetching quality metrics:', error);
throw new Error(error.response?.data?.detail || 'Failed to fetch quality metrics');
}
},
async getQualityRecommendations(strategyId: number): Promise<{ success: boolean; data: any; message: string }> {
try {
const response = await apiClient.get(`/api/content-planning/quality-analysis/${strategyId}/recommendations`);
return response.data;
} catch (error: any) {
console.error('Error fetching quality recommendations:', error);
throw new Error(error.response?.data?.detail || 'Failed to fetch quality recommendations');
}
},
async getQualityDashboard(strategyId: number): Promise<{ success: boolean; data: any; message: string }> {
try {
const response = await apiClient.get(`/api/content-planning/quality-analysis/${strategyId}/dashboard`);
return response.data;
} catch (error: any) {
console.error('Error fetching quality dashboard:', error);
throw new Error(error.response?.data?.detail || 'Failed to fetch quality dashboard');
}
}
};
// Hook for monitoring plan generation
export const useMonitoringPlanGeneration = () => {
const [isGenerating, setIsGenerating] = useState(false);
const [error, setError] = useState<string | null>(null);
const generatePlan = async (strategyId: number): Promise<MonitoringPlan> => {
setIsGenerating(true);
setError(null);
try {
const response = await strategyMonitoringApi.generateMonitoringPlan(strategyId);
return response.data;
} catch (err: any) {
setError(err.message);
throw err;
} finally {
setIsGenerating(false);
}
};
return { generatePlan, isGenerating, error };
};