mgbam commited on
Commit
7211e95
·
verified ·
1 Parent(s): 3979311

Create src/components/WorkshopGenerator.jsx

Browse files
Files changed (1) hide show
  1. src/components/WorkshopGenerator.jsx +148 -0
src/components/WorkshopGenerator.jsx ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useCallback } from 'react';
2
+ import { Zap } from 'lucide-react';
3
+
4
+ // Import sub-components for each step
5
+ import Header from './Header';
6
+ import SetupScreen from './SetupScreen';
7
+ import InputScreen from './InputScreen';
8
+ import GeneratingScreen from './GeneratingScreen';
9
+ import PreviewScreen from './PreviewScreen';
10
+
11
+ // Import the API services
12
+ import { callAnthropicAPI } from '../services/anthropic';
13
+ import { callHuggingFaceAPI } from '../services/huggingface'; // New service
14
+ import { getPrompts } from '../services/prompts';
15
+
16
+ const WorkshopGenerator = () => {
17
+ const [currentStep, setCurrentStep] = useState('setup');
18
+ const [apiKey, setApiKey] = useState({ anthropic: '', huggingface: '' });
19
+ const [apiProvider, setApiProvider] = useState('anthropic'); // 'anthropic' or 'huggingface'
20
+ const [workshopData, setWorkshopData] = useState({
21
+ topic: '',
22
+ audience: '',
23
+ duration: '90',
24
+ difficulty: 'intermediate'
25
+ });
26
+ const [generatedContent, setGeneratedContent] = useState(null);
27
+ const [isGenerating, setIsGenerating] = useState(false);
28
+ const [activeAgent, setActiveAgent] = useState('');
29
+ const [error, setError] = useState('');
30
+
31
+ const getApiCallFunction = useCallback(() => {
32
+ if (apiProvider === 'huggingface') {
33
+ return (prompt, maxTokens) => callHuggingFaceAPI(prompt, apiKey.huggingface, maxTokens);
34
+ }
35
+ // Default to Anthropic
36
+ return (prompt, maxTokens) => callAnthropicAPI(prompt, apiKey.anthropic, maxTokens);
37
+ }, [apiProvider, apiKey]);
38
+
39
+ const generateWorkshop = async () => {
40
+ setIsGenerating(true);
41
+ setCurrentStep('generating');
42
+ setError('');
43
+ const callAPI = getApiCallFunction();
44
+ const prompts = getPrompts(workshopData);
45
+
46
+ try {
47
+ const runAgent = async (agentName, prompt, maxTokens) => {
48
+ setActiveAgent(agentName);
49
+ const response = await callAPI(prompt, maxTokens);
50
+ const cleanResponse = response.replace(/```json\n?/, "").replace(/```\n?/, "").trim();
51
+ try {
52
+ return JSON.parse(cleanResponse);
53
+ } catch (parseError) {
54
+ console.error(`Error parsing JSON from ${agentName}:`, parseError, "Raw response:", response);
55
+ throw new Error(`Agent "${agentName}" returned invalid data. Please try again.`);
56
+ }
57
+ };
58
+
59
+ // Run the agent pipeline
60
+ const topicData = await runAgent('topic', prompts.topic, 1500);
61
+ const contentData = await runAgent('content', prompts.content(JSON.stringify(topicData)), 3000);
62
+ const slideData = await runAgent('slide', prompts.slide(JSON.stringify(contentData)), 4000);
63
+ const codeData = await runAgent('code', prompts.code(JSON.stringify(topicData)), 3000);
64
+
65
+ // Combine results
66
+ setGeneratedContent({
67
+ topic: topicData,
68
+ content: contentData,
69
+ slides: slideData,
70
+ code: codeData,
71
+ metadata: {
72
+ title: topicData.title || workshopData.topic,
73
+ modules: topicData.modules?.length || 0,
74
+ slideCount: slideData.slide_count || slideData.slides?.length || 0,
75
+ exercises: codeData.exercises?.length || 0,
76
+ generatedAt: new Date().toISOString(),
77
+ provider: apiProvider
78
+ }
79
+ });
80
+
81
+ setCurrentStep('preview');
82
+ } catch (err) {
83
+ console.error("Workshop generation error:", err);
84
+ setError(err.message);
85
+ setCurrentStep('input');
86
+ } finally {
87
+ setIsGenerating(false);
88
+ setActiveAgent('');
89
+ }
90
+ };
91
+
92
+ const resetGenerator = () => {
93
+ setCurrentStep('input');
94
+ setGeneratedContent(null);
95
+ setWorkshopData({ topic: '', audience: '', duration: '90', difficulty: 'intermediate' });
96
+ setError('');
97
+ };
98
+
99
+ const renderStep = () => {
100
+ switch (currentStep) {
101
+ case 'setup':
102
+ return <SetupScreen
103
+ apiKey={apiKey}
104
+ setApiKey={setApiKey}
105
+ apiProvider={apiProvider}
106
+ setApiProvider={setApiProvider}
107
+ setCurrentStep={setCurrentStep}
108
+ setError={setError}
109
+ getApiCallFunction={getApiCallFunction}
110
+ />;
111
+ case 'input':
112
+ return <InputScreen
113
+ workshopData={workshopData}
114
+ setWorkshopData={setWorkshopData}
115
+ isGenerating={isGenerating}
116
+ generateWorkshop={generateWorkshop}
117
+ setCurrentStep={setCurrentStep}
118
+ />;
119
+ case 'generating':
120
+ return <GeneratingScreen activeAgent={activeAgent} />;
121
+ case 'preview':
122
+ return <PreviewScreen
123
+ generatedContent={generatedContent}
124
+ workshopData={workshopData}
125
+ resetGenerator={resetGenerator}
126
+ />;
127
+ default:
128
+ return <SetupScreen />;
129
+ }
130
+ };
131
+
132
+ return (
133
+ <div className="min-h-screen bg-gray-900 text-white font-sans">
134
+ <Header />
135
+ <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
136
+ {error && (
137
+ <div className="max-w-2xl mx-auto mb-6 bg-red-500/20 border border-red-400 rounded-lg p-4 flex items-center space-x-3">
138
+ <AlertCircle className="w-5 h-5 text-red-400" />
139
+ <span className="text-red-200">{error}</span>
140
+ </div>
141
+ )}
142
+ {renderStep()}
143
+ </main>
144
+ </div>
145
+ );
146
+ };
147
+
148
+ export default WorkshopGenerator;