@o2vend/theme-cli 1.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +425 -0
  2. package/assets/Logo_o2vend.png +0 -0
  3. package/assets/favicon.png +0 -0
  4. package/assets/logo-white.png +0 -0
  5. package/bin/o2vend +42 -0
  6. package/config/widget-map.json +50 -0
  7. package/lib/commands/check.js +201 -0
  8. package/lib/commands/generate.js +33 -0
  9. package/lib/commands/init.js +214 -0
  10. package/lib/commands/optimize.js +216 -0
  11. package/lib/commands/package.js +208 -0
  12. package/lib/commands/serve.js +105 -0
  13. package/lib/commands/validate.js +191 -0
  14. package/lib/lib/api-client.js +357 -0
  15. package/lib/lib/dev-server.js +2618 -0
  16. package/lib/lib/file-watcher.js +80 -0
  17. package/lib/lib/hot-reload.js +106 -0
  18. package/lib/lib/liquid-engine.js +822 -0
  19. package/lib/lib/liquid-filters.js +671 -0
  20. package/lib/lib/mock-api-server.js +989 -0
  21. package/lib/lib/mock-data.js +1468 -0
  22. package/lib/lib/widget-service.js +321 -0
  23. package/package.json +70 -0
  24. package/test-theme/README.md +27 -0
  25. package/test-theme/assets/async-sections.js +446 -0
  26. package/test-theme/assets/cart-drawer.js +463 -0
  27. package/test-theme/assets/cart-manager.js +223 -0
  28. package/test-theme/assets/checkout-price-handler.js +368 -0
  29. package/test-theme/assets/components.css +4629 -0
  30. package/test-theme/assets/delivery-zone.css +299 -0
  31. package/test-theme/assets/delivery-zone.js +396 -0
  32. package/test-theme/assets/logo.png +0 -0
  33. package/test-theme/assets/sections.css +48 -0
  34. package/test-theme/assets/theme.css +3500 -0
  35. package/test-theme/assets/theme.js +3745 -0
  36. package/test-theme/config/settings_data.json +292 -0
  37. package/test-theme/config/settings_schema.json +1050 -0
  38. package/test-theme/layout/theme.liquid +195 -0
  39. package/test-theme/locales/en.default.json +260 -0
  40. package/test-theme/sections/content-fallback.liquid +53 -0
  41. package/test-theme/sections/content.liquid +57 -0
  42. package/test-theme/sections/footer-fallback.liquid +328 -0
  43. package/test-theme/sections/footer.liquid +278 -0
  44. package/test-theme/sections/header-fallback.liquid +1805 -0
  45. package/test-theme/sections/header.liquid +1145 -0
  46. package/test-theme/sections/hero-fallback.liquid +212 -0
  47. package/test-theme/sections/hero.liquid +136 -0
  48. package/test-theme/snippets/account-sidebar.liquid +200 -0
  49. package/test-theme/snippets/add-to-cart-modal.liquid +484 -0
  50. package/test-theme/snippets/breadcrumbs.liquid +134 -0
  51. package/test-theme/snippets/cart-drawer.liquid +467 -0
  52. package/test-theme/snippets/delivery-zone-city-selector.liquid +79 -0
  53. package/test-theme/snippets/delivery-zone-modal.liquid +337 -0
  54. package/test-theme/snippets/delivery-zone-search.liquid +78 -0
  55. package/test-theme/snippets/icon.liquid +105 -0
  56. package/test-theme/snippets/login-modal.liquid +346 -0
  57. package/test-theme/snippets/mega-menu.liquid +812 -0
  58. package/test-theme/snippets/news-thumbnail.liquid +187 -0
  59. package/test-theme/snippets/pagination.liquid +120 -0
  60. package/test-theme/snippets/price.liquid +92 -0
  61. package/test-theme/snippets/product-card-related.liquid +78 -0
  62. package/test-theme/snippets/product-card-simple.liquid +41 -0
  63. package/test-theme/snippets/product-card.liquid +697 -0
  64. package/test-theme/snippets/rating.liquid +85 -0
  65. package/test-theme/snippets/skeleton-collection-grid.liquid +114 -0
  66. package/test-theme/snippets/skeleton-product-card.liquid +124 -0
  67. package/test-theme/snippets/skeleton-product-grid.liquid +34 -0
  68. package/test-theme/snippets/social-sharing.liquid +185 -0
  69. package/test-theme/templates/account/dashboard.liquid +401 -0
  70. package/test-theme/templates/account/loyalty-redemption.liquid +405 -0
  71. package/test-theme/templates/account/loyalty.liquid +588 -0
  72. package/test-theme/templates/account/order-detail.liquid +230 -0
  73. package/test-theme/templates/account/orders.liquid +349 -0
  74. package/test-theme/templates/account/profile.liquid +758 -0
  75. package/test-theme/templates/account/register.liquid +232 -0
  76. package/test-theme/templates/account/return-orders.liquid +348 -0
  77. package/test-theme/templates/account/store-credit.liquid +464 -0
  78. package/test-theme/templates/account/subscriptions.liquid +601 -0
  79. package/test-theme/templates/account/wishlist.liquid +419 -0
  80. package/test-theme/templates/address-book.liquid +1092 -0
  81. package/test-theme/templates/categories.liquid +452 -0
  82. package/test-theme/templates/checkout.liquid +4511 -0
  83. package/test-theme/templates/error.liquid +384 -0
  84. package/test-theme/templates/index.liquid +11 -0
  85. package/test-theme/templates/login.liquid +185 -0
  86. package/test-theme/templates/order-confirmation.liquid +720 -0
  87. package/test-theme/templates/page.liquid +297 -0
  88. package/test-theme/templates/product-detail.liquid +4363 -0
  89. package/test-theme/templates/products.liquid +518 -0
  90. package/test-theme/templates/search.liquid +922 -0
  91. package/test-theme/theme.json.example +19 -0
  92. package/test-theme/widgets/brand-carousel.liquid +676 -0
  93. package/test-theme/widgets/brand.liquid +245 -0
  94. package/test-theme/widgets/carousel.liquid +843 -0
  95. package/test-theme/widgets/category-list-carousel.liquid +656 -0
  96. package/test-theme/widgets/category-list.liquid +340 -0
  97. package/test-theme/widgets/category.liquid +475 -0
  98. package/test-theme/widgets/discount-time.liquid +176 -0
  99. package/test-theme/widgets/footer-menu.liquid +695 -0
  100. package/test-theme/widgets/footer.liquid +179 -0
  101. package/test-theme/widgets/gallery.liquid +271 -0
  102. package/test-theme/widgets/header-menu.liquid +932 -0
  103. package/test-theme/widgets/header.liquid +159 -0
  104. package/test-theme/widgets/html.liquid +214 -0
  105. package/test-theme/widgets/news.liquid +217 -0
  106. package/test-theme/widgets/product-canvas.liquid +235 -0
  107. package/test-theme/widgets/product-carousel.liquid +502 -0
  108. package/test-theme/widgets/product.liquid +45 -0
  109. package/test-theme/widgets/recently-viewed.liquid +26 -0
  110. package/test-theme/widgets/shared/product-grid.liquid +339 -0
  111. package/test-theme/widgets/simple-product.liquid +42 -0
  112. package/test-theme/widgets/single-product.liquid +610 -0
  113. package/test-theme/widgets/spacebar-carousel.liquid +663 -0
  114. package/test-theme/widgets/spacebar.liquid +279 -0
  115. package/test-theme/widgets/splash.liquid +378 -0
  116. package/test-theme/widgets/testimonial-carousel.liquid +709 -0
@@ -0,0 +1,419 @@
1
+ {% layout 'layout/theme' %}
2
+
3
+ <section class="account-page">
4
+ <div class="container">
5
+ <div class="account-header">
6
+ <h1 class="account-title display-2">My Wishlist</h1>
7
+ <p class="account-subtitle">Items you've saved for later</p>
8
+ </div>
9
+
10
+ <div class="account-layout">
11
+ <!-- Account Sidebar -->
12
+ <aside class="account-sidebar">
13
+ {% render 'snippets/account-sidebar' %}
14
+ </aside>
15
+
16
+ <!-- Wishlist Content -->
17
+ <div class="account-content">
18
+ {% hook 'account_wishlist_before' %}
19
+ <div class="account-section-header">
20
+ <h2 class="account-section-title">My Wishlist</h2>
21
+ {% if wishlist and wishlist.items and wishlist.items.size > 0 %}
22
+ <span class="items-count">{{ wishlist.items.size }} item{% if wishlist.items.size != 1 %}s{% endif %}</span>
23
+ {% endif %}
24
+ </div>
25
+
26
+ <div class="wishlist-products">
27
+ {% if wishlist and wishlist.items and wishlist.items.size > 0 %}
28
+ <div class="products-grid">
29
+ {% for item in wishlist.items %}
30
+ <article class="product-card">
31
+ <div class="product-card-image">
32
+ {% if item.product.image %}
33
+ <img src="{{ item.product.image }}" alt="{{ item.product.name | default: item.product.title }}" loading="lazy">
34
+ {% else %}
35
+ <div class="product-placeholder">
36
+ <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
37
+ <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
38
+ <circle cx="8.5" cy="8.5" r="1.5"></circle>
39
+ <polyline points="21 15 16 10 5 21"></polyline>
40
+ </svg>
41
+ </div>
42
+ {% endif %}
43
+ <button class="remove-wishlist-btn" data-item-id="{{ item.id }}" title="Remove from wishlist">
44
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
45
+ <line x1="18" y1="6" x2="6" y2="18"></line>
46
+ <line x1="6" y1="6" x2="18" y2="18"></line>
47
+ </svg>
48
+ </button>
49
+ </div>
50
+
51
+ <div class="product-card-content">
52
+ <a href="{{ item.product.url | default: '#' }}" class="product-card-link">
53
+ <h3 class="product-card-title">{{ item.product.name | default: item.product.title }}</h3>
54
+ </a>
55
+
56
+ {% if item.product.price %}
57
+ <div class="product-card-price">
58
+ {% if item.product.compareAtPrice and item.product.compareAtPrice > item.product.price %}
59
+ <span class="price-compare">{{ item.product.compareAtPrice | money_with_settings: shop.settings }}</span>
60
+ <span class="price-current sale">{{ item.product.price | money_with_settings: shop.settings }}</span>
61
+ {% else %}
62
+ <span class="price-current">{{ item.product.price | money_with_settings: shop.settings }}</span>
63
+ {% endif %}
64
+ </div>
65
+ {% endif %}
66
+
67
+ {% if item.product.available %}
68
+ <button class="btn btn-primary btn-block add-to-cart" data-product-id="{{ item.product.id }}">
69
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
70
+ <circle cx="9" cy="21" r="1"></circle>
71
+ <circle cx="20" cy="21" r="1"></circle>
72
+ <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path>
73
+ </svg>
74
+ Add to Cart
75
+ </button>
76
+ {% else %}
77
+ <button class="btn btn-outline btn-block" disabled>Out of Stock</button>
78
+ {% endif %}
79
+ </div>
80
+ </article>
81
+ {% endfor %}
82
+ </div>
83
+ {% else %}
84
+ <div class="empty-state">
85
+ <div class="empty-icon">
86
+ <svg width="80" height="80" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
87
+ <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
88
+ </svg>
89
+ </div>
90
+ <h3>Your Wishlist is Empty</h3>
91
+ <p>Start adding products you love to keep track of them!</p>
92
+ <a href="/products" class="btn btn-primary">Browse Products</a>
93
+ </div>
94
+ {% endif %}
95
+ </div>
96
+ {% hook 'account_wishlist_after' %}
97
+ </div>
98
+ </div>
99
+ </div>
100
+ </section>
101
+
102
+ <style>
103
+ /* Account wishlist page uses theme.css variables - no local :root needed */
104
+
105
+ .account-page {
106
+ padding: var(--spacing-section) var(--spacing-small);
107
+ background: var(--color-background);
108
+ min-height: 100vh;
109
+ }
110
+
111
+ .container {
112
+ max-width: var(--container-width);
113
+ margin: 0 auto;
114
+ padding: 0 var(--spacing-small);
115
+ }
116
+
117
+ .account-header {
118
+ text-align: center;
119
+ margin-bottom: var(--spacing-xl);
120
+ }
121
+
122
+ .account-title {
123
+ font-size: 2.5rem;
124
+ font-weight: 700;
125
+ color: var(--color-text);
126
+ margin: 0 0 0.5rem 0;
127
+ letter-spacing: -0.025em;
128
+ }
129
+
130
+ .account-subtitle {
131
+ font-size: 1.125rem;
132
+ color: var(--color-text-light);
133
+ margin: 0;
134
+ }
135
+
136
+ .account-layout {
137
+ display: grid;
138
+ grid-template-columns: 280px 1fr;
139
+ gap: var(--spacing-lg);
140
+ align-items: start;
141
+ }
142
+
143
+ .account-sidebar {
144
+ position: sticky;
145
+ top: var(--spacing-lg);
146
+ background: var(--color-background);
147
+ border-radius: var(--radius-lg);
148
+ padding: var(--spacing-md);
149
+ box-shadow: var(--shadow-md);
150
+ border: 1px solid var(--color-border);
151
+ }
152
+
153
+ .account-content {
154
+ background: var(--color-background);
155
+ border-radius: var(--radius-lg);
156
+ padding: var(--spacing-lg);
157
+ box-shadow: var(--shadow-md);
158
+ border: 1px solid var(--color-border);
159
+ }
160
+
161
+ .account-section-header {
162
+ display: flex;
163
+ justify-content: space-between;
164
+ align-items: center;
165
+ margin-bottom: var(--spacing-lg);
166
+ padding-bottom: var(--spacing-md);
167
+ border-bottom: 1px solid var(--color-border);
168
+ }
169
+
170
+ .account-section-title {
171
+ font-size: 1.75rem;
172
+ font-weight: 600;
173
+ color: var(--color-text);
174
+ margin: 0;
175
+ }
176
+
177
+ .items-count {
178
+ background: var(--color-primary-light);
179
+ color: var(--color-primary);
180
+ padding: 0.375rem 0.75rem;
181
+ border-radius: 9999px;
182
+ font-size: 1.2rem;
183
+ font-weight: 600;
184
+ }
185
+
186
+ .products-grid {
187
+ display: grid;
188
+ grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
189
+ gap: var(--spacing-md);
190
+ }
191
+
192
+ .product-card {
193
+ background: var(--color-background);
194
+ border: 2px solid var(--color-border);
195
+ border-radius: var(--radius-lg);
196
+ overflow: hidden;
197
+ transition: all 0.3s ease;
198
+ display: flex;
199
+ flex-direction: column;
200
+ }
201
+
202
+ .product-card:hover {
203
+ border-color: var(--color-primary);
204
+ box-shadow: var(--shadow-lg);
205
+ transform: translateY(-4px);
206
+ }
207
+
208
+ .product-card-image {
209
+ position: relative;
210
+ width: 100%;
211
+ padding-top: 100%;
212
+ overflow: hidden;
213
+ background: var(--color-surface);
214
+ }
215
+
216
+ .product-card-image img {
217
+ position: absolute;
218
+ top: 0;
219
+ left: 0;
220
+ width: 100%;
221
+ height: 100%;
222
+ object-fit: cover;
223
+ transition: transform 0.3s ease;
224
+ }
225
+
226
+ .product-card:hover .product-card-image img {
227
+ transform: scale(1.05);
228
+ }
229
+
230
+ .product-placeholder {
231
+ position: absolute;
232
+ top: 0;
233
+ left: 0;
234
+ width: 100%;
235
+ height: 100%;
236
+ display: flex;
237
+ align-items: center;
238
+ justify-content: center;
239
+ color: var(--color-text-lighter);
240
+ }
241
+
242
+ .remove-wishlist-btn {
243
+ position: absolute;
244
+ top: var(--spacing-sm);
245
+ right: var(--spacing-sm);
246
+ width: 36px;
247
+ height: 36px;
248
+ display: flex;
249
+ align-items: center;
250
+ justify-content: center;
251
+ background: white;
252
+ border: none;
253
+ border-radius: 50%;
254
+ cursor: pointer;
255
+ box-shadow: var(--shadow-md);
256
+ transition: all 0.3s ease;
257
+ color: var(--color-text-light);
258
+ }
259
+
260
+ .remove-wishlist-btn:hover {
261
+ background: var(--color-danger);
262
+ color: white;
263
+ transform: scale(1.1);
264
+ }
265
+
266
+ .product-card-content {
267
+ padding: var(--spacing-md);
268
+ display: flex;
269
+ flex-direction: column;
270
+ gap: var(--spacing-sm);
271
+ flex: 1;
272
+ }
273
+
274
+ .product-card-link {
275
+ text-decoration: none;
276
+ }
277
+
278
+ .product-card-title {
279
+ font-size: 1rem;
280
+ font-weight: 600;
281
+ color: var(--color-text);
282
+ margin: 0;
283
+ line-height: 1.4;
284
+ transition: color 0.3s ease;
285
+ display: -webkit-box;
286
+ -webkit-line-clamp: 2;
287
+ -webkit-box-orient: vertical;
288
+ overflow: hidden;
289
+ }
290
+
291
+ .product-card-link:hover .product-card-title {
292
+ color: var(--color-primary);
293
+ }
294
+
295
+ .product-card-price {
296
+ display: flex;
297
+ align-items: center;
298
+ gap: var(--spacing-xs);
299
+ margin-top: auto;
300
+ }
301
+
302
+ .price-compare {
303
+ font-size: 0.875rem;
304
+ color: var(--color-text-lighter);
305
+ text-decoration: line-through;
306
+ }
307
+
308
+ .price-current {
309
+ font-size: 1.125rem;
310
+ font-weight: 700;
311
+ color: var(--color-text);
312
+ }
313
+
314
+ .price-current.sale {
315
+ color: var(--color-danger);
316
+ }
317
+
318
+ .btn {
319
+ display: inline-flex;
320
+ align-items: center;
321
+ justify-content: center;
322
+ gap: 0.5rem;
323
+ padding: 0.625rem 1.5rem;
324
+ font-size: 1.2rem;
325
+ font-weight: 500;
326
+ text-decoration: none;
327
+ border-radius: var(--radius-md);
328
+ border: none;
329
+ cursor: pointer;
330
+ transition: all 0.3s ease;
331
+ white-space: nowrap;
332
+ }
333
+
334
+ .btn-primary {
335
+ background: var(--color-primary);
336
+ color: white;
337
+ border: 2px solid var(--color-primary);
338
+ }
339
+
340
+ .btn-primary:hover:not(:disabled) {
341
+ background: var(--color-primary-hover);
342
+ transform: translateY(-1px);
343
+ box-shadow: var(--shadow-md);
344
+ }
345
+
346
+ .btn-outline {
347
+ background: transparent;
348
+ color: var(--color-text-light);
349
+ border: 2px solid var(--color-border);
350
+ }
351
+
352
+ .btn-block {
353
+ width: 100%;
354
+ }
355
+
356
+ .btn:disabled {
357
+ opacity: 0.5;
358
+ cursor: not-allowed;
359
+ }
360
+
361
+ .empty-state {
362
+ text-align: center;
363
+ padding: var(--spacing-xl);
364
+ background: var(--color-background);
365
+ border-radius: var(--radius-lg);
366
+ border: 2px dashed var(--color-border);
367
+ }
368
+
369
+ .empty-icon {
370
+ margin: 0 auto var(--spacing-md);
371
+ width: 120px;
372
+ height: 120px;
373
+ display: flex;
374
+ align-items: center;
375
+ justify-content: center;
376
+ background: var(--color-primary-light);
377
+ color: var(--color-primary);
378
+ border-radius: 50%;
379
+ }
380
+
381
+ .empty-state h3 {
382
+ font-size: 1.5rem;
383
+ font-weight: 600;
384
+ color: var(--color-text);
385
+ margin: 0 0 var(--spacing-xs) 0;
386
+ }
387
+
388
+ .empty-state p {
389
+ font-size: 1rem;
390
+ color: var(--color-text-light);
391
+ margin: 0 0 var(--spacing-md) 0;
392
+ }
393
+
394
+ @media (max-width: 768px) {
395
+ .account-layout {
396
+ grid-template-columns: 1fr;
397
+ }
398
+
399
+ .account-content {
400
+ order: 1;
401
+ }
402
+
403
+ .products-grid {
404
+ grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
405
+ }
406
+
407
+ .account-section-header {
408
+ flex-direction: column;
409
+ align-items: flex-start;
410
+ gap: var(--spacing-xs);
411
+ }
412
+ }
413
+
414
+ @media (max-width: 480px) {
415
+ .products-grid {
416
+ grid-template-columns: 1fr;
417
+ }
418
+ }
419
+ </style>