almahmud commited on
Commit
2d450d2
·
verified ·
1 Parent(s): e851fbe

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +6 -4
  2. index.html +872 -19
  3. prompts.txt +1 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Wc Product Cvs Generator
3
- emoji: 📉
4
  colorFrom: green
5
- colorTo: green
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: wc-product-cvs-generator
3
+ emoji: 🐳
4
  colorFrom: green
5
+ colorTo: yellow
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,872 @@
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>WooCommerce Product Import CSV Generator</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/@preline/[email protected]/dist/preline.min.js"></script>
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.0/papaparse.min.js"></script>
10
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
11
+ <style>
12
+ .variation-item {
13
+ transition: all 0.3s ease;
14
+ }
15
+ .variation-item:hover {
16
+ background-color: #f3f4f6;
17
+ }
18
+ .progress-bar {
19
+ height: 6px;
20
+ background-color: #e5e7eb;
21
+ border-radius: 3px;
22
+ overflow: hidden;
23
+ }
24
+ .progress-bar-fill {
25
+ height: 100%;
26
+ background-color: #10b981;
27
+ transition: width 0.3s ease;
28
+ }
29
+ .toast {
30
+ position: fixed;
31
+ top: 20px;
32
+ right: 20px;
33
+ padding: 12px 20px;
34
+ background-color: #10b981;
35
+ color: white;
36
+ border-radius: 6px;
37
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
38
+ transform: translateX(200%);
39
+ transition: transform 0.3s ease;
40
+ z-index: 1000;
41
+ }
42
+ .toast.show {
43
+ transform: translateX(0);
44
+ }
45
+ .toast.error {
46
+ background-color: #ef4444;
47
+ }
48
+ .back-to-top {
49
+ position: fixed;
50
+ bottom: 30px;
51
+ right: 30px;
52
+ width: 50px;
53
+ height: 50px;
54
+ border-radius: 50%;
55
+ background-color: #3b82f6;
56
+ color: white;
57
+ display: flex;
58
+ align-items: center;
59
+ justify-content: center;
60
+ cursor: pointer;
61
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
62
+ opacity: 0;
63
+ transition: opacity 0.3s ease;
64
+ z-index: 999;
65
+ }
66
+ .back-to-top.visible {
67
+ opacity: 1;
68
+ }
69
+ .back-to-top:hover {
70
+ background-color: #2563eb;
71
+ }
72
+ </style>
73
+ </head>
74
+ <body class="bg-gray-100">
75
+ <div class="container mx-auto px-4 py-8">
76
+ <div class="flex items-center justify-between mb-6">
77
+ <div>
78
+ <h1 class="text-3xl font-bold text-gray-800">WooCommerce Product Import CSV Generator</h1>
79
+ <p class="text-gray-600 mt-1">Create CSV files for bulk importing products to WooCommerce</p>
80
+ </div>
81
+ <div class="flex items-center space-x-2">
82
+ <span class="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm font-medium">
83
+ <i class="fas fa-box-open mr-1"></i>
84
+ <span id="productCount">0</span> products
85
+ </span>
86
+ </div>
87
+ </div>
88
+
89
+ <div class="bg-white rounded-lg shadow-md p-6 mb-6 border border-gray-200">
90
+ <div class="flex justify-between items-center mb-4">
91
+ <h2 class="text-xl font-semibold text-gray-700">Product List</h2>
92
+ <button id="addProductBtn" class="px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 transition-colors">
93
+ <i class="fas fa-plus mr-2"></i>Add Product
94
+ </button>
95
+ </div>
96
+
97
+ <div id="productList" class="space-y-4">
98
+ <div class="text-center py-12 text-gray-500">
99
+ <i class="fas fa-box-open text-4xl mb-2"></i>
100
+ <p>No products added yet</p>
101
+ <button id="addFirstProductBtn" class="mt-4 px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 transition-colors">
102
+ <i class="fas fa-plus mr-2"></i>Add Your First Product
103
+ </button>
104
+ </div>
105
+ </div>
106
+ </div>
107
+
108
+ <div class="flex justify-end space-x-3 pt-4">
109
+ <button id="resetBtn" class="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 transition-colors">
110
+ <i class="fas fa-trash-alt mr-2"></i>Reset All
111
+ </button>
112
+ <button id="generateBtn" class="px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-green-600 hover:bg-green-700 transition-colors">
113
+ <i class="fas fa-file-csv mr-2"></i>Generate CSV
114
+ </button>
115
+ </div>
116
+ </div>
117
+
118
+ <!-- Back to top button -->
119
+ <div id="backToTop" class="back-to-top">
120
+ <i class="fas fa-arrow-up"></i>
121
+ </div>
122
+
123
+ <!-- Product Modal -->
124
+ <div id="productModal" class="fixed z-10 inset-0 overflow-y-auto hidden">
125
+ <div class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
126
+ <div class="fixed inset-0 transition-opacity" aria-hidden="true">
127
+ <div class="absolute inset-0 bg-gray-500 opacity-75"></div>
128
+ </div>
129
+ <div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-2xl sm:w-full">
130
+ <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
131
+ <h3 class="text-lg font-medium text-gray-900 mb-4" id="modalTitle">Add New Product</h3>
132
+ <div class="mt-2">
133
+ <form id="productForm" class="space-y-4">
134
+ <input type="hidden" id="productId">
135
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
136
+ <div>
137
+ <label for="productType" class="block text-sm font-medium text-gray-700">Product Type</label>
138
+ <select id="productType" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
139
+ <option value="simple">Simple</option>
140
+ <option value="variable">Variable</option>
141
+ </select>
142
+ </div>
143
+ <div>
144
+ <label for="sku" class="block text-sm font-medium text-gray-700">SKU</label>
145
+ <input type="text" id="sku" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
146
+ </div>
147
+ </div>
148
+
149
+ <div>
150
+ <label for="productName" class="block text-sm font-medium text-gray-700">Product Name*</label>
151
+ <input type="text" id="productName" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
152
+ </div>
153
+
154
+ <div>
155
+ <label for="shortDescription" class="block text-sm font-medium text-gray-700">Short Description</label>
156
+ <textarea id="shortDescription" rows="2" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"></textarea>
157
+ </div>
158
+
159
+ <div>
160
+ <label for="description" class="block text-sm font-medium text-gray-700">Description</label>
161
+ <textarea id="description" rows="4" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"></textarea>
162
+ </div>
163
+
164
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
165
+ <div>
166
+ <label for="regularPrice" class="block text-sm font-medium text-gray-700">Regular Price</label>
167
+ <input type="number" step="0.01" id="regularPrice" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
168
+ </div>
169
+ <div>
170
+ <label for="salePrice" class="block text-sm font-medium text-gray-700">Sale Price</label>
171
+ <input type="number" step="0.01" id="salePrice" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
172
+ </div>
173
+ <div>
174
+ <label for="stock" class="block text-sm font-medium text-gray-700">Stock Quantity</label>
175
+ <input type="number" id="stock" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
176
+ </div>
177
+ </div>
178
+
179
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
180
+ <div>
181
+ <label for="weight" class="block text-sm font-medium text-gray-700">Weight (kg)</label>
182
+ <input type="number" step="0.01" id="weight" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
183
+ </div>
184
+ <div>
185
+ <label for="category" class="block text-sm font-medium text-gray-700">Category Slug</label>
186
+ <input type="text" id="category" placeholder="e.g. electronics" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
187
+ <p class="text-xs text-gray-500 mt-1">Enter the category slug (e.g. electronics, clothing)</p>
188
+ </div>
189
+ </div>
190
+
191
+ <div>
192
+ <label for="tags" class="block text-sm font-medium text-gray-700">Tags (comma separated)</label>
193
+ <input type="text" id="tags" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
194
+ </div>
195
+
196
+ <div>
197
+ <label for="imageUrl" class="block text-sm font-medium text-gray-700">Image URL</label>
198
+ <input type="text" id="imageUrl" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
199
+ </div>
200
+
201
+ <div id="variationsSection" class="hidden">
202
+ <div class="flex justify-between items-center mb-2">
203
+ <label class="block text-sm font-medium text-gray-700">Weight Variations*</label>
204
+ <button type="button" id="addVariationBtn" class="px-2 py-1 text-xs bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors">
205
+ <i class="fas fa-plus mr-1"></i>Add Variation
206
+ </button>
207
+ </div>
208
+ <div id="variationsContainer" class="space-y-2">
209
+ <!-- Variation items will be added here -->
210
+ </div>
211
+ </div>
212
+ </form>
213
+ </div>
214
+ </div>
215
+ <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
216
+ <button type="button" id="saveProductBtn" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm transition-colors">
217
+ Save Product
218
+ </button>
219
+ <button type="button" id="cancelProductBtn" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm transition-colors">
220
+ Cancel
221
+ </button>
222
+ </div>
223
+ </div>
224
+ </div>
225
+ </div>
226
+
227
+ <!-- CSV Download Modal -->
228
+ <div id="csvModal" class="fixed z-10 inset-0 overflow-y-auto hidden">
229
+ <div class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
230
+ <div class="fixed inset-0 transition-opacity" aria-hidden="true">
231
+ <div class="absolute inset-0 bg-gray-500 opacity-75"></div>
232
+ </div>
233
+ <div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
234
+ <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
235
+ <div class="sm:flex sm:items-start">
236
+ <div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-green-100 sm:mx-0 sm:h-10 sm:w-10">
237
+ <i class="fas fa-file-csv text-green-600"></i>
238
+ </div>
239
+ <div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
240
+ <h3 class="text-lg leading-6 font-medium text-gray-900" id="csvModalTitle">CSV Generated Successfully</h3>
241
+ <div class="mt-2">
242
+ <p class="text-sm text-gray-500">Your WooCommerce compatible CSV file is ready to download.</p>
243
+ <div class="mt-4">
244
+ <div class="progress-bar">
245
+ <div class="progress-bar-fill" style="width: 100%"></div>
246
+ </div>
247
+ </div>
248
+ </div>
249
+ </div>
250
+ </div>
251
+ </div>
252
+ <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
253
+ <button type="button" id="downloadCsvBtn" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-600 text-base font-medium text-white hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 sm:ml-3 sm:w-auto sm:text-sm transition-colors">
254
+ <i class="fas fa-download mr-2"></i>Download CSV
255
+ </button>
256
+ <button type="button" id="closeCsvModalBtn" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm transition-colors">
257
+ Close
258
+ </button>
259
+ </div>
260
+ </div>
261
+ </div>
262
+ </div>
263
+
264
+ <!-- Toast Notification -->
265
+ <div id="toast" class="toast">
266
+ <div class="flex items-center">
267
+ <i class="fas fa-check-circle mr-2"></i>
268
+ <span id="toastMessage">Operation completed successfully</span>
269
+ </div>
270
+ </div>
271
+
272
+ <script>
273
+ document.addEventListener('DOMContentLoaded', function() {
274
+ // Product data array
275
+ let products = [];
276
+ let currentProductId = 0;
277
+ let editingProductId = null;
278
+ let csvData = null;
279
+
280
+ // DOM elements
281
+ const addProductBtn = document.getElementById('addProductBtn');
282
+ const addFirstProductBtn = document.getElementById('addFirstProductBtn');
283
+ const productList = document.getElementById('productList');
284
+ const productModal = document.getElementById('productModal');
285
+ const productForm = document.getElementById('productForm');
286
+ const saveProductBtn = document.getElementById('saveProductBtn');
287
+ const cancelProductBtn = document.getElementById('cancelProductBtn');
288
+ const resetBtn = document.getElementById('resetBtn');
289
+ const generateBtn = document.getElementById('generateBtn');
290
+ const productTypeSelect = document.getElementById('productType');
291
+ const variationsSection = document.getElementById('variationsSection');
292
+ const variationsContainer = document.getElementById('variationsContainer');
293
+ const addVariationBtn = document.getElementById('addVariationBtn');
294
+ const csvModal = document.getElementById('csvModal');
295
+ const downloadCsvBtn = document.getElementById('downloadCsvBtn');
296
+ const closeCsvModalBtn = document.getElementById('closeCsvModalBtn');
297
+ const toast = document.getElementById('toast');
298
+ const productCount = document.getElementById('productCount');
299
+ const backToTop = document.getElementById('backToTop');
300
+
301
+ // Event listeners
302
+ addProductBtn.addEventListener('click', openAddProductModal);
303
+ addFirstProductBtn.addEventListener('click', openAddProductModal);
304
+ saveProductBtn.addEventListener('click', saveProduct);
305
+ cancelProductBtn.addEventListener('click', closeModal);
306
+ resetBtn.addEventListener('click', resetAll);
307
+ generateBtn.addEventListener('click', generateCSV);
308
+ productTypeSelect.addEventListener('change', toggleVariationsSection);
309
+ addVariationBtn.addEventListener('click', addVariation);
310
+ downloadCsvBtn.addEventListener('click', downloadCSV);
311
+ closeCsvModalBtn.addEventListener('click', closeCsvModal);
312
+
313
+ // Back to top button
314
+ window.addEventListener('scroll', function() {
315
+ if (window.pageYOffset > 300) {
316
+ backToTop.classList.add('visible');
317
+ } else {
318
+ backToTop.classList.remove('visible');
319
+ }
320
+ });
321
+
322
+ backToTop.addEventListener('click', function() {
323
+ window.scrollTo({
324
+ top: 0,
325
+ behavior: 'smooth'
326
+ });
327
+ });
328
+
329
+ // Functions
330
+ function openAddProductModal() {
331
+ editingProductId = null;
332
+ document.getElementById('modalTitle').textContent = 'Add New Product';
333
+ productForm.reset();
334
+ variationsContainer.innerHTML = '';
335
+ document.getElementById('productId').value = '';
336
+ productModal.classList.remove('hidden');
337
+ }
338
+
339
+ function openEditProductModal(productId) {
340
+ const product = products.find(p => p.id === productId);
341
+ if (!product) return;
342
+
343
+ editingProductId = productId;
344
+ document.getElementById('modalTitle').textContent = 'Edit Product';
345
+ document.getElementById('productId').value = product.id;
346
+ document.getElementById('productType').value = product.type;
347
+ document.getElementById('sku').value = product.sku || '';
348
+ document.getElementById('productName').value = product.name;
349
+ document.getElementById('shortDescription').value = product.shortDescription || '';
350
+ document.getElementById('description').value = product.description || '';
351
+ document.getElementById('regularPrice').value = product.regularPrice || '';
352
+ document.getElementById('salePrice').value = product.salePrice || '';
353
+ document.getElementById('stock').value = product.stock || '';
354
+ document.getElementById('weight').value = product.weight || '';
355
+ document.getElementById('category').value = product.category || '';
356
+ document.getElementById('tags').value = product.tags || '';
357
+ document.getElementById('imageUrl').value = product.imageUrl || '';
358
+
359
+ // Handle variations
360
+ variationsContainer.innerHTML = '';
361
+ if (product.type === 'variable' && product.variations && product.variations.length > 0) {
362
+ product.variations.forEach(variation => {
363
+ addVariation(variation.weight, variation.price);
364
+ });
365
+ }
366
+
367
+ toggleVariationsSection();
368
+ productModal.classList.remove('hidden');
369
+ }
370
+
371
+ function closeModal() {
372
+ productModal.classList.add('hidden');
373
+ }
374
+
375
+ function closeCsvModal() {
376
+ csvModal.classList.add('hidden');
377
+ }
378
+
379
+ function toggleVariationsSection() {
380
+ if (productTypeSelect.value === 'variable') {
381
+ variationsSection.classList.remove('hidden');
382
+ } else {
383
+ variationsSection.classList.add('hidden');
384
+ }
385
+ }
386
+
387
+ function addVariation(weight = '', price = '') {
388
+ const variationId = Date.now();
389
+ const variationItem = document.createElement('div');
390
+ variationItem.className = 'variation-item p-3 border rounded-md';
391
+ variationItem.dataset.id = variationId;
392
+ variationItem.innerHTML = `
393
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-3">
394
+ <div>
395
+ <label class="block text-xs font-medium text-gray-500">Weight (kg)*</label>
396
+ <input type="number" step="0.01" class="variation-weight w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500" value="${weight}" required>
397
+ </div>
398
+ <div>
399
+ <label class="block text-xs font-medium text-gray-500">Price*</label>
400
+ <input type="number" step="0.01" class="variation-price w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500" value="${price}" required>
401
+ </div>
402
+ </div>
403
+ <div class="mt-2 flex justify-end">
404
+ <button type="button" class="remove-variation text-xs text-red-500 hover:text-red-700 transition-colors">
405
+ <i class="fas fa-trash mr-1"></i>Remove
406
+ </button>
407
+ </div>
408
+ `;
409
+ variationsContainer.appendChild(variationItem);
410
+
411
+ // Add event listener to remove button
412
+ variationItem.querySelector('.remove-variation').addEventListener('click', function() {
413
+ variationsContainer.removeChild(variationItem);
414
+ });
415
+ }
416
+
417
+ function saveProduct() {
418
+ const productId = document.getElementById('productId').value;
419
+ const productType = document.getElementById('productType').value;
420
+ const sku = document.getElementById('sku').value;
421
+ const productName = document.getElementById('productName').value;
422
+ const shortDescription = document.getElementById('shortDescription').value;
423
+ const description = document.getElementById('description').value;
424
+ const regularPrice = document.getElementById('regularPrice').value;
425
+ const salePrice = document.getElementById('salePrice').value;
426
+ const stock = document.getElementById('stock').value;
427
+ const weight = document.getElementById('weight').value;
428
+ const category = document.getElementById('category').value;
429
+ const tags = document.getElementById('tags').value;
430
+ const imageUrl = document.getElementById('imageUrl').value;
431
+
432
+ // Collect variations if product is variable
433
+ let variations = [];
434
+ if (productType === 'variable') {
435
+ const variationItems = variationsContainer.querySelectorAll('.variation-item');
436
+ variationItems.forEach(item => {
437
+ const weight = item.querySelector('.variation-weight').value;
438
+ const price = item.querySelector('.variation-price').value;
439
+ if (weight && price) {
440
+ variations.push({
441
+ weight: weight,
442
+ price: price
443
+ });
444
+ }
445
+ });
446
+ }
447
+
448
+ // Validate required fields
449
+ if (!productName) {
450
+ showToast('Product name is required', true);
451
+ return;
452
+ }
453
+
454
+ if (productType === 'variable' && variations.length === 0) {
455
+ showToast('Please add at least one weight variation for variable products', true);
456
+ return;
457
+ }
458
+
459
+ // Create or update product
460
+ const productData = {
461
+ id: productId || ++currentProductId,
462
+ type: productType,
463
+ sku: sku,
464
+ name: productName,
465
+ shortDescription: shortDescription,
466
+ description: description,
467
+ regularPrice: regularPrice,
468
+ salePrice: salePrice,
469
+ stock: stock,
470
+ weight: weight,
471
+ category: category,
472
+ tags: tags,
473
+ imageUrl: imageUrl,
474
+ variations: variations
475
+ };
476
+
477
+ if (editingProductId !== null) {
478
+ // Update existing product
479
+ const index = products.findIndex(p => p.id === editingProductId);
480
+ if (index !== -1) {
481
+ products[index] = productData;
482
+ showToast('Product updated successfully');
483
+ }
484
+ } else {
485
+ // Add new product
486
+ products.push(productData);
487
+ showToast('Product added successfully');
488
+ }
489
+
490
+ renderProductList();
491
+ closeModal();
492
+ }
493
+
494
+ function renderProductList() {
495
+ productList.innerHTML = '';
496
+
497
+ if (products.length === 0) {
498
+ productList.innerHTML = `
499
+ <div class="text-center py-12 text-gray-500">
500
+ <i class="fas fa-box-open text-4xl mb-2"></i>
501
+ <p>No products added yet</p>
502
+ <button id="addFirstProductBtn" class="mt-4 px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 transition-colors">
503
+ <i class="fas fa-plus mr-2"></i>Add Your First Product
504
+ </button>
505
+ </div>
506
+ `;
507
+
508
+ // Re-add event listener for the new button
509
+ document.getElementById('addFirstProductBtn').addEventListener('click', openAddProductModal);
510
+
511
+ productCount.textContent = '0';
512
+ return;
513
+ }
514
+
515
+ productCount.textContent = products.length;
516
+
517
+ products.forEach(product => {
518
+ const productCard = document.createElement('div');
519
+ productCard.className = 'bg-white border rounded-lg overflow-hidden shadow-sm hover:shadow-md transition-shadow border-gray-200';
520
+ productCard.innerHTML = `
521
+ <div class="p-4">
522
+ <div class="flex justify-between items-start">
523
+ <div>
524
+ <h3 class="font-medium text-gray-900">${product.name}</h3>
525
+ <p class="text-sm text-gray-500 mt-1">
526
+ ${product.type === 'simple' ? 'Simple Product' : 'Variable Product'}
527
+ ${product.sku ? `• SKU: ${product.sku}` : ''}
528
+ </p>
529
+ </div>
530
+ <div class="flex space-x-2">
531
+ <button class="edit-product p-1 text-blue-500 hover:text-blue-700 transition-colors" data-id="${product.id}" title="Edit">
532
+ <i class="fas fa-edit"></i>
533
+ </button>
534
+ <button class="duplicate-product p-1 text-purple-500 hover:text-purple-700 transition-colors" data-id="${product.id}" title="Duplicate">
535
+ <i class="fas fa-copy"></i>
536
+ </button>
537
+ <button class="delete-product p-1 text-red-500 hover:text-red-700 transition-colors" data-id="${product.id}" title="Delete">
538
+ <i class="fas fa-trash"></i>
539
+ </button>
540
+ </div>
541
+ </div>
542
+ ${product.type === 'variable' ? `
543
+ <div class="mt-3">
544
+ <p class="text-xs font-medium text-gray-500">Weight Variations:</p>
545
+ <div class="flex flex-wrap gap-1 mt-1">
546
+ ${product.variations.map(v => `
547
+ <span class="text-xs bg-gray-100 px-2 py-1 rounded">${v.weight}kg (${v.price}৳)</span>
548
+ `).join('')}
549
+ </div>
550
+ </div>
551
+ ` : ''}
552
+ ${product.regularPrice ? `
553
+ <div class="mt-2">
554
+ <span class="text-sm font-medium">Price: ${product.regularPrice}৳</span>
555
+ ${product.salePrice ? `<span class="text-sm text-gray-500 ml-2 line-through">${product.salePrice}৳</span>` : ''}
556
+ </div>
557
+ ` : ''}
558
+ ${product.category ? `
559
+ <div class="mt-2">
560
+ <span class="text-xs bg-gray-100 px-2 py-1 rounded">Category: ${product.category}</span>
561
+ </div>
562
+ ` : ''}
563
+ </div>
564
+ `;
565
+ productList.appendChild(productCard);
566
+ });
567
+
568
+ // Add event listeners to edit, duplicate and delete buttons
569
+ document.querySelectorAll('.edit-product').forEach(btn => {
570
+ btn.addEventListener('click', function() {
571
+ openEditProductModal(parseInt(this.dataset.id));
572
+ });
573
+ });
574
+
575
+ document.querySelectorAll('.duplicate-product').forEach(btn => {
576
+ btn.addEventListener('click', function() {
577
+ duplicateProduct(parseInt(this.dataset.id));
578
+ });
579
+ });
580
+
581
+ document.querySelectorAll('.delete-product').forEach(btn => {
582
+ btn.addEventListener('click', function() {
583
+ deleteProduct(parseInt(this.dataset.id));
584
+ });
585
+ });
586
+ }
587
+
588
+ function duplicateProduct(productId) {
589
+ const product = products.find(p => p.id === productId);
590
+ if (!product) return;
591
+
592
+ // Create a deep copy of the product
593
+ const productCopy = JSON.parse(JSON.stringify(product));
594
+ productCopy.id = ++currentProductId;
595
+ productCopy.name = `${productCopy.name} (Copy)`;
596
+
597
+ // Add the duplicated product
598
+ products.push(productCopy);
599
+ renderProductList();
600
+ showToast('Product duplicated successfully');
601
+ }
602
+
603
+ function deleteProduct(productId) {
604
+ if (confirm('Are you sure you want to delete this product?')) {
605
+ products = products.filter(p => p.id !== productId);
606
+ renderProductList();
607
+ showToast('Product deleted successfully');
608
+ }
609
+ }
610
+
611
+ function resetAll() {
612
+ if (products.length === 0 || confirm('Are you sure you want to reset all products? This cannot be undone.')) {
613
+ products = [];
614
+ currentProductId = 0;
615
+ renderProductList();
616
+ showToast('All products have been reset');
617
+ }
618
+ }
619
+
620
+ function generateCSV() {
621
+ if (products.length === 0) {
622
+ showToast('No products to generate CSV', true);
623
+ return;
624
+ }
625
+
626
+ // Prepare CSV data
627
+ const csvRows = [];
628
+
629
+ // Add header row
630
+ const headers = [
631
+ 'ID', 'Type', 'SKU', 'Name', 'Published', 'Is featured?', 'Visibility in catalog',
632
+ 'Short description', 'Description', 'Date sale price starts', 'Date sale price ends',
633
+ 'Tax status', 'Tax class', 'In stock?', 'Stock', 'Backorders', 'Sold individually?',
634
+ 'Weight (kg)', 'Length (cm)', 'Width (cm)', 'Height (cm)', 'Allow customer reviews?',
635
+ 'Purchase note', 'Sale price', 'Regular price', 'Categories', 'Tags', 'Shipping class',
636
+ 'Images', 'Download limit', 'Download expiry days', 'Parent', 'Grouped products',
637
+ 'Upsells', 'Cross-sells', 'External URL', 'Button text', 'Position', 'Attribute 1 name',
638
+ 'Attribute 1 value(s)', 'Attribute 1 visible', 'Attribute 1 global', 'Attribute 2 name',
639
+ 'Attribute 2 value(s)', 'Attribute 2 visible', 'Attribute 2 global', 'Meta: _wpcom_is_markdown',
640
+ 'Download 1 name', 'Download 1 URL', 'Download 2 name', 'Download 2 URL'
641
+ ];
642
+
643
+ csvRows.push(headers);
644
+
645
+ // Add product rows
646
+ products.forEach(product => {
647
+ if (product.type === 'simple') {
648
+ // Simple product
649
+ const row = [
650
+ '', // ID
651
+ 'simple', // Type
652
+ product.sku || '', // SKU
653
+ product.name, // Name
654
+ '1', // Published
655
+ '0', // Is featured?
656
+ 'visible', // Visibility in catalog
657
+ product.shortDescription || '', // Short description
658
+ product.description || '', // Description
659
+ '', // Date sale price starts
660
+ '', // Date sale price ends
661
+ 'taxable', // Tax status
662
+ '', // Tax class
663
+ product.stock ? '1' : '0', // In stock?
664
+ product.stock || '', // Stock
665
+ '0', // Backorders
666
+ '0', // Sold individually?
667
+ product.weight || '', // Weight (kg)
668
+ '', // Length (cm)
669
+ '', // Width (cm)
670
+ '', // Height (cm)
671
+ '1', // Allow customer reviews?
672
+ '', // Purchase note
673
+ product.salePrice || '', // Sale price
674
+ product.regularPrice || '', // Regular price
675
+ product.category ? `${product.category}:${product.category}` : '', // Categories
676
+ product.tags || '', // Tags
677
+ '', // Shipping class
678
+ product.imageUrl || '', // Images
679
+ '', // Download limit
680
+ '', // Download expiry days
681
+ '', // Parent
682
+ '', // Grouped products
683
+ '', // Upsells
684
+ '', // Cross-sells
685
+ '', // External URL
686
+ '', // Button text
687
+ '0', // Position
688
+ '', // Attribute 1 name
689
+ '', // Attribute 1 value(s)
690
+ '0', // Attribute 1 visible
691
+ '0', // Attribute 1 global
692
+ '', // Attribute 2 name
693
+ '', // Attribute 2 value(s)
694
+ '0', // Attribute 2 visible
695
+ '0', // Attribute 2 global
696
+ '0', // Meta: _wpcom_is_markdown
697
+ '', // Download 1 name
698
+ '', // Download 1 URL
699
+ '', // Download 2 name
700
+ '', // Download 2 URL
701
+ ];
702
+
703
+ csvRows.push(row);
704
+ } else if (product.type === 'variable') {
705
+ // Variable product - first add the parent product
706
+ const parentRow = [
707
+ '', // ID
708
+ 'variable', // Type
709
+ product.sku || '', // SKU
710
+ product.name, // Name
711
+ '1', // Published
712
+ '0', // Is featured?
713
+ 'visible', // Visibility in catalog
714
+ product.shortDescription || '', // Short description
715
+ product.description || '', // Description
716
+ '', // Date sale price starts
717
+ '', // Date sale price ends
718
+ 'taxable', // Tax status
719
+ '', // Tax class
720
+ '1', // In stock?
721
+ '', // Stock
722
+ '0', // Backorders
723
+ '0', // Sold individually?
724
+ '', // Weight (kg)
725
+ '', // Length (cm)
726
+ '', // Width (cm)
727
+ '', // Height (cm)
728
+ '1', // Allow customer reviews?
729
+ '', // Purchase note
730
+ '', // Sale price
731
+ '', // Regular price
732
+ product.category ? `${product.category}:${product.category}` : '', // Categories
733
+ product.tags || '', // Tags
734
+ '', // Shipping class
735
+ product.imageUrl || '', // Images
736
+ '', // Download limit
737
+ '', // Download expiry days
738
+ '', // Parent
739
+ '', // Grouped products
740
+ '', // Upsells
741
+ '', // Cross-sells
742
+ '', // External URL
743
+ '', // Button text
744
+ '0', // Position
745
+ 'Weight', // Attribute 1 name
746
+ product.variations.map(v => v.weight).join('|'), // Attribute 1 value(s)
747
+ '1', // Attribute 1 visible
748
+ '1', // Attribute 1 global
749
+ '', // Attribute 2 name
750
+ '', // Attribute 2 value(s)
751
+ '0', // Attribute 2 visible
752
+ '0', // Attribute 2 global
753
+ '0', // Meta: _wpcom_is_markdown
754
+ '', // Download 1 name
755
+ '', // Download 1 URL
756
+ '', // Download 2 name
757
+ '', // Download 2 URL
758
+ ];
759
+
760
+ csvRows.push(parentRow);
761
+
762
+ // Then add each variation
763
+ product.variations.forEach((variation, index) => {
764
+ const variationRow = [
765
+ '', // ID
766
+ 'variation', // Type
767
+ product.sku ? `${product.sku}-${index + 1}` : '', // SKU
768
+ `${product.name} (${variation.weight}kg)`, // Name
769
+ '1', // Published
770
+ '0', // Is featured?
771
+ 'visible', // Visibility in catalog
772
+ '', // Short description
773
+ '', // Description
774
+ '', // Date sale price starts
775
+ '', // Date sale price ends
776
+ 'taxable', // Tax status
777
+ '', // Tax class
778
+ '1', // In stock?
779
+ '', // Stock
780
+ '0', // Backorders
781
+ '0', // Sold individually?
782
+ variation.weight, // Weight (kg)
783
+ '', // Length (cm)
784
+ '', // Width (cm)
785
+ '', // Height (cm)
786
+ '1', // Allow customer reviews?
787
+ '', // Purchase note
788
+ '', // Sale price
789
+ variation.price, // Regular price
790
+ '', // Categories
791
+ '', // Tags
792
+ '', // Shipping class
793
+ '', // Images
794
+ '', // Download limit
795
+ '', // Download expiry days
796
+ product.name, // Parent
797
+ '', // Grouped products
798
+ '', // Upsells
799
+ '', // Cross-sells
800
+ '', // External URL
801
+ '', // Button text
802
+ '0', // Position
803
+ 'Weight', // Attribute 1 name
804
+ variation.weight, // Attribute 1 value(s)
805
+ '1', // Attribute 1 visible
806
+ '1', // Attribute 1 global
807
+ '', // Attribute 2 name
808
+ '', // Attribute 2 value(s)
809
+ '0', // Attribute 2 visible
810
+ '0', // Attribute 2 global
811
+ '0', // Meta: _wpcom_is_markdown
812
+ '', // Download 1 name
813
+ '', // Download 1 URL
814
+ '', // Download 2 name
815
+ '', // Download 2 URL
816
+ ];
817
+
818
+ csvRows.push(variationRow);
819
+ });
820
+ }
821
+ });
822
+
823
+ // Convert to CSV string
824
+ csvData = Papa.unparse(csvRows);
825
+
826
+ // Show CSV download modal
827
+ csvModal.classList.remove('hidden');
828
+ }
829
+
830
+ function downloadCSV() {
831
+ if (!csvData) return;
832
+
833
+ const blob = new Blob([csvData], { type: 'text/csv;charset=utf-8;' });
834
+ const url = URL.createObjectURL(blob);
835
+ const link = document.createElement('a');
836
+ link.setAttribute('href', url);
837
+ link.setAttribute('download', 'woocommerce_products_import.csv');
838
+ link.style.visibility = 'hidden';
839
+ document.body.appendChild(link);
840
+ link.click();
841
+ document.body.removeChild(link);
842
+
843
+ showToast('CSV downloaded successfully');
844
+ closeCsvModal();
845
+ }
846
+
847
+ function showToast(message, isError = false) {
848
+ const toastMessage = document.getElementById('toastMessage');
849
+ toastMessage.textContent = message;
850
+
851
+ if (isError) {
852
+ toast.classList.add('error');
853
+ } else {
854
+ toast.classList.remove('error');
855
+ }
856
+
857
+ toast.classList.add('show');
858
+
859
+ setTimeout(() => {
860
+ toast.classList.remove('show');
861
+ }, 3000);
862
+ }
863
+
864
+ // Initialize
865
+ renderProductList();
866
+ });
867
+ </script>
868
+ <footer class="text-center text-gray-500 text-sm mt-8">
869
+ <p>WC Product CSV Generator App | Created by <a href="https://github.com/almahmudbd/" target="_blank" class="text-blue-500 hover:text-blue-700">almahmud</a></p>
870
+ </footer>
871
+ <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=almahmud/wc-product-cvs-generator" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
872
+ </html>
prompts.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ ক্যাটাগরির বিষয়টা সিম্পল করতে হবে, শুধুমাত্র স্লাগ লিখব, আগের ক্যাটাগরিতে এড করে দিবে এরকম। এছাড়া বক্সগুলো বেশি সাদা হয়ে গেছে, ব্যাকগ্রাউন্ডের সাথে মিশে গেছে এটা ঠিক করতে হবে। আর লিস্টে প্রোডাক্ট এড করার পর সেটা ডুপ্লিকেট করার জন্য একটা বটন রাখা যেতে পারে।