Skip to content

Commit 338e187

Browse files
authored
Merge pull request #38 from GizzZmo/copilot/fix-bb8db764-5a80-4c4b-a8dc-f8593e6591ba
feat: Add new pages with Prompt Library, Model Comparison, Analytics, and Help Documentation
2 parents ff3734c + 8b34136 commit 338e187

7 files changed

Lines changed: 1394 additions & 41 deletions

File tree

src/App.tsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import Header from './components/layout/Header';
33
import Sidebar from './components/layout/Sidebar';
44
import DashboardPage from './pages/DashboardPage';
55
import { PromptEditorPage } from './pages/PromptEditor/PromptEditorPage';
6+
import PromptLibraryPage from './pages/PromptLibraryPage';
67
import { AIToolkitPage } from './pages/AIToolkit/AIToolkitPage';
8+
import ModelComparisonPage from './pages/ModelComparisonPage';
9+
import AnalyticsPage from './pages/AnalyticsPage';
10+
import HelpPage from './pages/HelpPage';
711
import SettingsPage from './pages/SettingsPage';
812
import { AIProvider } from './context/AIContext';
913
import { ToastProvider } from './context/ToastContext';
@@ -62,17 +66,36 @@ function AppContent() {
6266
<PromptEditorPage />
6367
</PageErrorBoundary>
6468
} />
69+
<Route path="/prompt-library" element={
70+
<PageErrorBoundary pageName="Prompt Library">
71+
<PromptLibraryPage />
72+
</PageErrorBoundary>
73+
} />
6574
<Route path="/ai-toolkit" element={
6675
<PageErrorBoundary pageName="AI Toolkit">
6776
<AIToolkitPage />
6877
</PageErrorBoundary>
6978
} />
79+
<Route path="/model-comparison" element={
80+
<PageErrorBoundary pageName="Model Comparison">
81+
<ModelComparisonPage />
82+
</PageErrorBoundary>
83+
} />
84+
<Route path="/analytics" element={
85+
<PageErrorBoundary pageName="Analytics">
86+
<AnalyticsPage />
87+
</PageErrorBoundary>
88+
} />
89+
<Route path="/help" element={
90+
<PageErrorBoundary pageName="Help">
91+
<HelpPage />
92+
</PageErrorBoundary>
93+
} />
7094
<Route path="/settings" element={
7195
<PageErrorBoundary pageName="Settings">
7296
<SettingsPage />
7397
</PageErrorBoundary>
7498
} />
75-
{/* TODO: Add more routes for specific toolkit functionalities */}
7699
</Routes>
77100
</div>
78101
</div>

src/components/layout/Sidebar.tsx

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
11
import React from 'react';
2-
import { Link } from 'react-router-dom';
2+
import { Link, useLocation } from 'react-router-dom';
33

44
const Sidebar: React.FC = () => {
5+
const location = useLocation();
6+
7+
const isActive = (path: string) => location.pathname === path;
8+
9+
const linkStyle = (path: string) => ({
10+
color: 'white',
11+
textDecoration: 'none',
12+
padding: '10px 15px',
13+
display: 'flex',
14+
alignItems: 'center',
15+
gap: '10px',
16+
borderRadius: '5px',
17+
backgroundColor: isActive(path) ? 'rgba(255, 255, 255, 0.1)' : 'transparent',
18+
transition: 'background-color 0.2s',
19+
fontWeight: isActive(path) ? '600' : '400'
20+
});
21+
522
return (
623
<aside style={{
724
width: 'var(--sidebar-width)',
@@ -12,22 +29,57 @@ const Sidebar: React.FC = () => {
1229
height: '100%',
1330
overflowY: 'auto'
1431
}}>
15-
<h2 style={{ textAlign: 'center', marginBottom: '30px' }}>AI Orchestrator</h2>
32+
<h2 style={{ textAlign: 'center', marginBottom: '30px' }}>🤖 AI Orchestrator</h2>
1633
<nav>
1734
<ul style={{ listStyle: 'none', padding: 0 }}>
18-
<li style={{ marginBottom: '10px' }}>
19-
<Link to="/" style={{ color: 'white', textDecoration: 'none', padding: '10px 15px', display: 'block', borderRadius: '5px' }}>Dashboard</Link>
35+
<li style={{ marginBottom: '8px' }}>
36+
<Link to="/" style={linkStyle('/')}>
37+
<span style={{ fontSize: '18px' }}>🏠</span>
38+
<span>Dashboard</span>
39+
</Link>
40+
</li>
41+
<li style={{ marginBottom: '8px' }}>
42+
<Link to="/prompt-editor" style={linkStyle('/prompt-editor')}>
43+
<span style={{ fontSize: '18px' }}>📝</span>
44+
<span>Master Prompt Editor</span>
45+
</Link>
46+
</li>
47+
<li style={{ marginBottom: '8px' }}>
48+
<Link to="/prompt-library" style={linkStyle('/prompt-library')}>
49+
<span style={{ fontSize: '18px' }}>📚</span>
50+
<span>Prompt Library</span>
51+
</Link>
52+
</li>
53+
<li style={{ marginBottom: '8px' }}>
54+
<Link to="/ai-toolkit" style={linkStyle('/ai-toolkit')}>
55+
<span style={{ fontSize: '18px' }}>🛠️</span>
56+
<span>Advanced AI Toolkit</span>
57+
</Link>
58+
</li>
59+
<li style={{ marginBottom: '8px' }}>
60+
<Link to="/model-comparison" style={linkStyle('/model-comparison')}>
61+
<span style={{ fontSize: '18px' }}>🔍</span>
62+
<span>Model Comparison</span>
63+
</Link>
2064
</li>
21-
<li style={{ marginBottom: '10px' }}>
22-
<Link to="/prompt-editor" style={{ color: 'white', textDecoration: 'none', padding: '10px 15px', display: 'block', borderRadius: '5px' }}>Master Prompt Editor</Link>
65+
<li style={{ marginBottom: '8px' }}>
66+
<Link to="/analytics" style={linkStyle('/analytics')}>
67+
<span style={{ fontSize: '18px' }}>📊</span>
68+
<span>Analytics & Metrics</span>
69+
</Link>
2370
</li>
24-
<li style={{ marginBottom: '10px' }}>
25-
<Link to="/ai-toolkit" style={{ color: 'white', textDecoration: 'none', padding: '10px 15px', display: 'block', borderRadius: '5px' }}>Advanced AI Toolkit</Link>
71+
<li style={{ marginBottom: '8px' }}>
72+
<Link to="/help" style={linkStyle('/help')}>
73+
<span style={{ fontSize: '18px' }}></span>
74+
<span>Help & Documentation</span>
75+
</Link>
2676
</li>
27-
<li style={{ marginBottom: '10px' }}>
28-
<Link to="/settings" style={{ color: 'white', textDecoration: 'none', padding: '10px 15px', display: 'block', borderRadius: '5px' }}>Settings</Link>
77+
<li style={{ marginBottom: '8px', marginTop: '20px', paddingTop: '20px', borderTop: '1px solid rgba(255, 255, 255, 0.1)' }}>
78+
<Link to="/settings" style={linkStyle('/settings')}>
79+
<span style={{ fontSize: '18px' }}>⚙️</span>
80+
<span>Settings</span>
81+
</Link>
2982
</li>
30-
{/* TODO: Add more navigation links based on 'Swiss Army Knife' functionality */}
3183
</ul>
3284
</nav>
3385
</aside>

src/pages/AnalyticsPage.tsx

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
import React, { useState, useMemo } from 'react';
2+
3+
type TimeRange = '24h' | '7d' | '30d' | '90d';
4+
5+
interface ActivityLog {
6+
id: string;
7+
type: 'success' | 'warning' | 'error';
8+
message: string;
9+
timestamp: string;
10+
model?: string;
11+
}
12+
13+
interface ModelUsage {
14+
name: string;
15+
usage: number;
16+
percentage: number;
17+
}
18+
19+
const AnalyticsPage: React.FC = () => {
20+
const [timeRange, setTimeRange] = useState<TimeRange>('7d');
21+
22+
// Mock data - would come from API in production
23+
const metrics = useMemo(() => {
24+
const baseMetrics = {
25+
totalPrompts: 1247,
26+
avgResponseTime: 2.3,
27+
successRate: 96.8,
28+
apiCost: 142.50
29+
};
30+
31+
// Adjust metrics based on time range
32+
const multipliers = {
33+
'24h': 0.1,
34+
'7d': 1,
35+
'30d': 4,
36+
'90d': 12
37+
};
38+
39+
const multiplier = multipliers[timeRange];
40+
41+
return {
42+
totalPrompts: Math.round(baseMetrics.totalPrompts * multiplier),
43+
avgResponseTime: baseMetrics.avgResponseTime,
44+
successRate: baseMetrics.successRate,
45+
apiCost: baseMetrics.apiCost * multiplier
46+
};
47+
}, [timeRange]);
48+
49+
const modelUsage: ModelUsage[] = [
50+
{ name: 'GPT-4', usage: 485, percentage: 39 },
51+
{ name: 'Claude 3 Opus', usage: 374, percentage: 30 },
52+
{ name: 'GPT-4 Turbo', usage: 249, percentage: 20 },
53+
{ name: 'Gemini Pro', usage: 87, percentage: 7 },
54+
{ name: 'Others', usage: 52, percentage: 4 }
55+
];
56+
57+
const recentActivities: ActivityLog[] = [
58+
{ id: '1', type: 'success', message: 'Prompt optimization completed', timestamp: '2 minutes ago', model: 'GPT-4' },
59+
{ id: '2', type: 'success', message: 'Code review workflow executed', timestamp: '15 minutes ago', model: 'Claude 3' },
60+
{ id: '3', type: 'warning', message: 'High latency detected (3.8s)', timestamp: '1 hour ago', model: 'GPT-4 Turbo' },
61+
{ id: '4', type: 'success', message: 'Batch processing completed (50 items)', timestamp: '2 hours ago' },
62+
{ id: '5', type: 'error', message: 'API rate limit reached', timestamp: '3 hours ago', model: 'Gemini Pro' },
63+
{ id: '6', type: 'success', message: 'Marketing copy generated', timestamp: '4 hours ago', model: 'GPT-4' },
64+
{ id: '7', type: 'success', message: 'Data analysis completed', timestamp: '5 hours ago', model: 'Claude 3' },
65+
{ id: '8', type: 'warning', message: 'Token limit exceeded, truncated', timestamp: '6 hours ago' }
66+
];
67+
68+
const getStatusIcon = (type: string) => {
69+
switch (type) {
70+
case 'success': return '✅';
71+
case 'warning': return '⚠️';
72+
case 'error': return '❌';
73+
default: return '📝';
74+
}
75+
};
76+
77+
const getStatusColor = (type: string) => {
78+
switch (type) {
79+
case 'success': return '#28a745';
80+
case 'warning': return '#ffc107';
81+
case 'error': return '#dc3545';
82+
default: return '#6c757d';
83+
}
84+
};
85+
86+
return (
87+
<div>
88+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '20px' }}>
89+
<h2>📊 Analytics & Metrics</h2>
90+
91+
{/* Time Range Filter */}
92+
<div style={{ display: 'flex', gap: '5px' }}>
93+
{(['24h', '7d', '30d', '90d'] as TimeRange[]).map(range => (
94+
<button
95+
key={range}
96+
onClick={() => setTimeRange(range)}
97+
style={{
98+
padding: '8px 16px',
99+
backgroundColor: timeRange === range ? '#007bff' : 'white',
100+
color: timeRange === range ? 'white' : '#212529',
101+
border: '1px solid #dee2e6',
102+
borderRadius: '4px',
103+
cursor: 'pointer',
104+
fontSize: '14px',
105+
fontWeight: timeRange === range ? '600' : '400'
106+
}}
107+
>
108+
{range}
109+
</button>
110+
))}
111+
</div>
112+
</div>
113+
114+
{/* Key Metrics */}
115+
<div style={{
116+
display: 'grid',
117+
gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))',
118+
gap: '20px',
119+
marginBottom: '30px'
120+
}}>
121+
<div style={{
122+
backgroundColor: 'white',
123+
padding: '20px',
124+
borderRadius: '8px',
125+
border: '1px solid #e9ecef',
126+
boxShadow: '0 1px 3px rgba(0,0,0,0.1)'
127+
}}>
128+
<div style={{ fontSize: '14px', color: '#6c757d', marginBottom: '8px' }}>Total Prompts Executed</div>
129+
<div style={{ fontSize: '32px', fontWeight: 'bold', color: '#212529' }}>{metrics.totalPrompts.toLocaleString()}</div>
130+
<div style={{ fontSize: '12px', color: '#28a745', marginTop: '8px' }}>↑ 12% from previous period</div>
131+
</div>
132+
133+
<div style={{
134+
backgroundColor: 'white',
135+
padding: '20px',
136+
borderRadius: '8px',
137+
border: '1px solid #e9ecef',
138+
boxShadow: '0 1px 3px rgba(0,0,0,0.1)'
139+
}}>
140+
<div style={{ fontSize: '14px', color: '#6c757d', marginBottom: '8px' }}>Avg Response Time</div>
141+
<div style={{ fontSize: '32px', fontWeight: 'bold', color: '#212529' }}>{metrics.avgResponseTime}s</div>
142+
<div style={{ fontSize: '12px', color: '#28a745', marginTop: '8px' }}>↓ 8% faster</div>
143+
</div>
144+
145+
<div style={{
146+
backgroundColor: 'white',
147+
padding: '20px',
148+
borderRadius: '8px',
149+
border: '1px solid #e9ecef',
150+
boxShadow: '0 1px 3px rgba(0,0,0,0.1)'
151+
}}>
152+
<div style={{ fontSize: '14px', color: '#6c757d', marginBottom: '8px' }}>Success Rate</div>
153+
<div style={{ fontSize: '32px', fontWeight: 'bold', color: '#212529' }}>{metrics.successRate}%</div>
154+
<div style={{ fontSize: '12px', color: '#28a745', marginTop: '8px' }}>↑ 2.3% improvement</div>
155+
</div>
156+
157+
<div style={{
158+
backgroundColor: 'white',
159+
padding: '20px',
160+
borderRadius: '8px',
161+
border: '1px solid #e9ecef',
162+
boxShadow: '0 1px 3px rgba(0,0,0,0.1)'
163+
}}>
164+
<div style={{ fontSize: '14px', color: '#6c757d', marginBottom: '8px' }}>API Costs</div>
165+
<div style={{ fontSize: '32px', fontWeight: 'bold', color: '#212529' }}>${metrics.apiCost.toFixed(2)}</div>
166+
<div style={{ fontSize: '12px', color: '#dc3545', marginTop: '8px' }}>↑ 5% from previous period</div>
167+
</div>
168+
</div>
169+
170+
{/* Top Models by Usage */}
171+
<div style={{
172+
backgroundColor: 'white',
173+
padding: '20px',
174+
borderRadius: '8px',
175+
border: '1px solid #e9ecef',
176+
marginBottom: '30px',
177+
boxShadow: '0 1px 3px rgba(0,0,0,0.1)'
178+
}}>
179+
<h3 style={{ marginTop: 0, marginBottom: '20px' }}>Top Models by Usage</h3>
180+
{modelUsage.map((model, index) => (
181+
<div key={index} style={{ marginBottom: '15px' }}>
182+
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '5px' }}>
183+
<span style={{ fontSize: '14px', fontWeight: '500' }}>{model.name}</span>
184+
<span style={{ fontSize: '14px', color: '#6c757d' }}>
185+
{model.usage} runs ({model.percentage}%)
186+
</span>
187+
</div>
188+
<div style={{
189+
width: '100%',
190+
height: '8px',
191+
backgroundColor: '#e9ecef',
192+
borderRadius: '4px',
193+
overflow: 'hidden'
194+
}}>
195+
<div style={{
196+
width: `${model.percentage}%`,
197+
height: '100%',
198+
backgroundColor: '#007bff',
199+
borderRadius: '4px',
200+
transition: 'width 0.3s ease'
201+
}} />
202+
</div>
203+
</div>
204+
))}
205+
</div>
206+
207+
{/* Recent Activity Feed */}
208+
<div style={{
209+
backgroundColor: 'white',
210+
padding: '20px',
211+
borderRadius: '8px',
212+
border: '1px solid #e9ecef',
213+
boxShadow: '0 1px 3px rgba(0,0,0,0.1)'
214+
}}>
215+
<h3 style={{ marginTop: 0, marginBottom: '20px' }}>Recent Activity</h3>
216+
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
217+
{recentActivities.map(activity => (
218+
<div
219+
key={activity.id}
220+
style={{
221+
display: 'flex',
222+
alignItems: 'start',
223+
padding: '12px',
224+
backgroundColor: '#f8f9fa',
225+
borderRadius: '6px',
226+
borderLeft: `4px solid ${getStatusColor(activity.type)}`
227+
}}
228+
>
229+
<span style={{ fontSize: '20px', marginRight: '12px' }}>
230+
{getStatusIcon(activity.type)}
231+
</span>
232+
<div style={{ flex: 1 }}>
233+
<div style={{ fontSize: '14px', color: '#212529', marginBottom: '4px' }}>
234+
{activity.message}
235+
</div>
236+
<div style={{ fontSize: '12px', color: '#6c757d' }}>
237+
{activity.timestamp}
238+
{activity.model && ` • ${activity.model}`}
239+
</div>
240+
</div>
241+
</div>
242+
))}
243+
</div>
244+
</div>
245+
</div>
246+
);
247+
};
248+
249+
export default AnalyticsPage;

0 commit comments

Comments
 (0)