aceeee commited on
Commit
d62f18c
·
verified ·
1 Parent(s): 2f6a67f

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +6 -4
  2. index.html +902 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Ai Rm Builder 1
3
- emoji: 🌍
4
  colorFrom: purple
5
- colorTo: gray
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: ai-rm-builder-1
3
+ emoji: 🐳
4
  colorFrom: purple
5
+ colorTo: yellow
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,902 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>AI Department Roadmap Builder</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
10
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
11
+ <style>
12
+ .timeline-item:not(:last-child)::after {
13
+ content: '';
14
+ position: absolute;
15
+ left: 24px;
16
+ top: 32px;
17
+ height: calc(100% - 32px);
18
+ width: 2px;
19
+ background-color: #e5e7eb;
20
+ }
21
+ .draggable {
22
+ cursor: move;
23
+ user-select: none;
24
+ transition: transform 0.2s, box-shadow 0.2s;
25
+ }
26
+ .draggable:hover {
27
+ transform: translateY(-2px);
28
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
29
+ }
30
+ .draggable.dragging {
31
+ opacity: 0.5;
32
+ transform: scale(0.98);
33
+ }
34
+ .dropzone {
35
+ min-height: 100px;
36
+ transition: all 0.3s;
37
+ }
38
+ .dropzone.active {
39
+ background-color: rgba(59, 130, 246, 0.1);
40
+ border: 1px dashed #3b82f6;
41
+ }
42
+ .component-pulse {
43
+ animation: pulse 2s infinite;
44
+ }
45
+ @keyframes pulse {
46
+ 0% { transform: scale(1); }
47
+ 50% { transform: scale(1.05); }
48
+ 100% { transform: scale(1); }
49
+ }
50
+ .print-only {
51
+ display: none;
52
+ }
53
+ @media print {
54
+ .no-print {
55
+ display: none !important;
56
+ }
57
+ .print-only {
58
+ display: block !important;
59
+ }
60
+ body {
61
+ background: white;
62
+ font-size: 12pt;
63
+ }
64
+ .container {
65
+ width: 100%;
66
+ max-width: 100%;
67
+ padding: 0;
68
+ }
69
+ .shadow {
70
+ box-shadow: none !important;
71
+ }
72
+ }
73
+ </style>
74
+ </head>
75
+ <body class="bg-gray-50 min-h-screen">
76
+ <div class="container mx-auto px-4 py-8">
77
+ <!-- Header -->
78
+ <header class="mb-8">
79
+ <div class="flex justify-between items-center">
80
+ <div>
81
+ <h1 class="text-3xl font-bold text-gray-800">AI Department Roadmap Builder</h1>
82
+ <p class="text-gray-600">Strategic planning tool for AI initiatives</p>
83
+ </div>
84
+ <div class="flex space-x-4 no-print">
85
+ <button id="exportBtn" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg flex items-center transition-colors">
86
+ <i class="fas fa-file-export mr-2"></i> Export
87
+ </button>
88
+ <button id="printBtn" class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-4 py-2 rounded-lg flex items-center transition-colors">
89
+ <i class="fas fa-print mr-2"></i> Print
90
+ </button>
91
+ <button id="saveBtn" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg flex items-center transition-colors">
92
+ <i class="fas fa-save mr-2"></i> Save
93
+ </button>
94
+ <button id="loadBtn" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg flex items-center transition-colors">
95
+ <i class="fas fa-folder-open mr-2"></i> Load
96
+ </button>
97
+ </div>
98
+ </div>
99
+ <div class="print-only text-center mb-4">
100
+ <h1 class="text-2xl font-bold">AI Department Roadmap</h1>
101
+ <p class="text-sm text-gray-600">Generated on: <span id="printDate"></span></p>
102
+ </div>
103
+ </header>
104
+
105
+ <div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
106
+ <!-- Left Panel - Components -->
107
+ <div class="lg:col-span-1 bg-white rounded-xl shadow p-6 no-print">
108
+ <h2 class="text-xl font-semibold mb-4 text-gray-800">Roadmap Components</h2>
109
+
110
+ <div class="space-y-4">
111
+ <div class="component-group">
112
+ <h3 class="font-medium text-gray-700 mb-2 flex items-center">
113
+ <i class="fas fa-layer-group mr-2 text-blue-500"></i> Strategic Goals
114
+ </h3>
115
+ <div class="space-y-2">
116
+ <div draggable="true" class="draggable bg-blue-50 border border-blue-200 rounded-lg p-3 text-blue-800" data-type="goal" data-id="goal-1">
117
+ <div class="flex items-center">
118
+ <i class="fas fa-bullseye mr-2"></i>
119
+ <span>Improve AI Model Accuracy</span>
120
+ </div>
121
+ </div>
122
+ <div draggable="true" class="draggable bg-blue-50 border border-blue-200 rounded-lg p-3 text-blue-800" data-type="goal" data-id="goal-2">
123
+ <div class="flex items-center">
124
+ <i class="fas fa-bullseye mr-2"></i>
125
+ <span>Reduce Model Bias</span>
126
+ </div>
127
+ </div>
128
+ <div draggable="true" class="draggable bg-blue-50 border border-blue-200 rounded-lg p-3 text-blue-800" data-type="goal" data-id="goal-3">
129
+ <div class="flex items-center">
130
+ <i class="fas fa-bullseye mr-2"></i>
131
+ <span>Enhance Explainability</span>
132
+ </div>
133
+ </div>
134
+ </div>
135
+ </div>
136
+
137
+ <div class="component-group">
138
+ <h3 class="font-medium text-gray-700 mb-2 flex items-center">
139
+ <i class="fas fa-tasks mr-2 text-green-500"></i> Initiatives
140
+ </h3>
141
+ <div class="space-y-2">
142
+ <div draggable="true" class="draggable bg-green-50 border border-green-200 rounded-lg p-3 text-green-800" data-type="initiative" data-id="initiative-1">
143
+ <div class="flex items-center">
144
+ <i class="fas fa-project-diagram mr-2"></i>
145
+ <span>Model Optimization</span>
146
+ </div>
147
+ </div>
148
+ <div draggable="true" class="draggable bg-green-50 border border-green-200 rounded-lg p-3 text-green-800" data-type="initiative" data-id="initiative-2">
149
+ <div class="flex items-center">
150
+ <i class="fas fa-project-diagram mr-2"></i>
151
+ <span>Data Pipeline Upgrade</span>
152
+ </div>
153
+ </div>
154
+ <div draggable="true" class="draggable bg-green-50 border border-green-200 rounded-lg p-3 text-green-800" data-type="initiative" data-id="initiative-3">
155
+ <div class="flex items-center">
156
+ <i class="fas fa-project-diagram mr-2"></i>
157
+ <span>Ethics Framework</span>
158
+ </div>
159
+ </div>
160
+ </div>
161
+ </div>
162
+
163
+ <div class="component-group">
164
+ <h3 class="font-medium text-gray-700 mb-2 flex items-center">
165
+ <i class="fas fa-calendar-check mr-2 text-purple-500"></i> Milestones
166
+ </h3>
167
+ <div class="space-y-2">
168
+ <div draggable="true" class="draggable bg-purple-50 border border-purple-200 rounded-lg p-3 text-purple-800" data-type="milestone" data-id="milestone-1">
169
+ <div class="flex items-center">
170
+ <i class="fas fa-flag-checkered mr-2"></i>
171
+ <span>Model Validation</span>
172
+ </div>
173
+ </div>
174
+ <div draggable="true" class="draggable bg-purple-50 border border-purple-200 rounded-lg p-3 text-purple-800" data-type="milestone" data-id="milestone-2">
175
+ <div class="flex items-center">
176
+ <i class="fas fa-flag-checkered mr-2"></i>
177
+ <span>Deployment</span>
178
+ </div>
179
+ </div>
180
+ <div draggable="true" class="draggable bg-purple-50 border border-purple-200 rounded-lg p-3 text-purple-800" data-type="milestone" data-id="milestone-3">
181
+ <div class="flex items-center">
182
+ <i class="fas fa-flag-checkered mr-2"></i>
183
+ <span>Audit Completion</span>
184
+ </div>
185
+ </div>
186
+ </div>
187
+ </div>
188
+
189
+ <div class="component-group">
190
+ <h3 class="font-medium text-gray-700 mb-2 flex items-center">
191
+ <i class="fas fa-users mr-2 text-yellow-500"></i> Resources
192
+ </h3>
193
+ <div class="space-y-2">
194
+ <div draggable="true" class="draggable bg-yellow-50 border border-yellow-200 rounded-lg p-3 text-yellow-800" data-type="resource" data-id="resource-1">
195
+ <div class="flex items-center">
196
+ <i class="fas fa-user-tie mr-2"></i>
197
+ <span>Research Team</span>
198
+ </div>
199
+ </div>
200
+ <div draggable="true" class="draggable bg-yellow-50 border border-yellow-200 rounded-lg p-3 text-yellow-800" data-type="resource" data-id="resource-2">
201
+ <div class="flex items-center">
202
+ <i class="fas fa-server mr-2"></i>
203
+ <span>GPU Cluster</span>
204
+ </div>
205
+ </div>
206
+ <div draggable="true" class="draggable bg-yellow-50 border border-yellow-200 rounded-lg p-3 text-yellow-800" data-type="resource" data-id="resource-3">
207
+ <div class="flex items-center">
208
+ <i class="fas fa-money-bill-wave mr-2"></i>
209
+ <span>Budget Allocation</span>
210
+ </div>
211
+ </div>
212
+ </div>
213
+ </div>
214
+ </div>
215
+
216
+ <div class="mt-6">
217
+ <h3 class="font-medium text-gray-700 mb-2 flex items-center">
218
+ <i class="fas fa-plus-circle mr-2 text-red-500"></i> Custom Component
219
+ </h3>
220
+ <div class="flex">
221
+ <input type="text" id="customComponent" placeholder="New component name" class="flex-1 border rounded-l-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
222
+ <button id="addCustomBtn" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-r-lg transition-colors">
223
+ Add
224
+ </button>
225
+ </div>
226
+ <select id="customType" class="mt-2 w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
227
+ <option value="goal">Strategic Goal</option>
228
+ <option value="initiative">Initiative</option>
229
+ <option value="milestone">Milestone</option>
230
+ <option value="resource">Resource</option>
231
+ </select>
232
+ </div>
233
+ </div>
234
+
235
+ <!-- Main Roadmap Area -->
236
+ <div class="lg:col-span-3">
237
+ <div class="bg-white rounded-xl shadow p-6 mb-6">
238
+ <div class="flex justify-between items-center mb-4 no-print">
239
+ <h2 class="text-xl font-semibold text-gray-800">AI Department Roadmap</h2>
240
+ <div class="flex space-x-2">
241
+ <select id="timeframe" class="border rounded-lg px-3 py-1 focus:outline-none focus:ring-2 focus:ring-blue-500">
242
+ <option value="quarterly">Quarterly View</option>
243
+ <option value="yearly">Yearly View</option>
244
+ <option value="3year">3-Year Plan</option>
245
+ </select>
246
+ <button id="clearAllBtn" class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-3 py-1 rounded-lg text-sm transition-colors">
247
+ Clear All
248
+ </button>
249
+ </div>
250
+ </div>
251
+
252
+ <div class="overflow-x-auto">
253
+ <div id="roadmapTimeline" class="min-w-full">
254
+ <!-- Timeline will be generated here -->
255
+ <div class="relative">
256
+ <!-- Q1 -->
257
+ <div class="timeline-item relative pb-8 pl-10">
258
+ <div class="absolute left-0 top-0 w-8 h-8 rounded-full bg-blue-500 flex items-center justify-center text-white font-bold">
259
+ Q1
260
+ </div>
261
+ <div class="dropzone p-3 rounded-lg border border-dashed border-gray-300" data-timeframe="q1">
262
+ <h3 class="font-medium text-gray-700 mb-2">Q1 2024</h3>
263
+ <div class="space-y-2" id="q1-items"></div>
264
+ </div>
265
+ </div>
266
+
267
+ <!-- Q2 -->
268
+ <div class="timeline-item relative pb-8 pl-10">
269
+ <div class="absolute left-0 top-0 w-8 h-8 rounded-full bg-green-500 flex items-center justify-center text-white font-bold">
270
+ Q2
271
+ </div>
272
+ <div class="dropzone p-3 rounded-lg border border-dashed border-gray-300" data-timeframe="q2">
273
+ <h3 class="font-medium text-gray-700 mb-2">Q2 2024</h3>
274
+ <div class="space-y-2" id="q2-items"></div>
275
+ </div>
276
+ </div>
277
+
278
+ <!-- Q3 -->
279
+ <div class="timeline-item relative pb-8 pl-10">
280
+ <div class="absolute left-0 top-0 w-8 h-8 rounded-full bg-yellow-500 flex items-center justify-center text-white font-bold">
281
+ Q3
282
+ </div>
283
+ <div class="dropzone p-3 rounded-lg border border-dashed border-gray-300" data-timeframe="q3">
284
+ <h3 class="font-medium text-gray-700 mb-2">Q3 2024</h3>
285
+ <div class="space-y-2" id="q3-items"></div>
286
+ </div>
287
+ </div>
288
+
289
+ <!-- Q4 -->
290
+ <div class="timeline-item relative pb-8 pl-10">
291
+ <div class="absolute left-0 top-0 w-8 h-8 rounded-full bg-purple-500 flex items-center justify-center text-white font-bold">
292
+ Q4
293
+ </div>
294
+ <div class="dropzone p-3 rounded-lg border border-dashed border-gray-300" data-timeframe="q4">
295
+ <h3 class="font-medium text-gray-700 mb-2">Q4 2024</h3>
296
+ <div class="space-y-2" id="q4-items"></div>
297
+ </div>
298
+ </div>
299
+ </div>
300
+ </div>
301
+ </div>
302
+ </div>
303
+
304
+ <!-- Roadmap Summary -->
305
+ <div class="bg-white rounded-xl shadow p-6">
306
+ <h2 class="text-xl font-semibold mb-4 text-gray-800">Roadmap Summary</h2>
307
+ <div id="roadmapSummary" class="space-y-4">
308
+ <div class="text-center text-gray-500 py-8">
309
+ <i class="fas fa-road text-4xl mb-2 text-gray-300"></i>
310
+ <p>Your roadmap summary will appear here</p>
311
+ <p class="text-sm">Drag and drop components to build your AI department roadmap</p>
312
+ </div>
313
+ </div>
314
+ </div>
315
+ </div>
316
+ </div>
317
+ </div>
318
+
319
+ <!-- Save/Load Modal -->
320
+ <div id="saveLoadModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
321
+ <div class="bg-white rounded-xl shadow-xl p-6 w-full max-w-md">
322
+ <div class="flex justify-between items-center mb-4">
323
+ <h3 class="text-xl font-semibold" id="modalTitle">Save Roadmap</h3>
324
+ <button id="closeModalBtn" class="text-gray-500 hover:text-gray-700">
325
+ <i class="fas fa-times"></i>
326
+ </button>
327
+ </div>
328
+ <div id="modalContent">
329
+ <!-- Content will be filled dynamically -->
330
+ </div>
331
+ </div>
332
+ </div>
333
+
334
+ <script>
335
+ // Initialize jsPDF
336
+ const { jsPDF } = window.jspdf;
337
+
338
+ document.addEventListener('DOMContentLoaded', function() {
339
+ // Set print date
340
+ const now = new Date();
341
+ document.getElementById('printDate').textContent = now.toLocaleDateString() + ' ' + now.toLocaleTimeString();
342
+
343
+ // Initialize roadmap state
344
+ let roadmapState = {
345
+ q1: [],
346
+ q2: [],
347
+ q3: [],
348
+ q4: []
349
+ };
350
+
351
+ // Generate unique ID
352
+ function generateId() {
353
+ return 'id-' + Math.random().toString(36).substr(2, 9);
354
+ }
355
+
356
+ // Drag and drop functionality
357
+ const draggables = document.querySelectorAll('.draggable');
358
+ const dropzones = document.querySelectorAll('.dropzone');
359
+ let draggedItem = null;
360
+
361
+ // Add animation to components to encourage interaction
362
+ setTimeout(() => {
363
+ const components = document.querySelectorAll('.component-group .draggable');
364
+ components.forEach((comp, index) => {
365
+ setTimeout(() => {
366
+ comp.classList.add('component-pulse');
367
+ setTimeout(() => {
368
+ comp.classList.remove('component-pulse');
369
+ }, 2000);
370
+ }, index * 300);
371
+ });
372
+ }, 1000);
373
+
374
+ // Add event listeners for draggable items
375
+ draggables.forEach(item => {
376
+ item.addEventListener('dragstart', function(e) {
377
+ draggedItem = this;
378
+ this.classList.add('dragging');
379
+ e.dataTransfer.setData('text/plain', this.dataset.id);
380
+ e.dataTransfer.effectAllowed = 'move';
381
+ });
382
+
383
+ item.addEventListener('dragend', function() {
384
+ this.classList.remove('dragging');
385
+ });
386
+ });
387
+
388
+ // Add event listeners for drop zones
389
+ dropzones.forEach(zone => {
390
+ zone.addEventListener('dragover', function(e) {
391
+ e.preventDefault();
392
+ this.classList.add('active');
393
+ e.dataTransfer.dropEffect = 'move';
394
+ });
395
+
396
+ zone.addEventListener('dragleave', function() {
397
+ this.classList.remove('active');
398
+ });
399
+
400
+ zone.addEventListener('drop', function(e) {
401
+ e.preventDefault();
402
+ this.classList.remove('active');
403
+
404
+ if (draggedItem) {
405
+ const componentId = e.dataTransfer.getData('text/plain');
406
+ const originalComponent = document.querySelector(`[data-id="${componentId}"]`);
407
+
408
+ if (originalComponent) {
409
+ const timeframe = this.dataset.timeframe;
410
+ const componentData = {
411
+ id: componentId,
412
+ type: originalComponent.dataset.type,
413
+ text: originalComponent.querySelector('span').textContent,
414
+ timeframe: timeframe
415
+ };
416
+
417
+ // Check if component already exists in this timeframe
418
+ const existingIndex = roadmapState[timeframe].findIndex(item => item.id === componentId);
419
+
420
+ if (existingIndex === -1) {
421
+ // Add to new timeframe
422
+ roadmapState[timeframe].push(componentData);
423
+
424
+ // Remove from previous timeframe if it exists
425
+ Object.keys(roadmapState).forEach(q => {
426
+ if (q !== timeframe) {
427
+ roadmapState[q] = roadmapState[q].filter(item => item.id !== componentId);
428
+ }
429
+ });
430
+
431
+ // Update UI
432
+ updateRoadmapUI();
433
+ updateRoadmapSummary();
434
+ }
435
+ }
436
+ }
437
+ });
438
+ });
439
+
440
+ // Update the roadmap UI based on state
441
+ function updateRoadmapUI() {
442
+ // Clear all items first
443
+ document.querySelectorAll('[id$="-items"]').forEach(container => {
444
+ container.innerHTML = '';
445
+ });
446
+
447
+ // Add items based on state
448
+ Object.keys(roadmapState).forEach(timeframe => {
449
+ const container = document.getElementById(`${timeframe}-items`);
450
+
451
+ roadmapState[timeframe].forEach(item => {
452
+ const component = createRoadmapComponent(item);
453
+ container.appendChild(component);
454
+ });
455
+ });
456
+ }
457
+
458
+ // Create a roadmap component for the timeline
459
+ function createRoadmapComponent(item) {
460
+ let bgColor, borderColor, textColor, icon;
461
+
462
+ switch(item.type) {
463
+ case 'goal':
464
+ bgColor = 'bg-blue-50';
465
+ borderColor = 'border-blue-200';
466
+ textColor = 'text-blue-800';
467
+ icon = 'fa-bullseye';
468
+ break;
469
+ case 'initiative':
470
+ bgColor = 'bg-green-50';
471
+ borderColor = 'border-green-200';
472
+ textColor = 'text-green-800';
473
+ icon = 'fa-project-diagram';
474
+ break;
475
+ case 'milestone':
476
+ bgColor = 'bg-purple-50';
477
+ borderColor = 'border-purple-200';
478
+ textColor = 'text-purple-800';
479
+ icon = 'fa-flag-checkered';
480
+ break;
481
+ case 'resource':
482
+ bgColor = 'bg-yellow-50';
483
+ borderColor = 'border-yellow-200';
484
+ textColor = 'text-yellow-800';
485
+ icon = 'fa-user-tie';
486
+ break;
487
+ }
488
+
489
+ const component = document.createElement('div');
490
+ component.className = `${bgColor} border ${borderColor} rounded-lg p-3 ${textColor} relative group`;
491
+ component.dataset.id = item.id;
492
+ component.dataset.type = item.type;
493
+
494
+ component.innerHTML = `
495
+ <div class="flex items-center">
496
+ <i class="fas ${icon} mr-2"></i>
497
+ <span>${item.text}</span>
498
+ <button class="delete-btn ml-auto opacity-0 group-hover:opacity-100 text-red-500 hover:text-red-700 transition-opacity">
499
+ <i class="fas fa-times"></i>
500
+ </button>
501
+ </div>
502
+ `;
503
+
504
+ // Add delete functionality
505
+ const deleteBtn = component.querySelector('.delete-btn');
506
+ deleteBtn.addEventListener('click', function() {
507
+ roadmapState[item.timeframe] = roadmapState[item.timeframe].filter(i => i.id !== item.id);
508
+ updateRoadmapUI();
509
+ updateRoadmapSummary();
510
+ });
511
+
512
+ return component;
513
+ }
514
+
515
+ // Add custom component
516
+ document.getElementById('addCustomBtn').addEventListener('click', function() {
517
+ const componentName = document.getElementById('customComponent').value.trim();
518
+ const componentType = document.getElementById('customType').value;
519
+
520
+ if (componentName) {
521
+ const componentId = generateId();
522
+ let bgColor, borderColor, textColor, icon;
523
+
524
+ switch(componentType) {
525
+ case 'goal':
526
+ bgColor = 'bg-blue-50';
527
+ borderColor = 'border-blue-200';
528
+ textColor = 'text-blue-800';
529
+ icon = 'fa-bullseye';
530
+ break;
531
+ case 'initiative':
532
+ bgColor = 'bg-green-50';
533
+ borderColor = 'border-green-200';
534
+ textColor = 'text-green-800';
535
+ icon = 'fa-project-diagram';
536
+ break;
537
+ case 'milestone':
538
+ bgColor = 'bg-purple-50';
539
+ borderColor = 'border-purple-200';
540
+ textColor = 'text-purple-800';
541
+ icon = 'fa-flag-checkered';
542
+ break;
543
+ case 'resource':
544
+ bgColor = 'bg-yellow-50';
545
+ borderColor = 'border-yellow-200';
546
+ textColor = 'text-yellow-800';
547
+ icon = 'fa-user-tie';
548
+ break;
549
+ }
550
+
551
+ const newComponent = document.createElement('div');
552
+ newComponent.className = `draggable ${bgColor} border ${borderColor} rounded-lg p-3 ${textColor}`;
553
+ newComponent.setAttribute('draggable', 'true');
554
+ newComponent.setAttribute('data-type', componentType);
555
+ newComponent.setAttribute('data-id', componentId);
556
+ newComponent.innerHTML = `
557
+ <div class="flex items-center">
558
+ <i class="fas ${icon} mr-2"></i>
559
+ <span>${componentName}</span>
560
+ </div>
561
+ `;
562
+
563
+ // Add drag events to the new component
564
+ newComponent.addEventListener('dragstart', function(e) {
565
+ draggedItem = this;
566
+ this.classList.add('dragging');
567
+ e.dataTransfer.setData('text/plain', this.dataset.id);
568
+ e.dataTransfer.effectAllowed = 'move';
569
+ });
570
+
571
+ newComponent.addEventListener('dragend', function() {
572
+ this.classList.remove('dragging');
573
+ });
574
+
575
+ // Add to the appropriate component group
576
+ const componentGroups = document.querySelectorAll('.component-group');
577
+ componentGroups.forEach(group => {
578
+ const heading = group.querySelector('h3');
579
+ if (heading.textContent.includes(componentType.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase()))) {
580
+ group.querySelector('.space-y-2').prepend(newComponent);
581
+ }
582
+ });
583
+
584
+ document.getElementById('customComponent').value = '';
585
+
586
+ // Animate the new component
587
+ newComponent.classList.add('component-pulse');
588
+ setTimeout(() => {
589
+ newComponent.classList.remove('component-pulse');
590
+ }, 2000);
591
+ }
592
+ });
593
+
594
+ // Update roadmap summary
595
+ function updateRoadmapSummary() {
596
+ const summaryContainer = document.getElementById('roadmapSummary');
597
+ summaryContainer.innerHTML = '';
598
+
599
+ const quarters = ['q1', 'q2', 'q3', 'q4'];
600
+ let hasContent = false;
601
+
602
+ quarters.forEach(q => {
603
+ if (roadmapState[q].length > 0) {
604
+ hasContent = true;
605
+
606
+ const quarterSection = document.createElement('div');
607
+ quarterSection.className = 'bg-gray-50 rounded-lg p-4';
608
+
609
+ const quarterTitle = document.createElement('h3');
610
+ quarterTitle.className = 'font-semibold text-lg mb-2';
611
+ quarterTitle.textContent = document.querySelector(`[data-timeframe="${q}"] h3`).textContent;
612
+
613
+ quarterSection.appendChild(quarterTitle);
614
+
615
+ const itemsList = document.createElement('ul');
616
+ itemsList.className = 'space-y-2';
617
+
618
+ roadmapState[q].forEach(item => {
619
+ const listItem = document.createElement('li');
620
+ listItem.className = 'flex items-center';
621
+
622
+ let typeBadge;
623
+
624
+ switch(item.type) {
625
+ case 'goal':
626
+ typeBadge = '<span class="bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded mr-2">Goal</span>';
627
+ break;
628
+ case 'initiative':
629
+ typeBadge = '<span class="bg-green-100 text-green-800 text-xs px-2 py-1 rounded mr-2">Initiative</span>';
630
+ break;
631
+ case 'milestone':
632
+ typeBadge = '<span class="bg-purple-100 text-purple-800 text-xs px-2 py-1 rounded mr-2">Milestone</span>';
633
+ break;
634
+ case 'resource':
635
+ typeBadge = '<span class="bg-yellow-100 text-yellow-800 text-xs px-2 py-1 rounded mr-2">Resource</span>';
636
+ break;
637
+ }
638
+
639
+ listItem.innerHTML = `
640
+ ${typeBadge}
641
+ <span>${item.text}</span>
642
+ `;
643
+
644
+ itemsList.appendChild(listItem);
645
+ });
646
+
647
+ quarterSection.appendChild(itemsList);
648
+ summaryContainer.appendChild(quarterSection);
649
+ }
650
+ });
651
+
652
+ if (!hasContent) {
653
+ summaryContainer.innerHTML = `
654
+ <div class="text-center text-gray-500 py-8">
655
+ <i class="fas fa-road text-4xl mb-2 text-gray-300"></i>
656
+ <p>Your roadmap summary will appear here</p>
657
+ <p class="text-sm">Drag and drop components to build your AI department roadmap</p>
658
+ </div>
659
+ `;
660
+ }
661
+ }
662
+
663
+ // Clear all button
664
+ document.getElementById('clearAllBtn').addEventListener('click', function() {
665
+ if (confirm('Are you sure you want to clear all items from the roadmap?')) {
666
+ Object.keys(roadmapState).forEach(q => {
667
+ roadmapState[q] = [];
668
+ });
669
+ updateRoadmapUI();
670
+ updateRoadmapSummary();
671
+ }
672
+ });
673
+
674
+ // Export button (PDF)
675
+ document.getElementById('exportBtn').addEventListener('click', function() {
676
+ // Create a PDF of the roadmap
677
+ const roadmapElement = document.getElementById('roadmapTimeline');
678
+
679
+ html2canvas(roadmapElement, {
680
+ scale: 2,
681
+ logging: false,
682
+ useCORS: true,
683
+ allowTaint: true
684
+ }).then(canvas => {
685
+ const imgData = canvas.toDataURL('image/png');
686
+ const pdf = new jsPDF('p', 'mm', 'a4');
687
+ const imgWidth = 210; // A4 width in mm
688
+ const pageHeight = 295; // A4 height in mm
689
+ const imgHeight = canvas.height * imgWidth / canvas.width;
690
+ let heightLeft = imgHeight;
691
+ let position = 0;
692
+
693
+ pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
694
+ heightLeft -= pageHeight;
695
+
696
+ while (heightLeft >= 0) {
697
+ position = heightLeft - imgHeight;
698
+ pdf.addPage();
699
+ pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
700
+ heightLeft -= pageHeight;
701
+ }
702
+
703
+ pdf.save('AI-Roadmap-' + new Date().toISOString().slice(0, 10) + '.pdf');
704
+ });
705
+ });
706
+
707
+ // Print button
708
+ document.getElementById('printBtn').addEventListener('click', function() {
709
+ window.print();
710
+ });
711
+
712
+ // Save button
713
+ document.getElementById('saveBtn').addEventListener('click', function() {
714
+ showSaveModal();
715
+ });
716
+
717
+ // Load button
718
+ document.getElementById('loadBtn').addEventListener('click', function() {
719
+ showLoadModal();
720
+ });
721
+
722
+ // Timeframe selector
723
+ document.getElementById('timeframe').addEventListener('change', function() {
724
+ // In a real app, this would change the view of the timeline
725
+ // For now, we'll just show a notification
726
+ const notification = document.createElement('div');
727
+ notification.className = 'fixed bottom-4 right-4 bg-blue-500 text-white px-4 py-2 rounded-lg shadow-lg';
728
+ notification.textContent = `View changed to ${this.options[this.selectedIndex].text}`;
729
+ document.body.appendChild(notification);
730
+
731
+ setTimeout(() => {
732
+ notification.classList.add('opacity-0', 'transition-opacity', 'duration-500');
733
+ setTimeout(() => {
734
+ notification.remove();
735
+ }, 500);
736
+ }, 2000);
737
+ });
738
+
739
+ // Modal functionality
740
+ const modal = document.getElementById('saveLoadModal');
741
+ const modalTitle = document.getElementById('modalTitle');
742
+ const modalContent = document.getElementById('modalContent');
743
+ const closeModalBtn = document.getElementById('closeModalBtn');
744
+
745
+ closeModalBtn.addEventListener('click', function() {
746
+ modal.classList.add('hidden');
747
+ });
748
+
749
+ function showSaveModal() {
750
+ modalTitle.textContent = 'Save Roadmap';
751
+
752
+ const content = `
753
+ <div class="mb-4">
754
+ <label for="roadmapName" class="block text-sm font-medium text-gray-700 mb-1">Roadmap Name</label>
755
+ <input type="text" id="roadmapName" class="w-full border rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="My AI Roadmap">
756
+ </div>
757
+ <div class="flex justify-end space-x-2">
758
+ <button id="cancelSaveBtn" class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-4 py-2 rounded-lg">Cancel</button>
759
+ <button id="confirmSaveBtn" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg">Save</button>
760
+ </div>
761
+ `;
762
+
763
+ modalContent.innerHTML = content;
764
+ modal.classList.remove('hidden');
765
+
766
+ document.getElementById('cancelSaveBtn').addEventListener('click', function() {
767
+ modal.classList.add('hidden');
768
+ });
769
+
770
+ document.getElementById('confirmSaveBtn').addEventListener('click', function() {
771
+ const roadmapName = document.getElementById('roadmapName').value.trim() || 'My AI Roadmap';
772
+ const roadmapData = {
773
+ name: roadmapName,
774
+ date: new Date().toISOString(),
775
+ state: roadmapState
776
+ };
777
+
778
+ localStorage.setItem('aiRoadmap', JSON.stringify(roadmapData));
779
+
780
+ // Show success notification
781
+ const notification = document.createElement('div');
782
+ notification.className = 'fixed bottom-4 right-4 bg-green-500 text-white px-4 py-2 rounded-lg shadow-lg';
783
+ notification.textContent = `Roadmap "${roadmapName}" saved successfully!`;
784
+ document.body.appendChild(notification);
785
+
786
+ setTimeout(() => {
787
+ notification.classList.add('opacity-0', 'transition-opacity', 'duration-500');
788
+ setTimeout(() => {
789
+ notification.remove();
790
+ }, 500);
791
+ }, 2000);
792
+
793
+ modal.classList.add('hidden');
794
+ });
795
+ }
796
+
797
+ function showLoadModal() {
798
+ const savedRoadmap = localStorage.getItem('aiRoadmap');
799
+
800
+ if (!savedRoadmap) {
801
+ modalTitle.textContent = 'No Saved Roadmap';
802
+ modalContent.innerHTML = `
803
+ <div class="text-center py-4">
804
+ <i class="fas fa-exclamation-circle text-4xl text-yellow-500 mb-2"></i>
805
+ <p>No saved roadmap found.</p>
806
+ </div>
807
+ <div class="flex justify-end">
808
+ <button id="closeEmptyModalBtn" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg">OK</button>
809
+ </div>
810
+ `;
811
+
812
+ modal.classList.remove('hidden');
813
+
814
+ document.getElementById('closeEmptyModalBtn').addEventListener('click', function() {
815
+ modal.classList.add('hidden');
816
+ });
817
+
818
+ return;
819
+ }
820
+
821
+ modalTitle.textContent = 'Load Roadmap';
822
+
823
+ try {
824
+ const roadmapData = JSON.parse(savedRoadmap);
825
+
826
+ const content = `
827
+ <div class="mb-4">
828
+ <p class="text-sm text-gray-600 mb-1">Saved Roadmap:</p>
829
+ <div class="bg-gray-50 p-3 rounded-lg">
830
+ <h4 class="font-medium">${roadmapData.name}</h4>
831
+ <p class="text-xs text-gray-500">Saved on: ${new Date(roadmapData.date).toLocaleString()}</p>
832
+ </div>
833
+ </div>
834
+ <div class="mb-4">
835
+ <p class="text-sm font-medium text-gray-700 mb-1">This will replace your current roadmap. Continue?</p>
836
+ </div>
837
+ <div class="flex justify-end space-x-2">
838
+ <button id="cancelLoadBtn" class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-4 py-2 rounded-lg">Cancel</button>
839
+ <button id="confirmLoadBtn" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg">Load</button>
840
+ </div>
841
+ `;
842
+
843
+ modalContent.innerHTML = content;
844
+ modal.classList.remove('hidden');
845
+
846
+ document.getElementById('cancelLoadBtn').addEventListener('click', function() {
847
+ modal.classList.add('hidden');
848
+ });
849
+
850
+ document.getElementById('confirmLoadBtn').addEventListener('click', function() {
851
+ roadmapState = roadmapData.state;
852
+ updateRoadmapUI();
853
+ updateRoadmapSummary();
854
+
855
+ // Show success notification
856
+ const notification = document.createElement('div');
857
+ notification.className = 'fixed bottom-4 right-4 bg-green-500 text-white px-4 py-2 rounded-lg shadow-lg';
858
+ notification.textContent = `Roadmap "${roadmapData.name}" loaded successfully!`;
859
+ document.body.appendChild(notification);
860
+
861
+ setTimeout(() => {
862
+ notification.classList.add('opacity-0', 'transition-opacity', 'duration-500');
863
+ setTimeout(() => {
864
+ notification.remove();
865
+ }, 500);
866
+ }, 2000);
867
+
868
+ modal.classList.add('hidden');
869
+ });
870
+ } catch (e) {
871
+ modalTitle.textContent = 'Error Loading Roadmap';
872
+ modalContent.innerHTML = `
873
+ <div class="text-center py-4">
874
+ <i class="fas fa-exclamation-triangle text-4xl text-red-500 mb-2"></i>
875
+ <p>Error loading saved roadmap.</p>
876
+ </div>
877
+ <div class="flex justify-end">
878
+ <button id="closeErrorModalBtn" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg">OK</button>
879
+ </div>
880
+ `;
881
+
882
+ modal.classList.remove('hidden');
883
+
884
+ document.getElementById('closeErrorModalBtn').addEventListener('click', function() {
885
+ modal.classList.add('hidden');
886
+ });
887
+ }
888
+ }
889
+
890
+ // Close modal when clicking outside
891
+ modal.addEventListener('click', function(e) {
892
+ if (e.target === modal) {
893
+ modal.classList.add('hidden');
894
+ }
895
+ });
896
+
897
+ // Initialize empty roadmap
898
+ updateRoadmapSummary();
899
+ });
900
+ </script>
901
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=aceeee/ai-rm-builder-1" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
902
+ </html>