pvanand commited on
Commit
f2de90e
·
verified ·
1 Parent(s): 44451eb

Create article-writer.html

Browse files
templates/apps-hub/article-writer.html ADDED
@@ -0,0 +1,333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Report Generator</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
8
+ <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
9
+ <style>
10
+ /* Main styles */
11
+ body {
12
+ margin: 0;
13
+ padding: 0;
14
+ text-rendering: optimizeLegibility;
15
+ -webkit-font-smoothing: antialiased;
16
+ color: rgba(0,0,0,0.8);
17
+ position: relative;
18
+ min-height: 100vh;
19
+ font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif;
20
+ font-size: 20px;
21
+ line-height: 1.58;
22
+ color: rgba(0, 0, 0, 0.8);
23
+ background-color: #fff;
24
+ margin: 0;
25
+ padding: 0;
26
+ }
27
+ .container {
28
+ max-width: 800px;
29
+ margin: 0 auto;
30
+ padding: 0 20px;
31
+ }
32
+ /* Typography */
33
+ h1, h2, h3, h4, h5, h6 {
34
+ font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif;
35
+ font-weight: 700;
36
+ color: rgba(0, 0, 0, 0.84);
37
+ letter-spacing: -0.022em;
38
+ line-height: 1.2;
39
+ }
40
+ h1 {
41
+ font-size: 40px;
42
+ margin-bottom: 0.5em;
43
+ }
44
+ h2 {
45
+ font-size: 32px;
46
+ margin-top: 1.5em;
47
+ margin-bottom: 0.5em;
48
+ }
49
+ h3 {
50
+ font-size: 26px;
51
+ margin-top: 1.5em;
52
+ margin-bottom: 0.5em;
53
+ }
54
+ p {
55
+ margin-bottom: 32px;
56
+ }
57
+ /* Links */
58
+ a {
59
+ color: #1a8917;
60
+ text-decoration: none;
61
+ }
62
+ a:hover {
63
+ text-decoration: underline;
64
+ }
65
+ /* Input container */
66
+ #input-container {
67
+ margin-bottom: 40px;
68
+ background-color: #f9f9f9;
69
+ padding: 32px;
70
+ border-radius: 5px;
71
+ }
72
+ textarea {
73
+ width: 100%;
74
+ padding: 12px;
75
+ margin-bottom: 20px;
76
+ border: 1px solid rgba(0, 0, 0, 0.15);
77
+ border-radius: 4px;
78
+ font-size: 18px;
79
+ resize: vertical;
80
+ box-sizing: border-box;
81
+ font-family: inherit;
82
+ }
83
+ button {
84
+ padding: 12px 24px;
85
+ background-color: #1a8917;
86
+ color: white;
87
+ border: none;
88
+ border-radius: 4px;
89
+ cursor: pointer;
90
+ font-size: 18px;
91
+ transition: background-color 0.3s;
92
+ }
93
+ button:hover {
94
+ background-color: #0f6b0f;
95
+ }
96
+ /* Output container */
97
+ #output-container {
98
+ display: flex;
99
+ flex-direction: column;
100
+ gap: 40px;
101
+ }
102
+ #report-container, #sources-container {
103
+ background-color: #fff;
104
+ padding: 32px;
105
+ border-radius: 5px;
106
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
107
+ overflow-wrap: break-word;
108
+ word-wrap: break-word;
109
+ word-break: break-word;
110
+ }
111
+ /* Sources */
112
+ .source-item {
113
+ margin-bottom: 32px;
114
+ padding: 24px;
115
+ background-color: #f9f9f9;
116
+ border: 1px solid #e0e0e0;
117
+ border-radius: 5px;
118
+ position: relative;
119
+ cursor: pointer;
120
+ transition: box-shadow 0.3s;
121
+ }
122
+ .source-item:hover {
123
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
124
+ }
125
+ .source-url {
126
+ color: #1a8917;
127
+ text-decoration: none;
128
+ word-break: break-all;
129
+ font-weight: bold;
130
+ display: block;
131
+ margin-bottom: 16px;
132
+ font-size: 18px;
133
+ }
134
+ .source-content {
135
+ margin-top: 16px;
136
+ position: relative;
137
+ overflow: hidden;
138
+ }
139
+ .source-snippet {
140
+ max-height: 150px;
141
+ overflow: hidden;
142
+ }
143
+ .source-full {
144
+ display: none;
145
+ }
146
+ .expand-indicator {
147
+ position: absolute;
148
+ bottom: 0;
149
+ left: 0;
150
+ right: 0;
151
+ height: 40px;
152
+ background: linear-gradient(to bottom, rgba(249,249,249,0), rgba(249,249,249,1));
153
+ display: flex;
154
+ align-items: center;
155
+ justify-content: center;
156
+ }
157
+ .expand-indicator::after {
158
+ content: '▼';
159
+ font-size: 14px;
160
+ color: #666;
161
+ }
162
+ .expanded .expand-indicator::after {
163
+ content: '▲';
164
+ }
165
+ /* Responsive adjustments */
166
+ @media (max-width: 768px) {
167
+ .container {
168
+ padding: 0 16px;
169
+ }
170
+ h1 {
171
+ font-size: 32px;
172
+ }
173
+ h2 {
174
+ font-size: 24px;
175
+ }
176
+ #input-container, #report-container, #sources-container {
177
+ padding: 24px;
178
+ }
179
+ }
180
+ </style>
181
+ </head>
182
+ <body>
183
+ <div class="container">
184
+ <div id="input-container">
185
+ <h1>Blog Post Generator</h1>
186
+ <textarea id="description" rows="4" placeholder="Enter description">write a medium article on nvidia stock performance</textarea>
187
+ <button onclick="generateReport()">Generate Report</button>
188
+ </div>
189
+ <div id="output-container">
190
+ <div id="report-container"></div>
191
+ <div id="sources-container"></div>
192
+ </div>
193
+ </div>
194
+ <script>
195
+ async function generateReport() {
196
+ const description = document.getElementById('description').value;
197
+ const reportContainer = document.getElementById('report-container');
198
+ const sourcesContainer = document.getElementById('sources-container');
199
+ reportContainer.innerHTML = 'Generating report...';
200
+ sourcesContainer.innerHTML = '';
201
+ try {
202
+ const response = await fetch('https://pvanand-search-generate-prod.hf.space/generate_report', {
203
+ method: 'POST',
204
+ headers: {
205
+ 'Content-Type': 'application/json',
206
+ 'Accept': 'text/plain'
207
+ },
208
+ body: JSON.stringify({
209
+ description: description,
210
+ user_id: "",
211
+ user_name: "multi-agent-research",
212
+ internet: true,
213
+ output_format: "report_table",
214
+ data_format: "Structured data",
215
+ generate_charts: true,
216
+ output_as_md: true
217
+ })
218
+ });
219
+ if (!response.ok) {
220
+ throw new Error(`HTTP error! status: ${response.status}`);
221
+ }
222
+ const reader = response.body.getReader();
223
+ const decoder = new TextDecoder();
224
+ let markdown = '';
225
+ let metadata = '';
226
+ let isReadingMetadata = false;
227
+ while (true) {
228
+ const { value, done } = await reader.read();
229
+ if (done) break;
230
+
231
+ const chunk = decoder.decode(value, { stream: true });
232
+
233
+ if (chunk.includes('<report-metadata>')) {
234
+ isReadingMetadata = true;
235
+ metadata = '';
236
+ }
237
+
238
+ if (isReadingMetadata) {
239
+ metadata += chunk;
240
+ if (chunk.includes('</report-metadata>')) {
241
+ isReadingMetadata = false;
242
+ processMetadata(metadata);
243
+ }
244
+ } else {
245
+ markdown += chunk;
246
+ renderMarkdown(markdown);
247
+ }
248
+ }
249
+ } catch (error) {
250
+ reportContainer.innerHTML = `Error generating report: ${error.message}`;
251
+ }
252
+ }
253
+ function renderMarkdown(markdown) {
254
+ const reportContainer = document.getElementById('report-container');
255
+ const reportContent = markdown.match(/<report>([\s\S]*)<\/report>/);
256
+
257
+ if (reportContent) {
258
+ reportContainer.innerHTML = marked.parse(reportContent[1]);
259
+ } else {
260
+ reportContainer.innerHTML = marked.parse(markdown);
261
+ }
262
+
263
+ const scripts = reportContainer.getElementsByTagName('script');
264
+ Array.from(scripts).forEach(script => {
265
+ const newScript = document.createElement('script');
266
+ newScript.textContent = script.textContent;
267
+ script.parentNode.replaceChild(newScript, script);
268
+ });
269
+ // Make Plotly charts responsive
270
+ const plots = reportContainer.querySelectorAll('.js-plotly-plot');
271
+ plots.forEach(plot => {
272
+ Plotly.Plots.resize(plot);
273
+ });
274
+ }
275
+ function processMetadata(metadata) {
276
+ const sourcesContainer = document.getElementById('sources-container');
277
+ const metadataMatch = metadata.match(/all-text-with-urls: (.+)/);
278
+
279
+ if (metadataMatch) {
280
+ const metadataObj = JSON.parse(metadataMatch[1]);
281
+
282
+ sourcesContainer.innerHTML = '<h2>Sources</h2>';
283
+ metadataObj.forEach(([content, url]) => {
284
+ if (content.trim() !== "") {
285
+ const sourceItem = document.createElement('div');
286
+ sourceItem.className = 'source-item';
287
+ const snippet = content.length > 400 ? content.substring(0, 400) + '...' : content;
288
+ sourceItem.innerHTML = `
289
+ <a href="${url}" target="_blank" class="source-url">${url}</a>
290
+ <div class="source-content">
291
+ <div class="source-snippet">${marked.parse(snippet)}</div>
292
+ <div class="source-full">${marked.parse(content)}</div>
293
+ <div class="expand-indicator"></div>
294
+ </div>
295
+ `;
296
+ sourcesContainer.appendChild(sourceItem);
297
+
298
+ const sourceUrl = sourceItem.querySelector('.source-url');
299
+ const sourceContent = sourceItem.querySelector('.source-content');
300
+ const snippetDiv = sourceItem.querySelector('.source-snippet');
301
+ const fullDiv = sourceItem.querySelector('.source-full');
302
+
303
+ sourceContent.addEventListener('click', function(e) {
304
+ if (!sourceItem.classList.contains('expanded')) {
305
+ sourceItem.classList.add('expanded');
306
+ snippetDiv.style.display = 'none';
307
+ fullDiv.style.display = 'block';
308
+ } else if (e.clientY > sourceContent.getBoundingClientRect().bottom - 30) {
309
+ sourceItem.classList.remove('expanded');
310
+ snippetDiv.style.display = 'block';
311
+ fullDiv.style.display = 'none';
312
+ }
313
+ });
314
+
315
+ sourceUrl.addEventListener('click', function(e) {
316
+ e.stopPropagation();
317
+ });
318
+ }
319
+ });
320
+ } else {
321
+ sourcesContainer.innerHTML = '<h2>Sources</h2><p>No source information available.</p>';
322
+ }
323
+ }
324
+ // Make Plotly charts responsive on window resize
325
+ window.addEventListener('resize', function() {
326
+ const plots = document.querySelectorAll('.js-plotly-plot');
327
+ plots.forEach(plot => {
328
+ Plotly.Plots.resize(plot);
329
+ });
330
+ });
331
+ </script>
332
+ </body>
333
+ </html>