JymNils commited on
Commit
f506fdb
·
verified ·
1 Parent(s): c64c746

el tamaño del widget se resetea al hacer una edicion o borrado de una linea, que esto no suceda y se mantenga - Initial Deployment

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +603 -18
  3. prompts.txt +11 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Dashboard
3
- emoji: 👀
4
- colorFrom: gray
5
- colorTo: yellow
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: dashboard
3
+ emoji: 🐳
4
+ colorFrom: red
5
+ colorTo: purple
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,604 @@
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>Custom Dashboard</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://unpkg.com/feather-icons"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/sortablejs@1.14.0/Sortable.min.js"></script>
10
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
11
+ <style>
12
+ .widget {
13
+ transition: all 0.2s ease;
14
+ position: relative;
15
+ overflow: hidden;
16
+ min-width: 250px;
17
+ min-height: 150px;
18
+ width: calc(33.333% - 20px);
19
+ flex: 0 0 calc(33.333% - 20px);
20
+ margin-bottom: 20px;
21
+ resize: vertical;
22
+ }
23
+ .widget.size-1 {
24
+ width: calc(33.333% - 20px);
25
+ flex: 0 0 calc(33.333% - 20px);
26
+ height: 150px;
27
+ }
28
+ .widget.size-2 {
29
+ width: calc(66.666% - 20px);
30
+ flex: 0 0 calc(66.666% - 20px);
31
+ height: 200px;
32
+ }
33
+ .widget.size-3 {
34
+ width: calc(100% - 20px);
35
+ flex: 0 0 calc(100% - 20px);
36
+ height: 250px;
37
+ }
38
+ .resize-controls {
39
+ position: absolute;
40
+ right: 10px;
41
+ top: 10px;
42
+ display: flex;
43
+ gap: 5px;
44
+ z-index: 10;
45
+ }
46
+ .resize-btn {
47
+ width: 20px;
48
+ height: 20px;
49
+ background: #f0f0f0;
50
+ border: 1px solid #ddd;
51
+ border-radius: 3px;
52
+ display: flex;
53
+ align-items: center;
54
+ justify-content: center;
55
+ cursor: pointer;
56
+ font-size: 10px;
57
+ }
58
+ .resize-btn:hover {
59
+ background: #e0e0e0;
60
+ }
61
+ .widget:hover {
62
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
63
+ }
64
+ .bookmark-item {
65
+ padding: 0.05rem 0.3rem;
66
+ margin: 0;
67
+ }
68
+ .bookmark-item:hover {
69
+ background-color: rgba(59, 130, 246, 0.1);
70
+ margin: 0;
71
+ }
72
+ .bookmark-link {
73
+ display: flex;
74
+ align-items: center;
75
+ text-decoration: none;
76
+ color: inherit;
77
+ flex-grow: 1;
78
+ padding: 0.1rem 0;
79
+ }
80
+ .sortable-ghost {
81
+ opacity: 0.5;
82
+ background: #c8ebfb;
83
+ }
84
+ </style>
85
+ </head>
86
+ <body class="bg-gray-50 font-sans">
87
+ <div class="container mx-auto px-4 py-8">
88
+ <!-- Header -->
89
+ <header class="flex justify-between items-center mb-8">
90
+ <h1 class="text-3xl font-bold text-blue-600">My Dashboard</h1>
91
+ <div class="flex space-x-4">
92
+ <button id="addWidgetBtn" class="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 transition flex items-center">
93
+ <i data-feather="plus" class="mr-2"></i> Add Widget
94
+ </button>
95
+ </div>
96
+ </header>
97
+
98
+ <!-- Widgets Container -->
99
+ <div id="widgetsContainer" class="flex flex-wrap gap-6">
100
+ <!-- Widgets will be added here -->
101
+ </div>
102
+
103
+ <!-- Add Widget Modal -->
104
+ <div id="addWidgetModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
105
+ <div class="bg-white rounded-lg p-6 w-full max-w-md">
106
+ <div class="flex justify-between items-center mb-4">
107
+ <h3 class="text-xl font-semibold">Add New Widget</h3>
108
+ <button id="closeWidgetModal" class="text-gray-500 hover:text-gray-700">
109
+ <i data-feather="x"></i>
110
+ </button>
111
+ </div>
112
+ <div class="mb-4">
113
+ <label class="block text-gray-700 mb-2">Widget Title</label>
114
+ <input type="text" id="widgetTitle" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
115
+ </div>
116
+ <div class="flex justify-end space-x-3">
117
+ <button id="cancelWidget" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300">Cancel</button>
118
+ <button id="confirmWidget" class="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600">Add Widget</button>
119
+ </div>
120
+ </div>
121
+ </div>
122
+
123
+ <!-- Add Bookmark Modal -->
124
+ <div id="addBookmarkModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
125
+ <div class="bg-white rounded-lg p-6 w-full max-w-md">
126
+ <div class="flex justify-between items-center mb-4">
127
+ <h3 class="text-xl font-semibold">Add New Bookmark</h3>
128
+ <button id="closeBookmarkModal" class="text-gray-500 hover:text-gray-700">
129
+ <i data-feather="x"></i>
130
+ </button>
131
+ </div>
132
+ <div class="mb-4">
133
+ <label class="block text-gray-700 mb-2">Title</label>
134
+ <input type="text" id="bookmarkTitle" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
135
+ </div>
136
+ <div class="mb-4">
137
+ <label class="block text-gray-700 mb-2">URL</label>
138
+ <input type="text" id="bookmarkUrl" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="https://">
139
+ </div>
140
+ <div class="flex justify-end space-x-3">
141
+ <button id="cancelBookmark" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300">Cancel</button>
142
+ <button id="confirmBookmark" class="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600">Add Bookmark</button>
143
+ </div>
144
+ </div>
145
+ </div>
146
+
147
+ <!-- Edit Widget Modal -->
148
+ <div id="editWidgetModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
149
+ <div class="bg-white rounded-lg p-6 w-full max-w-md">
150
+ <div class="flex justify-between items-center mb-4">
151
+ <h3 class="text-xl font-semibold">Edit Widget</h3>
152
+ <button id="closeEditWidgetModal" class="text-gray-500 hover:text-gray-700">
153
+ <i data-feather="x"></i>
154
+ </button>
155
+ </div>
156
+ <div class="mb-4">
157
+ <label class="block text-gray-700 mb-2">Widget Title</label>
158
+ <input type="text" id="editWidgetTitle" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
159
+ </div>
160
+ <div class="flex justify-end space-x-3">
161
+ <button id="deleteWidget" class="px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600">Delete Widget</button>
162
+ <button id="saveWidget" class="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600">Save Changes</button>
163
+ </div>
164
+ </div>
165
+ </div>
166
+ </div>
167
+
168
+ <script>
169
+ document.addEventListener('DOMContentLoaded', function() {
170
+ feather.replace();
171
+
172
+ // Initialize dashboard with sample widgets if empty
173
+ if (!localStorage.getItem('widgets')) {
174
+ const sampleWidgets = [
175
+ {
176
+ id: 'widget-' + Date.now(),
177
+ title: 'Favorites',
178
+ width: '300px',
179
+ height: '200px',
180
+ bookmarks: [
181
+ { id: 'bookmark-' + Date.now() + 1, title: 'Google', url: 'https://google.com' },
182
+ { id: 'bookmark-' + Date.now() + 2, title: 'GitHub', url: 'https://github.com' }
183
+ ]
184
+ },
185
+ {
186
+ id: 'widget-' + (Date.now() + 1),
187
+ title: 'Social',
188
+ width: '300px',
189
+ height: '200px',
190
+ bookmarks: [
191
+ { id: 'bookmark-' + (Date.now() + 3), title: 'Twitter', url: 'https://twitter.com' },
192
+ { id: 'bookmark-' + (Date.now() + 4), title: 'Facebook', url: 'https://facebook.com' }
193
+ ]
194
+ }
195
+ ];
196
+ localStorage.setItem('widgets', JSON.stringify(sampleWidgets));
197
+ }
198
+
199
+ // Load widgets from localStorage
200
+ loadWidgets();
201
+
202
+ // Make widgets sortable
203
+ const widgetsContainer = document.getElementById('widgetsContainer');
204
+ new Sortable(widgetsContainer, {
205
+ animation: 150,
206
+ ghostClass: 'sortable-ghost',
207
+ onEnd: function() {
208
+ saveWidgetsOrder();
209
+ }
210
+ });
211
+
212
+ // Modal controls
213
+ const addWidgetModal = document.getElementById('addWidgetModal');
214
+ const addBookmarkModal = document.getElementById('addBookmarkModal');
215
+ const editWidgetModal = document.getElementById('editWidgetModal');
216
+ let currentWidgetId = null;
217
+ let editMode = false;
218
+
219
+ // Show/hide add widget modal
220
+ document.getElementById('addWidgetBtn').addEventListener('click', () => {
221
+ addWidgetModal.classList.remove('hidden');
222
+ });
223
+
224
+ document.getElementById('closeWidgetModal').addEventListener('click', () => {
225
+ addWidgetModal.classList.add('hidden');
226
+ });
227
+
228
+ document.getElementById('cancelWidget').addEventListener('click', () => {
229
+ addWidgetModal.classList.add('hidden');
230
+ });
231
+
232
+ // Show/hide add bookmark modal
233
+ function showAddBookmarkModal(widgetId) {
234
+ currentWidgetId = widgetId;
235
+ // Reset modal state
236
+ document.getElementById('bookmarkTitle').value = '';
237
+ document.getElementById('bookmarkUrl').value = '';
238
+ document.querySelector('#addBookmarkModal h3').textContent = 'Add New Bookmark';
239
+ document.getElementById('confirmBookmark').textContent = 'Add Bookmark';
240
+ delete document.getElementById('confirmBookmark').dataset.bookmarkId;
241
+ addBookmarkModal.classList.remove('hidden');
242
+ }
243
+
244
+ document.getElementById('closeBookmarkModal').addEventListener('click', () => {
245
+ addBookmarkModal.classList.add('hidden');
246
+ });
247
+
248
+ document.getElementById('cancelBookmark').addEventListener('click', () => {
249
+ addBookmarkModal.classList.add('hidden');
250
+ });
251
+
252
+ // Show/hide edit widget modal
253
+ function showEditWidgetModal(widgetId) {
254
+ currentWidgetId = widgetId;
255
+ const widgets = JSON.parse(localStorage.getItem('widgets'));
256
+ const widget = widgets.find(w => w.id === widgetId);
257
+ document.getElementById('editWidgetTitle').value = widget.title;
258
+ editWidgetModal.classList.remove('hidden');
259
+ }
260
+
261
+ document.getElementById('closeEditWidgetModal').addEventListener('click', () => {
262
+ editWidgetModal.classList.add('hidden');
263
+ });
264
+
265
+ // Add new widget
266
+ document.getElementById('confirmWidget').addEventListener('click', () => {
267
+ const title = document.getElementById('widgetTitle').value.trim();
268
+ if (title) {
269
+ const newWidget = {
270
+ id: 'widget-' + Date.now(),
271
+ title: title,
272
+ bookmarks: [],
273
+ size: 1 // Default to smallest size (1/3 width)
274
+ };
275
+
276
+ const widgets = JSON.parse(localStorage.getItem('widgets')) || [];
277
+ widgets.push(newWidget);
278
+ localStorage.setItem('widgets', JSON.stringify(widgets));
279
+
280
+ loadWidgets();
281
+ addWidgetModal.classList.add('hidden');
282
+ document.getElementById('widgetTitle').value = '';
283
+ }
284
+ });
285
+
286
+ // Add or edit bookmark
287
+ document.getElementById('confirmBookmark').addEventListener('click', () => {
288
+ const title = document.getElementById('bookmarkTitle').value.trim();
289
+ let url = document.getElementById('bookmarkUrl').value.trim();
290
+
291
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
292
+ url = 'https://' + url;
293
+ }
294
+
295
+ if (title && url) {
296
+ const widgets = JSON.parse(localStorage.getItem('widgets'));
297
+ const widgetIndex = widgets.findIndex(w => w.id === currentWidgetId);
298
+
299
+ if (widgetIndex !== -1) {
300
+ const bookmarkId = document.getElementById('confirmBookmark').dataset.bookmarkId;
301
+
302
+ if (bookmarkId) {
303
+ // Editing existing bookmark
304
+ const bookmarkIndex = widgets[widgetIndex].bookmarks.findIndex(b => b.id === bookmarkId);
305
+ if (bookmarkIndex !== -1) {
306
+ widgets[widgetIndex].bookmarks[bookmarkIndex].title = title;
307
+ widgets[widgetIndex].bookmarks[bookmarkIndex].url = url;
308
+ }
309
+ } else {
310
+ // Adding new bookmark
311
+ const newBookmark = {
312
+ id: 'bookmark-' + Date.now(),
313
+ title: title,
314
+ url: url
315
+ };
316
+ widgets[widgetIndex].bookmarks.push(newBookmark);
317
+ }
318
+
319
+ localStorage.setItem('widgets', JSON.stringify(widgets));
320
+
321
+ loadWidgets();
322
+ addBookmarkModal.classList.add('hidden');
323
+ document.getElementById('bookmarkTitle').value = '';
324
+ document.getElementById('bookmarkUrl').value = '';
325
+
326
+ // Reset modal state
327
+ document.querySelector('#addBookmarkModal h3').textContent = 'Add New Bookmark';
328
+ document.getElementById('confirmBookmark').textContent = 'Add Bookmark';
329
+ delete document.getElementById('confirmBookmark').dataset.bookmarkId;
330
+ }
331
+ }
332
+ });
333
+
334
+ // Save widget changes
335
+ document.getElementById('saveWidget').addEventListener('click', () => {
336
+ const title = document.getElementById('editWidgetTitle').value.trim();
337
+ if (title) {
338
+ const widgets = JSON.parse(localStorage.getItem('widgets'));
339
+ const widgetIndex = widgets.findIndex(w => w.id === currentWidgetId);
340
+
341
+ if (widgetIndex !== -1) {
342
+ widgets[widgetIndex].title = title;
343
+ localStorage.setItem('widgets', JSON.stringify(widgets));
344
+
345
+ loadWidgets();
346
+ editWidgetModal.classList.add('hidden');
347
+ }
348
+ }
349
+ });
350
+
351
+ // Delete widget
352
+ document.getElementById('deleteWidget').addEventListener('click', () => {
353
+ if (confirm('Are you sure you want to delete this widget and all its bookmarks?')) {
354
+ const widgets = JSON.parse(localStorage.getItem('widgets'));
355
+ const updatedWidgets = widgets.filter(w => w.id !== currentWidgetId);
356
+ localStorage.setItem('widgets', JSON.stringify(updatedWidgets));
357
+
358
+ loadWidgets();
359
+ editWidgetModal.classList.add('hidden');
360
+ }
361
+ });
362
+
363
+ // Load widgets from localStorage
364
+ function loadWidgets() {
365
+ const widgetsContainer = document.getElementById('widgetsContainer');
366
+ widgetsContainer.innerHTML = '';
367
+
368
+ const widgets = JSON.parse(localStorage.getItem('widgets')) || [];
369
+
370
+ widgets.forEach(widget => {
371
+ const widgetElement = document.createElement('div');
372
+ widgetElement.className = 'widget bg-white rounded-lg shadow-md p-4 relative';
373
+ widgetElement.dataset.widgetId = widget.id;
374
+ widgetElement.style.width = widget.width || '300px';
375
+ widgetElement.style.height = widget.height || '200px';
376
+
377
+ // Add resize controls
378
+ const resizeControls = document.createElement('div');
379
+ resizeControls.className = 'resize-controls';
380
+
381
+ // Horizontal resize buttons
382
+ const hSizes = [1, 2, 3];
383
+ hSizes.forEach(size => {
384
+ const sizeBtn = document.createElement('button');
385
+ sizeBtn.className = 'resize-btn';
386
+ sizeBtn.textContent = `${size}x`;
387
+ sizeBtn.title = `Width ${size}/3`;
388
+ sizeBtn.addEventListener('click', (e) => {
389
+ e.stopPropagation();
390
+ resizeWidget(widget.id, size, 'width');
391
+ });
392
+ resizeControls.appendChild(sizeBtn);
393
+ });
394
+
395
+
396
+ widgetElement.appendChild(resizeControls);
397
+
398
+ // Set initial size classes
399
+ widgetElement.classList.add(`size-${widget.widthSize || 1}`);
400
+ widgetElement.classList.add(`height-${widget.heightSize || 1}`);
401
+ widgetElement.style.height = widget.height || '150px';
402
+
403
+ // Widget header
404
+ const header = document.createElement('div');
405
+ header.className = 'flex justify-between items-center mb-4';
406
+
407
+ const title = document.createElement('h2');
408
+ title.className = 'text-xl font-semibold text-gray-800';
409
+ title.textContent = widget.title;
410
+
411
+ const controls = document.createElement('div');
412
+ controls.className = 'flex space-x-2 widget-edit-controls hidden';
413
+
414
+ const editBtn = document.createElement('button');
415
+ editBtn.className = 'text-blue-500 hover:text-blue-700';
416
+ editBtn.innerHTML = '<i data-feather="edit-2" class="w-4 h-4"></i>';
417
+ editBtn.addEventListener('click', () => showEditWidgetModal(widget.id));
418
+
419
+ const addBookmarkBtn = document.createElement('button');
420
+ addBookmarkBtn.className = 'text-green-500 hover:text-green-700';
421
+ addBookmarkBtn.innerHTML = '<i data-feather="plus" class="w-4 h-4"></i>';
422
+ addBookmarkBtn.addEventListener('click', () => showAddBookmarkModal(widget.id));
423
+
424
+ controls.appendChild(addBookmarkBtn);
425
+ controls.appendChild(editBtn);
426
+
427
+ header.appendChild(title);
428
+ header.appendChild(controls);
429
+
430
+ // Bookmarks list
431
+ const bookmarksList = document.createElement('div');
432
+ bookmarksList.className = 'space-y-1';
433
+
434
+ widget.bookmarks.forEach(bookmark => {
435
+ const bookmarkItem = document.createElement('div');
436
+ bookmarkItem.className = 'bookmark-item flex justify-between items-center p-1 rounded-md transition cursor-pointer';
437
+ bookmarkItem.dataset.bookmarkId = bookmark.id;
438
+
439
+ const bookmarkLink = document.createElement('a');
440
+ bookmarkLink.className = 'bookmark-link text-blue-600 hover:text-blue-800 flex-grow';
441
+ bookmarkLink.href = bookmark.url;
442
+ bookmarkLink.target = '_blank';
443
+ // Add double click handler
444
+ bookmarkLink.addEventListener('dblclick', (e) => {
445
+ e.preventDefault();
446
+ window.open(bookmark.url, '_blank');
447
+ });
448
+
449
+ const linkIcon = document.createElement('i');
450
+ linkIcon.dataset.feather = 'external-link';
451
+ linkIcon.className = 'mr-1 w-3 h-3';
452
+
453
+ const linkText = document.createElement('span');
454
+ linkText.className = 'truncate';
455
+ linkText.textContent = bookmark.title;
456
+ linkText.title = bookmark.title;
457
+
458
+ bookmarkLink.appendChild(linkIcon);
459
+ bookmarkLink.appendChild(linkText);
460
+
461
+ const controls = document.createElement('div');
462
+ controls.className = 'flex space-x-1 ml-2';
463
+
464
+ const editBtn = document.createElement('button');
465
+ editBtn.className = 'text-gray-500 hover:text-gray-700';
466
+ editBtn.innerHTML = '<i data-feather="edit" class="w-3 h-3"></i>';
467
+ editBtn.addEventListener('click', (e) => {
468
+ e.stopPropagation();
469
+ editBookmark(widget.id, bookmark.id);
470
+ });
471
+
472
+ const deleteBtn = document.createElement('button');
473
+ deleteBtn.className = 'text-red-500 hover:text-red-700';
474
+ deleteBtn.innerHTML = '<i data-feather="trash-2" class="w-3 h-3"></i>';
475
+ deleteBtn.addEventListener('click', (e) => {
476
+ e.stopPropagation();
477
+ deleteBookmark(widget.id, bookmark.id);
478
+ });
479
+
480
+ controls.appendChild(editBtn);
481
+ controls.appendChild(deleteBtn);
482
+
483
+ bookmarkItem.appendChild(bookmarkLink);
484
+ bookmarkItem.appendChild(controls);
485
+
486
+ bookmarksList.appendChild(bookmarkItem);
487
+ });
488
+
489
+ // Add bookmark button (visible in edit mode)
490
+ const addBookmarkBtnBottom = document.createElement('button');
491
+ addBookmarkBtnBottom.className = 'absolute bottom-2 right-2 p-1 text-blue-500 hover:text-blue-700 rounded-full hover:bg-blue-50';
492
+ addBookmarkBtnBottom.innerHTML = '<i data-feather="plus" class="w-4 h-4"></i>';
493
+ addBookmarkBtnBottom.addEventListener('click', () => showAddBookmarkModal(widget.id));
494
+
495
+ widgetElement.appendChild(header);
496
+ widgetElement.appendChild(bookmarksList);
497
+ widgetElement.appendChild(addBookmarkBtnBottom);
498
+
499
+ widgetsContainer.appendChild(widgetElement);
500
+ });
501
+
502
+ feather.replace();
503
+ }
504
+
505
+ // Edit bookmark
506
+ function editBookmark(widgetId, bookmarkId) {
507
+ const widgets = JSON.parse(localStorage.getItem('widgets'));
508
+ const widgetIndex = widgets.findIndex(w => w.id === widgetId);
509
+
510
+ if (widgetIndex !== -1) {
511
+ const bookmark = widgets[widgetIndex].bookmarks.find(b => b.id === bookmarkId);
512
+ if (bookmark) {
513
+ document.getElementById('bookmarkTitle').value = bookmark.title;
514
+ document.getElementById('bookmarkUrl').value = bookmark.url;
515
+ currentWidgetId = widgetId;
516
+
517
+ // Store the bookmark ID to update
518
+ document.getElementById('confirmBookmark').dataset.bookmarkId = bookmarkId;
519
+
520
+ // Change modal title and button text
521
+ document.querySelector('#addBookmarkModal h3').textContent = 'Edit Bookmark';
522
+ document.getElementById('confirmBookmark').textContent = 'Save Changes';
523
+
524
+ addBookmarkModal.classList.remove('hidden');
525
+ }
526
+ }
527
+ }
528
+
529
+ // Delete bookmark
530
+ function deleteBookmark(widgetId, bookmarkId) {
531
+ if (confirm('Are you sure you want to delete this bookmark?')) {
532
+ const widgets = JSON.parse(localStorage.getItem('widgets'));
533
+ const widgetIndex = widgets.findIndex(w => w.id === widgetId);
534
+
535
+ if (widgetIndex !== -1) {
536
+ widgets[widgetIndex].bookmarks = widgets[widgetIndex].bookmarks.filter(b => b.id !== bookmarkId);
537
+ localStorage.setItem('widgets', JSON.stringify(widgets));
538
+
539
+ loadWidgets();
540
+ }
541
+ }
542
+ }
543
+
544
+ // Save widgets order after drag and drop
545
+ function saveWidgetsOrder() {
546
+ const widgetsContainer = document.getElementById('widgetsContainer');
547
+ const widgetElements = Array.from(widgetsContainer.children);
548
+
549
+ const widgets = JSON.parse(localStorage.getItem('widgets'));
550
+ const orderedWidgets = [];
551
+
552
+ widgetElements.forEach(element => {
553
+ const widgetId = element.dataset.widgetId;
554
+ const widget = widgets.find(w => w.id === widgetId);
555
+ if (widget) {
556
+ orderedWidgets.push(widget);
557
+ }
558
+ });
559
+
560
+ localStorage.setItem('widgets', JSON.stringify(orderedWidgets));
561
+ }
562
+
563
+ // Resize widget function
564
+ function resizeWidget(widgetId, size, dimension) {
565
+ const widgets = JSON.parse(localStorage.getItem('widgets'));
566
+ const widgetIndex = widgets.findIndex(w => w.id === widgetId);
567
+
568
+ if (widgetIndex !== -1) {
569
+ if (dimension === 'width') {
570
+ widgets[widgetIndex].widthSize = size;
571
+ } else {
572
+ widgets[widgetIndex].heightSize = size;
573
+ }
574
+
575
+ localStorage.setItem('widgets', JSON.stringify(widgets));
576
+
577
+ // Update all widgets to ensure proper layout
578
+ const widgetElements = document.querySelectorAll('.widget');
579
+ widgetElements.forEach(el => {
580
+ const id = el.dataset.widgetId;
581
+ const widget = widgets.find(w => w.id === id);
582
+
583
+ // Remove all size classes
584
+ el.className = el.className.replace(/\b(size|height)-\d\b/g, '');
585
+
586
+ // Add width size class
587
+ const widthSize = widget.widthSize || 1;
588
+ el.classList.add(`size-${widthSize}`);
589
+
590
+ // Add height size class
591
+ const heightSize = widget.heightSize || 1;
592
+ el.classList.add(`height-${heightSize}`);
593
+
594
+ // Set height based on size
595
+ if (heightSize === 1) el.style.height = '150px';
596
+ else if (heightSize === 2) el.style.height = '200px';
597
+ else if (heightSize === 3) el.style.height = '250px';
598
+ });
599
+ }
600
+ }
601
+ });
602
+ </script>
603
+ </body>
604
  </html>
prompts.txt ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ quiero un sitio parecido https://protopage.com/#Bookmarks quiero que se puede añadir , editar,borrar bookmarks, asi como añadir nuevos widgets de bookmarks, que los widgets se puedan mover de lugar en la pantalla, de modo que yo pueda organizarlos personalmente
2
+ quiero que los widgets puedan cambiar su tamaño
3
+ no quiero que los widgets a los que se les ha modificado su tamaño se sobrepongan a otros, si un widget ha crecido mas alla de su espacio asignado, debe desplazar al otro para hacer espacio, haz que las dimensiones de los widgets olo puedan tener 3 estados de tamaño horizontal, uno que sea 1/3 del espacio, otros 2/3 y el final 3/3
4
+ añade a los widgets 3 pequeño icono que diga 1x 2x 3x, al presionar estos iconos el wided ocupara mas espacio en la pantalla y movera a los otros para que todo se ajuste perfectamente
5
+ deja que uno pueda redimencionar los widgets de manera vertical
6
+ quita los botones de redimensionado vertical, deja que el usuario estire el widget de la parte inferior
7
+ junta mas los links dentro del widget, de manera que entren mas, cuando se haga doble click sobre el link este debe ir ala pagina web que esta progamado
8
+ delete the edit mode button, make the widgets have a buton for each link that let you edit and delete the link, and one + icon on the the bottom right to add a new link
9
+ los links dentro de los widgets estan muy separados, reduce los amrgenes superior e inferior de los espacios donde estan los links
10
+ el boton de edicion de los links no funciona
11
+ el tamaño del widget se resetea al hacer una edicion o borrado de una linea, que esto no suceda y se mantenga