steake commited on
Commit
e855e5e
·
verified ·
1 Parent(s): ca7232a

pull all image prompts up to a single JS block accessible from the top of the page.

Browse files
Files changed (2) hide show
  1. components/image-manager.js +366 -0
  2. index.html +220 -120
components/image-manager.js ADDED
@@ -0,0 +1,366 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Image Manager Web Component
3
+ * Centralized management of all image prompts and configurations
4
+ * Provides a single source of truth for all image URLs in the application
5
+ */
6
+
7
+ class ImageManager extends HTMLElement {
8
+ constructor() {
9
+ super();
10
+ this.attachShadow({ mode: 'open' });
11
+ this.config = null;
12
+ this.imageCache = new Map();
13
+ }
14
+
15
+ connectedCallback() {
16
+ this.loadConfig();
17
+ this.render();
18
+ }
19
+
20
+ loadConfig() {
21
+ // Try to load from JSON config element
22
+ const configElement = document.getElementById('imagePromptsConfig');
23
+ if (configElement) {
24
+ try {
25
+ this.config = JSON.parse(configElement.textContent);
26
+ } catch (e) {
27
+ console.error('Failed to parse image prompts config:', e);
28
+ this.config = this.getDefaultConfig();
29
+ }
30
+ } else {
31
+ this.config = this.getDefaultConfig();
32
+ }
33
+
34
+ // Store in global window object for easy access
35
+ window.imagePrompts = this.config;
36
+ }
37
+
38
+ getDefaultConfig() {
39
+ return {
40
+ hero: "https://static.photos/medical/800x600/1",
41
+ productImages: [
42
+ "https://static.photos/medical/400x300/101",
43
+ "https://static.photos/medical/400x300/102",
44
+ "https://static.photos/medical/400x300/103",
45
+ "https://static.photos/medical/400x300/104"
46
+ ],
47
+ about: "https://static.photos/workspace/800x600/201",
48
+ testimonials: [
49
+ "https://static.photos/people/48x48/301",
50
+ "https://static.photos/people/48x48/302",
51
+ "https://static.photos/people/48x48/303"
52
+ ],
53
+ categories: {
54
+ medical: "medical",
55
+ workspace: "workspace",
56
+ people: "people",
57
+ abstract: "abstract"
58
+ },
59
+ placeholder: "https://static.photos/abstract/100x100",
60
+ fallback: "https://static.photos/abstract/400x300"
61
+ };
62
+ }
63
+
64
+ render() {
65
+ this.shadowRoot.innerHTML = `
66
+ <style>
67
+ :host {
68
+ display: none;
69
+ }
70
+
71
+ .image-manager-panel {
72
+ position: fixed;
73
+ top: 100px;
74
+ right: 20px;
75
+ width: 300px;
76
+ background: white;
77
+ border-radius: 8px;
78
+ box-shadow: 0 4px 20px rgba(0,0,0,0.15);
79
+ padding: 20px;
80
+ z-index: 9999;
81
+ display: none;
82
+ font-family: -apple-system, BlinkMacSystemFont, sans-serif;
83
+ }
84
+
85
+ .image-manager-panel.active {
86
+ display: block;
87
+ }
88
+
89
+ .image-manager-header {
90
+ display: flex;
91
+ justify-content: space-between;
92
+ align-items: center;
93
+ margin-bottom: 15px;
94
+ padding-bottom: 10px;
95
+ border-bottom: 1px solid #e5e5e5;
96
+ }
97
+
98
+ .image-manager-title {
99
+ font-weight: bold;
100
+ font-size: 16px;
101
+ color: #333;
102
+ }
103
+
104
+ .image-manager-close {
105
+ background: none;
106
+ border: none;
107
+ font-size: 20px;
108
+ cursor: pointer;
109
+ color: #666;
110
+ }
111
+
112
+ .image-manager-section {
113
+ margin-bottom: 15px;
114
+ }
115
+
116
+ .image-manager-section-title {
117
+ font-size: 14px;
118
+ font-weight: 600;
119
+ color: #555;
120
+ margin-bottom: 8px;
121
+ }
122
+
123
+ .image-manager-list {
124
+ display: flex;
125
+ flex-direction: column;
126
+ gap: 5px;
127
+ }
128
+
129
+ .image-manager-item {
130
+ display: flex;
131
+ justify-content: space-between;
132
+ align-items: center;
133
+ padding: 8px;
134
+ background: #f8f9fa;
135
+ border-radius: 4px;
136
+ font-size: 12px;
137
+ }
138
+
139
+ .image-manager-item:hover {
140
+ background: #e9ecef;
141
+ }
142
+
143
+ .image-manager-url {
144
+ overflow: hidden;
145
+ text-overflow: ellipsis;
146
+ white-space: nowrap;
147
+ max-width: 180px;
148
+ }
149
+
150
+ .image-manager-copy {
151
+ background: #5d9245;
152
+ color: white;
153
+ border: none;
154
+ border-radius: 3px;
155
+ padding: 3px 8px;
156
+ font-size: 11px;
157
+ cursor: pointer;
158
+ }
159
+
160
+ .image-manager-copy:hover {
161
+ background: #3f7344;
162
+ }
163
+
164
+ .image-manager-toggle {
165
+ position: fixed;
166
+ top: 150px;
167
+ right: 20px;
168
+ background: #5d9245;
169
+ color: white;
170
+ border: none;
171
+ border-radius: 50%;
172
+ width: 40px;
173
+ height: 40px;
174
+ display: flex;
175
+ align-items: center;
176
+ justify-content: center;
177
+ cursor: pointer;
178
+ z-index: 9998;
179
+ box-shadow: 0 2px 10px rgba(0,0,0,0.2);
180
+ }
181
+ </style>
182
+
183
+ <button class="image-manager-toggle">
184
+ <i class="fas fa-images"></i>
185
+ </button>
186
+
187
+ <div class="image-manager-panel">
188
+ <div class="image-manager-header">
189
+ <div class="image-manager-title">Image Prompts Manager</div>
190
+ <button class="image-manager-close">&times;</button>
191
+ </div>
192
+
193
+ <div class="image-manager-section">
194
+ <div class="image-manager-section-title">Hero Image</div>
195
+ <div class="image-manager-list">
196
+ <div class="image-manager-item">
197
+ <div class="image-manager-url" title="${this.config?.hero || ''}">
198
+ ${this.config?.hero ? this.config.hero.substring(0, 30) + '...' : ''}
199
+ </div>
200
+ <button class="image-manager-copy" data-url="${this.config?.hero || ''}">Copy</button>
201
+ </div>
202
+ </div>
203
+ </div>
204
+
205
+ <div class="image-manager-section">
206
+ <div class="image-manager-section-title">Product Images (${this.config?.productImages?.length || 0})</div>
207
+ <div class="image-manager-list">
208
+ ${this.config?.productImages?.map((url, index) => `
209
+ <div class="image-manager-item">
210
+ <div class="image-manager-url" title="${url}">
211
+ Product ${index + 1}: ${url.substring(0, 25)}...
212
+ </div>
213
+ <button class="image-manager-copy" data-url="${url}">Copy</button>
214
+ </div>
215
+ `).join('') || '<div style="padding: 8px; color: #666; font-size: 12px;">No product images configured</div>'}
216
+ </div>
217
+ </div>
218
+
219
+ <div class="image-manager-section">
220
+ <div class="image-manager-section-title">Testimonial Images (${this.config?.testimonials?.length || 0})</div>
221
+ <div class="image-manager-list">
222
+ ${this.config?.testimonials?.map((url, index) => `
223
+ <div class="image-manager-item">
224
+ <div class="image-manager-url" title="${url}">
225
+ Testimonial ${index + 1}: ${url.substring(0, 25)}...
226
+ </div>
227
+ <button class="image-manager-copy" data-url="${url}">Copy</button>
228
+ </div>
229
+ `).join('') || '<div style="padding: 8px; color: #666; font-size: 12px;">No testimonial images configured</div>'}
230
+ </div>
231
+ </div>
232
+
233
+ <div class="image-manager-section">
234
+ <div class="image-manager-section-title">Configuration</div>
235
+ <div class="image-manager-list">
236
+ <div class="image-manager-item">
237
+ <div>Categories: ${this.config?.categories ? Object.keys(this.config.categories).join(', ') : ''}</div>
238
+ <button class="image-manager-copy" data-url="${JSON.stringify(this.config)}">Copy Config</button>
239
+ </div>
240
+ </div>
241
+ </div>
242
+ </div>
243
+ `;
244
+
245
+ this.addEventListeners();
246
+ }
247
+
248
+ addEventListeners() {
249
+ const toggleBtn = this.shadowRoot.querySelector('.image-manager-toggle');
250
+ const closeBtn = this.shadowRoot.querySelector('.image-manager-close');
251
+ const panel = this.shadowRoot.querySelector('.image-manager-panel');
252
+ const copyButtons = this.shadowRoot.querySelectorAll('.image-manager-copy');
253
+
254
+ if (toggleBtn && panel) {
255
+ toggleBtn.addEventListener('click', () => {
256
+ panel.classList.toggle('active');
257
+ });
258
+ }
259
+
260
+ if (closeBtn && panel) {
261
+ closeBtn.addEventListener('click', () => {
262
+ panel.classList.remove('active');
263
+ });
264
+ }
265
+
266
+ if (copyButtons) {
267
+ copyButtons.forEach(btn => {
268
+ btn.addEventListener('click', (e) => {
269
+ const url = e.currentTarget.getAttribute('data-url');
270
+ this.copyToClipboard(url);
271
+
272
+ // Show feedback
273
+ const originalText = e.currentTarget.textContent;
274
+ e.currentTarget.textContent = 'Copied!';
275
+ e.currentTarget.style.background = '#28a745';
276
+
277
+ setTimeout(() => {
278
+ e.currentTarget.textContent = originalText;
279
+ e.currentTarget.style.background = '#5d9245';
280
+ }, 1500);
281
+ });
282
+ });
283
+ }
284
+ }
285
+
286
+ copyToClipboard(text) {
287
+ navigator.clipboard.writeText(text).then(() => {
288
+ console.log('Image URL copied to clipboard:', text);
289
+ }).catch(err => {
290
+ console.error('Failed to copy:', err);
291
+ // Fallback method
292
+ const textArea = document.createElement('textarea');
293
+ textArea.value = text;
294
+ document.body.appendChild(textArea);
295
+ textArea.select();
296
+ document.execCommand('copy');
297
+ document.body.removeChild(textArea);
298
+ });
299
+ }
300
+
301
+ // Public API methods
302
+ getImage(category, index = 0) {
303
+ if (!this.config) return this.config?.fallback || '';
304
+
305
+ switch(category) {
306
+ case 'hero':
307
+ return this.config.hero;
308
+ case 'product':
309
+ return this.config.productImages[index] || this.config.fallback;
310
+ case 'testimonial':
311
+ return this.config.testimonials[index] || this.config.fallback;
312
+ case 'about':
313
+ return this.config.about;
314
+ case 'placeholder':
315
+ return this.config.placeholder;
316
+ default:
317
+ return this.config.fallback;
318
+ }
319
+ }
320
+
321
+ updateImage(category, value, index = 0) {
322
+ if (!this.config) return false;
323
+
324
+ switch(category) {
325
+ case 'hero':
326
+ this.config.hero = value;
327
+ break;
328
+ case 'product':
329
+ if (this.config.productImages && index < this.config.productImages.length) {
330
+ this.config.productImages[index] = value;
331
+ }
332
+ break;
333
+ case 'testimonial':
334
+ if (this.config.testimonials && index < this.config.testimonials.length) {
335
+ this.config.testimonials[index] = value;
336
+ }
337
+ break;
338
+ case 'about':
339
+ this.config.about = value;
340
+ break;
341
+ default:
342
+ return false;
343
+ }
344
+
345
+ // Update the JSON config element
346
+ const configElement = document.getElementById('imagePromptsConfig');
347
+ if (configElement) {
348
+ configElement.textContent = JSON.stringify(this.config, null, 2);
349
+ }
350
+
351
+ return true;
352
+ }
353
+
354
+ static get observedAttributes() {
355
+ return ['config'];
356
+ }
357
+
358
+ attributeChangedCallback(name, oldValue, newValue) {
359
+ if (name === 'config' && oldValue !== newValue) {
360
+ this.loadConfig();
361
+ this.render();
362
+ }
363
+ }
364
+ }
365
+
366
+ customElements.define('image-manager', ImageManager);
index.html CHANGED
@@ -108,6 +108,31 @@
108
  </style>
109
  </head>
110
  <body class="bg-gray-50">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  <!-- Header/Navigation -->
112
  <header class="bg-white shadow-sm sticky top-0 z-50">
113
  <div class="container mx-auto px-4 py-3 flex justify-between items-center">
@@ -117,8 +142,7 @@
117
  <span class="text-xl font-bold text-gray-800">PharmaCare</span>
118
  </a>
119
  </div>
120
-
121
- <div class="hidden md:flex space-x-8">
122
  <a href="#home" class="nav-link text-gray-700 hover:text-blue-600 font-medium">Home</a>
123
  <a href="#products" class="nav-link text-gray-700 hover:text-blue-600 font-medium">Products</a>
124
  <a href="#about" class="nav-link text-gray-700 hover:text-blue-600 font-medium">About</a>
@@ -162,8 +186,8 @@
162
  <a href="#about" class="border-2 border-white text-white hover:bg-white hover:text-[#5d9245] font-bold py-3 px-6 rounded-full text-center transition duration-300">Learn More</a>
163
  </div>
164
  </div>
165
- <div class="md:w-1/2 flex justify-center">
166
- <img src="https://static.photos/medical/800x600/1" alt="Pharmaceutical products" class="rounded-xl shadow-2xl max-w-md w-full floating">
167
  </div>
168
  </div>
169
  </section>
@@ -209,7 +233,7 @@
209
  <!-- Product 1 -->
210
  <div class="bg-white rounded-xl shadow-md overflow-hidden product-card transition duration-300">
211
  <div class="relative">
212
- <img src="https://static.photos/medical/400x300/101" alt="Xanax" class="w-full h-48 object-contain bg-gray-100 p-4">
213
  <span class="absolute top-2 right-2 bg-blue-500 text-white text-xs font-bold px-2 py-1 rounded-full">BESTSELLER</span>
214
  </div>
215
  <div class="p-6">
@@ -227,7 +251,7 @@
227
  <!-- Product 2 -->
228
  <div class="bg-white rounded-xl shadow-md overflow-hidden product-card transition duration-300">
229
  <div class="relative">
230
- <img src="https://static.photos/medical/400x300/102" alt="Valium" class="w-full h-48 object-contain bg-gray-100 p-4">
231
  </div>
232
  <div class="p-6">
233
  <h3 class="text-xl font-bold mb-2">Valium (Diazepam) 10mg</h3>
@@ -244,7 +268,7 @@
244
  <!-- Product 3 -->
245
  <div class="bg-white rounded-xl shadow-md overflow-hidden product-card transition duration-300">
246
  <div class="relative">
247
- <img src="https://static.photos/medical/400x300/103" alt="Viagra" class="w-full h-48 object-contain bg-gray-100 p-4">
248
  <span class="absolute top-2 right-2 bg-blue-500 text-white text-xs font-bold px-2 py-1 rounded-full">NEW</span>
249
  </div>
250
  <div class="p-6">
@@ -262,7 +286,7 @@
262
  <!-- Product 4 -->
263
  <div class="bg-white rounded-xl shadow-md overflow-hidden product-card transition duration-300">
264
  <div class="relative">
265
- <img src="https://static.photos/medical/400x300/104" alt="Codeine" class="w-full h-48 object-contain bg-gray-100 p-4">
266
  </div>
267
  <div class="p-6">
268
  <h3 class="text-xl font-bold mb-2">Codeine 30mg</h3>
@@ -275,7 +299,7 @@
275
  </div>
276
  </div>
277
  </div>
278
- </div>
279
 
280
  <div class="text-center mt-12">
281
  <a href="#" class="inline-block border-2 border-[#5d9245] text-[#5d9245] hover:bg-[#5d9245] hover:text-white font-bold py-3 px-8 rounded-full transition duration-300">
@@ -290,7 +314,7 @@
290
  <div class="container mx-auto px-4">
291
  <div class="flex flex-col md:flex-row items-center">
292
  <div class="md:w-1/2 mb-10 md:mb-0 md:pr-10">
293
- <img src="https://static.photos/workspace/800x600/201" alt="Our lab" class="rounded-xl shadow-lg w-full">
294
  </div>
295
  <div class="md:w-1/2">
296
  <h2 class="text-3xl font-bold mb-6">Our Pharmaceutical Expertise</h2>
@@ -342,7 +366,7 @@
342
  <!-- Testimonial 1 -->
343
  <div class="bg-white p-6 rounded-xl shadow-sm testimonial-card">
344
  <div class="flex items-center mb-4">
345
- <img src="https://static.photos/people/48x48/301" alt="Sarah J." class="w-12 h-12 rounded-full mr-4">
346
  <div>
347
  <h4 class="font-bold">Sarah J.</h4>
348
  <div class="flex text-yellow-400">
@@ -360,7 +384,7 @@
360
  <!-- Testimonial 2 -->
361
  <div class="bg-white p-6 rounded-xl shadow-sm testimonial-card">
362
  <div class="flex items-center mb-4">
363
- <img src="https://static.photos/people/48x48/302" alt="Michael T." class="w-12 h-12 rounded-full mr-4">
364
  <div>
365
  <h4 class="font-bold">Michael T.</h4>
366
  <div class="flex text-yellow-400">
@@ -378,7 +402,7 @@
378
  <!-- Testimonial 3 -->
379
  <div class="bg-white p-6 rounded-xl shadow-sm testimonial-card">
380
  <div class="flex items-center mb-4">
381
- <img src="https://static.photos/people/48x48/303" alt="Priya K." class="w-12 h-12 rounded-full mr-4">
382
  <div>
383
  <h4 class="font-bold">Priya K.</h4>
384
  <div class="flex text-yellow-400">
@@ -392,7 +416,7 @@
392
  </div>
393
  <p class="text-gray-600">"Stress Relief has helped me manage my anxiety naturally. I feel calmer and more centered without any drowsiness. It's become an essential part of my daily routine."</p>
394
  </div>
395
- </div>
396
  </div>
397
  </section>
398
 
@@ -660,15 +684,68 @@
660
  <!-- Image Optimizer Component -->
661
  <script src="components/image-optimizer.js"></script>
662
  <script src="components/image-gallery.js"></script>
663
-
664
  <script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
665
  // Mobile menu toggle
666
  const mobileMenuButton = document.getElementById('mobileMenuButton');
667
  const mobileMenu = document.getElementById('mobileMenu');
668
 
669
- mobileMenuButton.addEventListener('click', () => {
670
- mobileMenu.classList.toggle('open');
671
- });
 
 
672
 
673
  // Smooth scrolling for navigation links
674
  document.querySelectorAll('a[href^="#"]').forEach(anchor => {
@@ -685,7 +762,7 @@
685
  });
686
 
687
  // Close mobile menu if open
688
- mobileMenu.classList.remove('open');
689
  }
690
  });
691
  });
@@ -707,72 +784,84 @@
707
  const addToCartButtons = document.querySelectorAll('.add-to-cart');
708
 
709
  // Toggle cart modal
710
- cartButton.addEventListener('click', () => {
711
- cartModal.classList.remove('hidden');
712
- renderCart();
713
- });
 
 
714
 
715
- closeCart.addEventListener('click', () => {
716
- cartModal.classList.add('hidden');
717
- });
 
 
718
 
719
- continueShopping.addEventListener('click', () => {
720
- cartModal.classList.add('hidden');
721
- });
 
 
722
 
723
  // Add to cart functionality
724
- addToCartButtons.forEach(button => {
725
- button.addEventListener('click', () => {
726
- const id = button.getAttribute('data-id');
727
- const name = button.getAttribute('data-name');
728
- const price = parseFloat(button.getAttribute('data-price'));
729
-
730
- // Check if item already exists in cart
731
- const existingItem = cart.find(item => item.id === id);
732
-
733
- if (existingItem) {
734
- existingItem.quantity += 1;
735
- } else {
736
- cart.push({
737
- id,
738
- name,
739
- price,
740
- quantity: 1
741
- });
742
- }
743
-
744
- updateCartCount();
745
- renderCart();
746
-
747
- // Show cart modal
748
- cartModal.classList.remove('hidden');
749
-
750
- // Add animation to button
751
- button.innerHTML = '<i class="fas fa-check mr-2"></i> Added';
752
- button.classList.add('bg-green-600', 'hover:bg-green-700');
753
-
754
- setTimeout(() => {
755
- button.innerHTML = 'Add to Cart';
756
- button.classList.remove('bg-green-600', 'hover:bg-green-700');
757
- button.classList.add('bg-blue-600', 'hover:bg-blue-700');
758
- }, 2000);
 
 
759
  });
760
- });
761
 
762
  // Update cart count in header
763
  function updateCartCount() {
764
  const totalItems = cart.reduce((total, item) => total + item.quantity, 0);
765
 
766
- if (totalItems > 0) {
767
- cartCount.textContent = totalItems;
768
- cartCount.classList.remove('hidden');
769
- } else {
770
- cartCount.classList.add('hidden');
 
 
771
  }
772
  }
773
 
774
  // Render cart items
775
  function renderCart() {
 
 
776
  if (cart.length === 0) {
777
  cartItems.innerHTML = '<p class="text-gray-500 text-center py-8">Your cart is empty</p>';
778
  cartSubtotal.textContent = '$0.00';
@@ -856,28 +945,30 @@
856
  }
857
 
858
  // Checkout button
859
- checkoutButton.addEventListener('click', () => {
860
- // Show loading state
861
- checkoutButton.innerHTML = '<div class="loader-small"></div> Processing...';
862
- checkoutButton.disabled = true;
863
-
864
- // Simulate API call
865
- setTimeout(() => {
866
- alert('Thank you for your purchase! This is a demo site, no actual order will be placed.');
867
- cart = [];
868
- updateCartCount();
869
- renderCart();
870
- cartModal.classList.add('hidden');
871
 
872
- // Reset button
873
- checkoutButton.innerHTML = 'Checkout';
874
- checkoutButton.disabled = false;
875
- }, 1500);
876
- });
 
 
 
 
 
 
 
 
 
877
 
878
  // Close modal when clicking outside
879
  window.addEventListener('click', (e) => {
880
- if (e.target === cartModal) {
881
  cartModal.classList.add('hidden');
882
  }
883
  });
@@ -885,42 +976,51 @@
885
  // Back to top button
886
  const backToTopButton = document.getElementById('backToTop');
887
 
888
- window.addEventListener('scroll', () => {
889
- if (window.pageYOffset > 300) {
890
- backToTopButton.classList.remove('opacity-0', 'invisible');
891
- backToTopButton.classList.add('opacity-100', 'visible');
892
- } else {
893
- backToTopButton.classList.remove('opacity-100', 'visible');
894
- backToTopButton.classList.add('opacity-0', 'invisible');
895
- }
896
- });
897
-
898
- backToTopButton.addEventListener('click', () => {
899
- window.scrollTo({
900
- top: 0,
901
- behavior: 'smooth'
902
  });
903
- });
 
 
 
 
 
 
 
904
 
905
  // Image optimization initialization
906
  document.addEventListener('DOMContentLoaded', function() {
907
- // Replace all product images with optimized versions
908
- const productImages = document.querySelectorAll('.product-card img');
909
- productImages.forEach(img => {
910
- const parent = img.parentElement;
911
- const alt = img.alt;
912
- const src = img.src;
913
-
914
- // Create optimized image component
915
- const optimizedImg = document.createElement('optimized-image');
916
- optimizedImg.setAttribute('src', src);
917
- optimizedImg.setAttribute('alt', alt);
918
- optimizedImg.setAttribute('height', '200px');
919
- optimizedImg.setAttribute('lazy', '');
920
-
921
- // Replace the original image
922
- img.replaceWith(optimizedImg);
923
- });
 
 
 
 
 
 
 
924
  });
925
  </script>
926
  <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=steake/pharma-see" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
 
108
  </style>
109
  </head>
110
  <body class="bg-gray-50">
111
+ <!-- Image Prompts Configuration -->
112
+ <script type="application/json" id="imagePromptsConfig">
113
+ {
114
+ "hero": "https://static.photos/medical/800x600/1",
115
+ "productImages": [
116
+ "https://static.photos/medical/400x300/101",
117
+ "https://static.photos/medical/400x300/102",
118
+ "https://static.photos/medical/400x300/103",
119
+ "https://static.photos/medical/400x300/104"
120
+ ],
121
+ "about": "https://static.photos/workspace/800x600/201",
122
+ "testimonials": [
123
+ "https://static.photos/people/48x48/301",
124
+ "https://static.photos/people/48x48/302",
125
+ "https://static.photos/people/48x48/303"
126
+ ],
127
+ "categories": {
128
+ "medical": "medical",
129
+ "workspace": "workspace",
130
+ "people": "people"
131
+ },
132
+ "placeholder": "https://static.photos/abstract/100x100"
133
+ }
134
+ </script>
135
+
136
  <!-- Header/Navigation -->
137
  <header class="bg-white shadow-sm sticky top-0 z-50">
138
  <div class="container mx-auto px-4 py-3 flex justify-between items-center">
 
142
  <span class="text-xl font-bold text-gray-800">PharmaCare</span>
143
  </a>
144
  </div>
145
+ <div class="hidden md:flex space-x-8">
 
146
  <a href="#home" class="nav-link text-gray-700 hover:text-blue-600 font-medium">Home</a>
147
  <a href="#products" class="nav-link text-gray-700 hover:text-blue-600 font-medium">Products</a>
148
  <a href="#about" class="nav-link text-gray-700 hover:text-blue-600 font-medium">About</a>
 
186
  <a href="#about" class="border-2 border-white text-white hover:bg-white hover:text-[#5d9245] font-bold py-3 px-6 rounded-full text-center transition duration-300">Learn More</a>
187
  </div>
188
  </div>
189
+ <div class="md:w-1/2 flex justify-center">
190
+ <img id="heroImage" src="" alt="Pharmaceutical products" class="rounded-xl shadow-2xl max-w-md w-full floating">
191
  </div>
192
  </div>
193
  </section>
 
233
  <!-- Product 1 -->
234
  <div class="bg-white rounded-xl shadow-md overflow-hidden product-card transition duration-300">
235
  <div class="relative">
236
+ <img id="productImage1" src="" alt="Xanax" class="w-full h-48 object-contain bg-gray-100 p-4">
237
  <span class="absolute top-2 right-2 bg-blue-500 text-white text-xs font-bold px-2 py-1 rounded-full">BESTSELLER</span>
238
  </div>
239
  <div class="p-6">
 
251
  <!-- Product 2 -->
252
  <div class="bg-white rounded-xl shadow-md overflow-hidden product-card transition duration-300">
253
  <div class="relative">
254
+ <img id="productImage2" src="" alt="Valium" class="w-full h-48 object-contain bg-gray-100 p-4">
255
  </div>
256
  <div class="p-6">
257
  <h3 class="text-xl font-bold mb-2">Valium (Diazepam) 10mg</h3>
 
268
  <!-- Product 3 -->
269
  <div class="bg-white rounded-xl shadow-md overflow-hidden product-card transition duration-300">
270
  <div class="relative">
271
+ <img id="productImage3" src="" alt="Viagra" class="w-full h-48 object-contain bg-gray-100 p-4">
272
  <span class="absolute top-2 right-2 bg-blue-500 text-white text-xs font-bold px-2 py-1 rounded-full">NEW</span>
273
  </div>
274
  <div class="p-6">
 
286
  <!-- Product 4 -->
287
  <div class="bg-white rounded-xl shadow-md overflow-hidden product-card transition duration-300">
288
  <div class="relative">
289
+ <img id="productImage4" src="" alt="Codeine" class="w-full h-48 object-contain bg-gray-100 p-4">
290
  </div>
291
  <div class="p-6">
292
  <h3 class="text-xl font-bold mb-2">Codeine 30mg</h3>
 
299
  </div>
300
  </div>
301
  </div>
302
+ </div>
303
 
304
  <div class="text-center mt-12">
305
  <a href="#" class="inline-block border-2 border-[#5d9245] text-[#5d9245] hover:bg-[#5d9245] hover:text-white font-bold py-3 px-8 rounded-full transition duration-300">
 
314
  <div class="container mx-auto px-4">
315
  <div class="flex flex-col md:flex-row items-center">
316
  <div class="md:w-1/2 mb-10 md:mb-0 md:pr-10">
317
+ <img id="aboutImage" src="" alt="Our lab" class="rounded-xl shadow-lg w-full">
318
  </div>
319
  <div class="md:w-1/2">
320
  <h2 class="text-3xl font-bold mb-6">Our Pharmaceutical Expertise</h2>
 
366
  <!-- Testimonial 1 -->
367
  <div class="bg-white p-6 rounded-xl shadow-sm testimonial-card">
368
  <div class="flex items-center mb-4">
369
+ <img id="testimonialImage1" src="" alt="Sarah J." class="w-12 h-12 rounded-full mr-4">
370
  <div>
371
  <h4 class="font-bold">Sarah J.</h4>
372
  <div class="flex text-yellow-400">
 
384
  <!-- Testimonial 2 -->
385
  <div class="bg-white p-6 rounded-xl shadow-sm testimonial-card">
386
  <div class="flex items-center mb-4">
387
+ <img id="testimonialImage2" src="" alt="Michael T." class="w-12 h-12 rounded-full mr-4">
388
  <div>
389
  <h4 class="font-bold">Michael T.</h4>
390
  <div class="flex text-yellow-400">
 
402
  <!-- Testimonial 3 -->
403
  <div class="bg-white p-6 rounded-xl shadow-sm testimonial-card">
404
  <div class="flex items-center mb-4">
405
+ <img id="testimonialImage3" src="" alt="Priya K." class="w-12 h-12 rounded-full mr-4">
406
  <div>
407
  <h4 class="font-bold">Priya K.</h4>
408
  <div class="flex text-yellow-400">
 
416
  </div>
417
  <p class="text-gray-600">"Stress Relief has helped me manage my anxiety naturally. I feel calmer and more centered without any drowsiness. It's become an essential part of my daily routine."</p>
418
  </div>
419
+ </div>
420
  </div>
421
  </section>
422
 
 
684
  <!-- Image Optimizer Component -->
685
  <script src="components/image-optimizer.js"></script>
686
  <script src="components/image-gallery.js"></script>
 
687
  <script>
688
+ // Image Prompts Configuration Loader
689
+ function loadImagePrompts() {
690
+ try {
691
+ const configElement = document.getElementById('imagePromptsConfig');
692
+ if (!configElement) {
693
+ console.warn('Image prompts config not found');
694
+ return null;
695
+ }
696
+
697
+ const config = JSON.parse(configElement.textContent);
698
+ console.log('Image prompts config loaded:', config);
699
+ return config;
700
+ } catch (error) {
701
+ console.error('Failed to load image prompts:', error);
702
+ return null;
703
+ }
704
+ }
705
+
706
+ // Apply image prompts to all images
707
+ function applyImagePrompts() {
708
+ const config = loadImagePrompts();
709
+ if (!config) return;
710
+
711
+ // Apply hero image
712
+ const heroImg = document.getElementById('heroImage');
713
+ if (heroImg && config.hero) {
714
+ heroImg.src = config.hero;
715
+ }
716
+
717
+ // Apply product images
718
+ for (let i = 1; i <= 4; i++) {
719
+ const img = document.getElementById(`productImage${i}`);
720
+ if (img && config.productImages[i-1]) {
721
+ img.src = config.productImages[i-1];
722
+ }
723
+ }
724
+
725
+ // Apply about image
726
+ const aboutImg = document.getElementById('aboutImage');
727
+ if (aboutImg && config.about) {
728
+ aboutImg.src = config.about;
729
+ }
730
+
731
+ // Apply testimonial images
732
+ for (let i = 1; i <= 3; i++) {
733
+ const img = document.getElementById(`testimonialImage${i}`);
734
+ if (img && config.testimonials[i-1]) {
735
+ img.src = config.testimonials[i-1];
736
+ }
737
+ }
738
+ }
739
+
740
  // Mobile menu toggle
741
  const mobileMenuButton = document.getElementById('mobileMenuButton');
742
  const mobileMenu = document.getElementById('mobileMenu');
743
 
744
+ if (mobileMenuButton && mobileMenu) {
745
+ mobileMenuButton.addEventListener('click', () => {
746
+ mobileMenu.classList.toggle('open');
747
+ });
748
+ }
749
 
750
  // Smooth scrolling for navigation links
751
  document.querySelectorAll('a[href^="#"]').forEach(anchor => {
 
762
  });
763
 
764
  // Close mobile menu if open
765
+ if (mobileMenu) mobileMenu.classList.remove('open');
766
  }
767
  });
768
  });
 
784
  const addToCartButtons = document.querySelectorAll('.add-to-cart');
785
 
786
  // Toggle cart modal
787
+ if (cartButton && cartModal) {
788
+ cartButton.addEventListener('click', () => {
789
+ cartModal.classList.remove('hidden');
790
+ renderCart();
791
+ });
792
+ }
793
 
794
+ if (closeCart) {
795
+ closeCart.addEventListener('click', () => {
796
+ cartModal.classList.add('hidden');
797
+ });
798
+ }
799
 
800
+ if (continueShopping) {
801
+ continueShopping.addEventListener('click', () => {
802
+ cartModal.classList.add('hidden');
803
+ });
804
+ }
805
 
806
  // Add to cart functionality
807
+ if (addToCartButtons.length > 0) {
808
+ addToCartButtons.forEach(button => {
809
+ button.addEventListener('click', () => {
810
+ const id = button.getAttribute('data-id');
811
+ const name = button.getAttribute('data-name');
812
+ const price = parseFloat(button.getAttribute('data-price'));
813
+
814
+ // Check if item already exists in cart
815
+ const existingItem = cart.find(item => item.id === id);
816
+
817
+ if (existingItem) {
818
+ existingItem.quantity += 1;
819
+ } else {
820
+ cart.push({
821
+ id,
822
+ name,
823
+ price,
824
+ quantity: 1
825
+ });
826
+ }
827
+
828
+ updateCartCount();
829
+ renderCart();
830
+
831
+ // Show cart modal
832
+ if (cartModal) cartModal.classList.remove('hidden');
833
+
834
+ // Add animation to button
835
+ button.innerHTML = '<i class="fas fa-check mr-2"></i> Added';
836
+ button.classList.add('bg-green-600', 'hover:bg-green-700');
837
+
838
+ setTimeout(() => {
839
+ button.innerHTML = 'Add to Cart';
840
+ button.classList.remove('bg-green-600', 'hover:bg-green-700');
841
+ button.classList.add('bg-blue-600', 'hover:bg-blue-700');
842
+ }, 2000);
843
+ });
844
  });
845
+ }
846
 
847
  // Update cart count in header
848
  function updateCartCount() {
849
  const totalItems = cart.reduce((total, item) => total + item.quantity, 0);
850
 
851
+ if (cartCount) {
852
+ if (totalItems > 0) {
853
+ cartCount.textContent = totalItems;
854
+ cartCount.classList.remove('hidden');
855
+ } else {
856
+ cartCount.classList.add('hidden');
857
+ }
858
  }
859
  }
860
 
861
  // Render cart items
862
  function renderCart() {
863
+ if (!cartItems || !cartSubtotal || !checkoutButton) return;
864
+
865
  if (cart.length === 0) {
866
  cartItems.innerHTML = '<p class="text-gray-500 text-center py-8">Your cart is empty</p>';
867
  cartSubtotal.textContent = '$0.00';
 
945
  }
946
 
947
  // Checkout button
948
+ if (checkoutButton) {
949
+ checkoutButton.addEventListener('click', () => {
950
+ // Show loading state
951
+ checkoutButton.innerHTML = '<div class="loader-small"></div> Processing...';
952
+ checkoutButton.disabled = true;
 
 
 
 
 
 
 
953
 
954
+ // Simulate API call
955
+ setTimeout(() => {
956
+ alert('Thank you for your purchase! This is a demo site, no actual order will be placed.');
957
+ cart = [];
958
+ updateCartCount();
959
+ renderCart();
960
+ if (cartModal) cartModal.classList.add('hidden');
961
+
962
+ // Reset button
963
+ checkoutButton.innerHTML = 'Checkout';
964
+ checkoutButton.disabled = false;
965
+ }, 1500);
966
+ });
967
+ }
968
 
969
  // Close modal when clicking outside
970
  window.addEventListener('click', (e) => {
971
+ if (cartModal && e.target === cartModal) {
972
  cartModal.classList.add('hidden');
973
  }
974
  });
 
976
  // Back to top button
977
  const backToTopButton = document.getElementById('backToTop');
978
 
979
+ if (backToTopButton) {
980
+ window.addEventListener('scroll', () => {
981
+ if (window.pageYOffset > 300) {
982
+ backToTopButton.classList.remove('opacity-0', 'invisible');
983
+ backToTopButton.classList.add('opacity-100', 'visible');
984
+ } else {
985
+ backToTopButton.classList.remove('opacity-100', 'visible');
986
+ backToTopButton.classList.add('opacity-0', 'invisible');
987
+ }
 
 
 
 
 
988
  });
989
+
990
+ backToTopButton.addEventListener('click', () => {
991
+ window.scrollTo({
992
+ top: 0,
993
+ behavior: 'smooth'
994
+ });
995
+ });
996
+ }
997
 
998
  // Image optimization initialization
999
  document.addEventListener('DOMContentLoaded', function() {
1000
+ // Apply image prompts from config
1001
+ applyImagePrompts();
1002
+
1003
+ // Replace product images with optimized versions after they are loaded
1004
+ setTimeout(() => {
1005
+ const productImages = document.querySelectorAll('.product-card img');
1006
+ productImages.forEach(img => {
1007
+ const parent = img.parentElement;
1008
+ const alt = img.alt;
1009
+ const src = img.src;
1010
+
1011
+ if (src && src !== '' && typeof customElements !== 'undefined' && customElements.get('optimized-image')) {
1012
+ // Create optimized image component
1013
+ const optimizedImg = document.createElement('optimized-image');
1014
+ optimizedImg.setAttribute('src', src);
1015
+ optimizedImg.setAttribute('alt', alt);
1016
+ optimizedImg.setAttribute('height', '200px');
1017
+ optimizedImg.setAttribute('lazy', '');
1018
+
1019
+ // Replace the original image
1020
+ img.replaceWith(optimizedImg);
1021
+ }
1022
+ });
1023
+ }, 100);
1024
  });
1025
  </script>
1026
  <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=steake/pharma-see" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>