docto41 commited on
Commit
ee41924
·
verified ·
1 Parent(s): d036fc2

Add 2 files

Browse files
Files changed (2) hide show
  1. index.html +548 -465
  2. prompts.txt +2 -1
index.html CHANGED
@@ -3,505 +3,444 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Hacker Codes - Recherche Envato & CodeCanyon</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
10
- @import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap');
11
-
12
- :root {
13
- --neon-green: #39ff14;
14
- --neon-blue: #00f7ff;
15
- --neon-pink: #ff00ff;
16
- }
17
-
18
- body {
19
- font-family: 'Share Tech Mono', monospace;
20
- background-color: #0a0a0a;
21
- color: #fff;
22
- overflow-x: hidden;
23
- }
24
-
25
- .glitch {
26
- position: relative;
27
- }
28
-
29
- .glitch::before, .glitch::after {
30
- content: attr(data-text);
31
- position: absolute;
32
- top: 0;
33
- left: 0;
34
- width: 100%;
35
- height: 100%;
36
- }
37
-
38
- .glitch::before {
39
- left: 2px;
40
- text-shadow: -2px 0 var(--neon-pink);
41
- clip: rect(44px, 450px, 56px, 0);
42
- animation: glitch-anim 5s infinite linear alternate-reverse;
43
- }
44
-
45
- .glitch::after {
46
- left: -2px;
47
- text-shadow: -2px 0 var(--neon-blue);
48
- clip: rect(44px, 450px, 56px, 0);
49
- animation: glitch-anim2 5s infinite linear alternate-reverse;
50
- }
51
-
52
- @keyframes glitch-anim {
53
- 0% { clip: rect(31px, 9999px, 94px, 0); }
54
- 10% { clip: rect(112px, 9999px, 76px, 0); }
55
- 20% { clip: rect(85px, 9999px, 77px, 0); }
56
- 30% { clip: rect(27px, 9999px, 97px, 0); }
57
- 40% { clip: rect(64px, 9999px, 98px, 0); }
58
- 50% { clip: rect(61px, 9999px, 85px, 0); }
59
- 60% { clip: rect(99px, 9999px, 114px, 0); }
60
- 70% { clip: rect(34px, 9999px, 115px, 0); }
61
- 80% { clip: rect(98px, 9999px, 129px, 0); }
62
- 90% { clip: rect(43px, 9999px, 96px, 0); }
63
- 100% { clip: rect(82px, 9999px, 64px, 0); }
64
- }
65
-
66
- @keyframes glitch-anim2 {
67
- 0% { clip: rect(65px, 9999px, 119px, 0); }
68
- 10% { clip: rect(79px, 9999px, 66px, 0); }
69
- 20% { clip: rect(101px, 9999px, 114px, 0); }
70
- 30% { clip: rect(107px, 9999px, 99px, 0); }
71
- 40% { clip: rect(47px, 9999px, 128px, 0); }
72
- 50% { clip: rect(13px, 9999px, 55px, 0); }
73
- 60% { clip: rect(60px, 9999px, 92px, 0); }
74
- 70% { clip: rect(10px, 9999px, 2px, 0); }
75
- 80% { clip: rect(86px, 9999px, 40px, 0); }
76
- 90% { clip: rect(41px, 9999px, 23px, 0); }
77
- 100% { clip: rect(83px, 9999px, 40px, 0); }
78
- }
79
-
80
- .terminal {
81
- border: 1px solid var(--neon-green);
82
- box-shadow: 0 0 10px var(--neon-green);
83
- position: relative;
84
- }
85
-
86
- .terminal::before {
87
- content: '';
88
- position: absolute;
89
- top: 0;
90
- left: 0;
91
- right: 0;
92
- height: 30px;
93
- background: rgba(57, 255, 20, 0.1);
94
- border-bottom: 1px solid var(--neon-green);
95
- }
96
-
97
- .terminal-header {
98
- position: absolute;
99
- top: 5px;
100
- left: 10px;
101
- display: flex;
102
- }
103
-
104
- .terminal-btn {
105
- width: 12px;
106
- height: 12px;
107
- border-radius: 50%;
108
- margin-right: 5px;
109
- }
110
-
111
- .terminal-btn.red {
112
- background: #ff5f56;
113
- }
114
-
115
- .terminal-btn.yellow {
116
- background: #ffbd2e;
117
- }
118
-
119
- .terminal-btn.green {
120
- background: #27c93f;
121
- }
122
-
123
- .code-input {
124
- background: transparent;
125
- border: 1px solid var(--neon-blue);
126
- color: var(--neon-green);
127
- font-family: 'Share Tech Mono', monospace;
128
- outline: none;
129
- box-shadow: 0 0 5px var(--neon-blue);
130
- }
131
-
132
- .code-input:focus {
133
- box-shadow: 0 0 10px var(--neon-blue);
134
- }
135
-
136
- .neon-text {
137
- text-shadow: 0 0 5px var(--neon-green);
138
- color: var(--neon-green);
139
- }
140
-
141
- .neon-border {
142
- border: 1px solid var(--neon-green);
143
- box-shadow: 0 0 10px var(--neon-green);
144
- }
145
-
146
- .neon-border-blue {
147
- border: 1px solid var(--neon-blue);
148
- box-shadow: 0 0 10px var(--neon-blue);
149
- }
150
-
151
- .neon-border-pink {
152
- border: 1px solid var(--neon-pink);
153
- box-shadow: 0 0 10px var(--neon-pink);
154
- }
155
-
156
- .scanline {
157
- position: absolute;
158
- top: 0;
159
- left: 0;
160
- width: 100%;
161
- height: 100%;
162
- background: linear-gradient(
163
- to bottom,
164
- rgba(255, 255, 255, 0) 0%,
165
- rgba(255, 255, 255, 0.03) 50%,
166
- rgba(255, 255, 255, 0) 100%
167
- );
168
- animation: scanline 8s linear infinite;
169
- pointer-events: none;
170
  }
171
 
172
- @keyframes scanline {
173
- 0% { transform: translateY(-100%); }
174
- 100% { transform: translateY(100%); }
175
  }
176
 
177
- .typewriter {
178
- overflow: hidden;
179
- border-right: 3px solid var(--neon-green);
180
- white-space: nowrap;
181
- margin: 0 auto;
182
- letter-spacing: 2px;
183
- animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite;
184
  }
185
 
186
- @keyframes typing {
187
- from { width: 0 }
188
- to { width: 100% }
 
 
189
  }
190
 
191
- @keyframes blink-caret {
192
- from, to { border-color: transparent }
193
- 50% { border-color: var(--neon-green) }
194
  }
195
 
196
- .matrix-bg {
197
- position: fixed;
198
- top: 0;
199
- left: 0;
200
- width: 100%;
201
- height: 100%;
202
- z-index: -1;
203
- opacity: 0.1;
204
  }
205
 
206
- .pulse {
207
- animation: pulse 2s infinite;
 
208
  }
209
 
210
  @keyframes pulse {
211
- 0% { box-shadow: 0 0 0 0 rgba(57, 255, 20, 0.7); }
212
- 70% { box-shadow: 0 0 0 10px rgba(57, 255, 20, 0); }
213
- 100% { box-shadow: 0 0 0 0 rgba(57, 255, 20, 0); }
214
  }
215
 
216
- .flicker {
217
- animation: flicker 3s linear infinite;
218
  }
219
 
220
- @keyframes flicker {
221
- 0%, 19.999%, 22%, 62.999%, 64%, 64.999%, 70%, 100% {
222
- opacity: 1;
223
- }
224
- 20%, 21.999%, 63%, 63.999%, 65%, 69.999% {
225
- opacity: 0.4;
226
- }
227
- }
228
-
229
- .dropzone {
230
- border: 2px dashed var(--neon-blue);
231
- border-radius: 5px;
232
- padding: 25px;
233
- text-align: center;
234
- cursor: pointer;
235
- transition: all 0.3s;
236
- }
237
-
238
- .dropzone:hover {
239
- border-color: var(--neon-green);
240
- box-shadow: 0 0 10px var(--neon-green);
241
- }
242
-
243
- .dropzone.active {
244
- border-color: var(--neon-pink);
245
- background-color: rgba(255, 0, 255, 0.05);
246
- }
247
-
248
- .search-highlight {
249
- background-color: rgba(57, 255, 20, 0.3);
250
- font-weight: bold;
251
  }
252
  </style>
253
  </head>
254
- <body class="min-h-screen flex flex-col items-center justify-center p-4">
255
- <canvas id="matrix" class="matrix-bg"></canvas>
256
- <div class="scanline"></div>
257
-
258
- <div class="w-full max-w-4xl relative">
259
- <!-- Header with glitch effect -->
260
- <div class="text-center mb-8">
261
- <h1 class="glitch text-4xl md:text-6xl font-bold mb-4" data-text="HACKER CODES">
262
- HACKER CODES
263
- </h1>
264
- <p class="typewriter text-xl neon-text">Recherche de codes Envato & CodeCanyon</p>
265
- </div>
266
-
267
- <!-- Main terminal -->
268
- <div class="terminal bg-black bg-opacity-90 rounded-lg p-6 pt-12 mb-8 neon-border">
269
- <div class="terminal-header">
270
- <div class="terminal-btn red"></div>
271
- <div class="terminal-btn yellow"></div>
272
- <div class="terminal-btn green"></div>
273
  </div>
274
-
275
- <!-- Search section -->
276
- <div class="mb-6">
277
- <div class="flex items-center mb-2">
278
- <span class="text-green-400 mr-2">$</span>
279
- <span class="text-gray-300">search_codes --method=</span>
280
- <select id="searchMethod" class="code-input ml-2 px-2 py-1 rounded bg-black text-green-400">
281
- <option value="text">Nom du produit</option>
282
- <option value="image">Image du produit</option>
283
- </select>
284
  </div>
285
-
286
- <!-- Text search -->
287
- <div id="textSearch" class="ml-8 mt-4">
288
- <div class="flex items-center mb-2">
289
- <span class="text-green-400 mr-2">></span>
290
- <input type="text" id="searchInput" placeholder="Entrez le nom du produit..." class="code-input w-full px-3 py-2 rounded bg-black text-green-400">
291
- </div>
292
- <button id="searchBtn" class="mt-2 px-4 py-2 bg-blue-900 text-blue-300 rounded hover:bg-blue-800 transition flex items-center">
293
  <i class="fas fa-search mr-2"></i> Rechercher
294
  </button>
295
  </div>
296
 
297
- <!-- Image search -->
298
- <div id="imageSearch" class="ml-8 mt-4 hidden">
299
- <div id="dropzone" class="dropzone mb-4">
300
- <i class="fas fa-cloud-upload-alt text-3xl text-blue-400 mb-2"></i>
301
- <p class="text-blue-300">Glissez-déposez une image ici</p>
302
- <p class="text-gray-400 text-sm mt-2">ou cliquez pour sélectionner</p>
303
- <input type="file" id="fileInput" accept="image/*" class="hidden">
304
  </div>
305
- <div id="imagePreview" class="hidden mb-4">
306
- <img id="preview" src="#" alt="Aperçu de l'image" class="max-h-40 mx-auto rounded border border-blue-400">
 
 
 
 
 
 
 
 
 
 
307
  </div>
308
- <button id="searchImageBtn" class="px-4 py-2 bg-pink-900 text-pink-300 rounded hover:bg-pink-800 transition flex items-center">
309
- <i class="fas fa-camera mr-2"></i> Rechercher par image
310
- </button>
311
  </div>
312
  </div>
313
 
314
- <!-- Results section -->
315
- <div id="results" class="hidden">
316
- <div class="flex items-center mb-2">
317
- <span class="text-green-400 mr-2">$</span>
318
- <span class="text-gray-300">results_found --count=<span id="resultCount" class="text-green-400">0</span></span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  </div>
320
-
321
- <div id="resultsContainer" class="mt-4 space-y-4">
322
- <!-- Results will be displayed here -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  </div>
324
  </div>
325
 
326
- <!-- Status bar -->
327
- <div class="text-xs text-gray-500 flex justify-between border-t border-gray-800 pt-2">
328
- <div>
329
- <span class="text-green-400">STATUS:</span>
330
- <span class="text-gray-400">ACTIVE</span>
331
- </div>
332
- <div>
333
- <span class="text-blue-400">CONNECTION:</span>
334
- <span class="text-gray-400">SECURE</span>
335
- </div>
336
- <div>
337
- <span class="text-pink-400">LAST SEARCH:</span>
338
- <span id="lastSearch" class="text-gray-400">Aucune</span>
339
  </div>
340
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341
  </div>
342
 
343
- <!-- Disclaimer -->
344
- <div class="text-center text-xs text-gray-500 neon-border p-3 rounded">
345
- <p class="flicker">WARNING: Ceci est une démonstration d'interface. Les fonctionnalités de recherche sont simulées.</p>
346
- </div>
 
 
 
 
 
 
 
 
 
 
 
347
  </div>
348
 
349
  <script>
350
- // Matrix background effect
351
- const canvas = document.getElementById('matrix');
352
- const ctx = canvas.getContext('2d');
353
-
354
- canvas.width = window.innerWidth;
355
- canvas.height = window.innerHeight;
356
-
357
- const katakana = 'アァカサタナハマヤャラワガザダバパイィキシチニヒミリヰギジヂビピウゥクスツヌフムユュルグズブヅプエェケセテネヘメレヱゲゼ��ベペオォコソトノホモヨョロヲゴゾドボポヴッン';
358
- const latin = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
359
- const nums = '0123456789';
360
- const symbols = '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~';
361
-
362
- const alphabet = katakana + latin + nums + symbols;
363
-
364
- const fontSize = 16;
365
- const columns = canvas.width / fontSize;
366
-
367
- const rainDrops = [];
368
-
369
- for (let x = 0; x < columns; x++) {
370
- rainDrops[x] = 1;
371
- }
372
-
373
- const draw = () => {
374
- ctx.fillStyle = 'rgba(0, 0, 0, 0.05)';
375
- ctx.fillRect(0, 0, canvas.width, canvas.height);
376
-
377
- ctx.fillStyle = '#39ff14';
378
- ctx.font = fontSize + 'px monospace';
379
-
380
- for (let i = 0; i < rainDrops.length; i++) {
381
- const text = alphabet.charAt(Math.floor(Math.random() * alphabet.length));
382
- ctx.fillText(text, i * fontSize, rainDrops[i] * fontSize);
383
-
384
- if (rainDrops[i] * fontSize > canvas.height && Math.random() > 0.975) {
385
- rainDrops[i] = 0;
386
- }
387
- rainDrops[i]++;
388
- }
389
- };
390
-
391
- setInterval(draw, 30);
392
-
393
- // Handle window resize
394
- window.addEventListener('resize', () => {
395
- canvas.width = window.innerWidth;
396
- canvas.height = window.innerHeight;
397
- });
398
-
399
- // Sample database of products
400
  const products = [
401
- {
402
- name: "ThemeForest - Avada",
403
- type: "envato",
404
- code: "ENV-7XK9-2P4M-Q6R1",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
405
  category: "Thème WordPress",
406
- description: "Thème WordPress multi-usage avec constructeur de page avancé."
 
 
 
 
 
 
 
407
  },
408
- {
409
- name: "CodeCanyon - Slider Revolution",
410
- type: "codecanyon",
411
- code: "CC-5H8J-3K9M-4P2Q",
412
  category: "Plugin WordPress",
413
- description: "Plugin de création de sliders et animations avancées."
 
 
 
 
 
 
 
414
  },
415
- {
416
- name: "ThemeForest - BeTheme",
417
- type: "envato",
418
- code: "ENV-3L8D-9F2K-5N7J",
419
  category: "Thème WordPress",
420
- description: "Thème WordPress avec plus de 600 démos pré-construites."
 
 
 
 
 
 
 
421
  },
422
- {
423
- name: "CodeCanyon - WPBakery",
424
- type: "codecanyon",
425
- code: "CC-7R2T-9Y4U-1I6O",
426
  category: "Plugin WordPress",
427
- description: "Constructeur de page visuel pour WordPress."
 
 
 
 
 
 
 
428
  },
429
- {
430
- name: "ThemeForest - The7",
431
- type: "envato",
432
- code: "ENV-1M4P-7R9T-2S6V",
433
  category: "Thème WordPress",
434
- description: "Thème WordPress ultra-personnalisable avec options avancées."
 
 
 
 
 
 
 
435
  },
436
- {
437
- name: "CodeCanyon - Elementor Pro",
438
- type: "codecanyon",
439
- code: "CC-8W3E-5R7T-2Y9U",
440
  category: "Plugin WordPress",
441
- description: "Constructeur de page avancé avec fonctionnalités pro."
 
 
 
 
 
 
 
442
  }
443
  ];
444
-
445
- // Search method toggle
446
- const searchMethod = document.getElementById('searchMethod');
447
- const textSearch = document.getElementById('textSearch');
448
- const imageSearch = document.getElementById('imageSearch');
449
-
450
- searchMethod.addEventListener('change', function() {
451
- if (this.value === 'text') {
452
- textSearch.classList.remove('hidden');
453
- imageSearch.classList.add('hidden');
454
- } else {
455
- textSearch.classList.add('hidden');
456
- imageSearch.classList.remove('hidden');
457
- }
458
- });
459
-
460
- // Image upload handling
461
  const dropzone = document.getElementById('dropzone');
462
  const fileInput = document.getElementById('fileInput');
463
- const imagePreview = document.getElementById('imagePreview');
464
  const preview = document.getElementById('preview');
465
-
466
- // Handle drag and drop
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
  ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
468
  dropzone.addEventListener(eventName, preventDefaults, false);
469
  });
470
-
471
  function preventDefaults(e) {
472
  e.preventDefault();
473
  e.stopPropagation();
474
  }
475
-
476
  ['dragenter', 'dragover'].forEach(eventName => {
477
  dropzone.addEventListener(eventName, highlight, false);
478
  });
479
-
480
  ['dragleave', 'drop'].forEach(eventName => {
481
  dropzone.addEventListener(eventName, unhighlight, false);
482
  });
483
-
484
  function highlight() {
485
- dropzone.classList.add('active');
486
  }
487
-
488
  function unhighlight() {
489
- dropzone.classList.remove('active');
490
  }
491
-
492
  dropzone.addEventListener('drop', handleDrop, false);
493
  dropzone.addEventListener('click', () => fileInput.click(), false);
494
-
495
  fileInput.addEventListener('change', function() {
496
  handleFiles(this.files);
497
  });
498
-
499
  function handleDrop(e) {
500
  const dt = e.dataTransfer;
501
  const files = dt.files;
502
  handleFiles(files);
503
  }
504
-
505
  function handleFiles(files) {
506
  if (files.length) {
507
  const file = files[0];
@@ -509,68 +448,141 @@
509
  const reader = new FileReader();
510
  reader.onload = function(e) {
511
  preview.src = e.target.result;
512
- imagePreview.classList.remove('hidden');
 
513
  };
514
  reader.readAsDataURL(file);
515
  }
516
  }
517
  }
518
-
519
- // Text search function
520
- document.getElementById('searchBtn').addEventListener('click', function() {
521
- const searchTerm = document.getElementById('searchInput').value.trim().toLowerCase();
522
- if (searchTerm) {
523
- searchProducts(searchTerm);
524
- document.getElementById('lastSearch').textContent = `Texte: "${searchTerm}"`;
 
 
 
 
 
 
525
  }
526
  });
527
-
528
- // Image search function (simulated)
529
- document.getElementById('searchImageBtn').addEventListener('click', function() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
530
  if (preview.src && !preview.src.endsWith('#')) {
 
 
531
  // Simulate image search with random results
532
- const randomProducts = [...products].sort(() => 0.5 - Math.random()).slice(0, 3);
533
- displayResults(randomProducts);
534
- document.getElementById('lastSearch').textContent = "Par image";
535
- document.getElementById('resultCount').textContent = randomProducts.length;
536
- document.getElementById('results').classList.remove('hidden');
537
  } else {
538
  alert("Veuillez d'abord sélectionner une image.");
539
  }
540
- });
541
-
542
- // Search products function
543
- function searchProducts(searchTerm) {
544
- const results = products.filter(product =>
545
- product.name.toLowerCase().includes(searchTerm) ||
546
- product.description.toLowerCase().includes(searchTerm) ||
547
- product.category.toLowerCase().includes(searchTerm)
548
- );
 
 
 
 
 
 
 
 
 
 
 
 
549
 
550
- displayResults(results, searchTerm);
551
- document.getElementById('resultCount').textContent = results.length;
552
- document.getElementById('results').classList.remove('hidden');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
553
  }
554
-
555
- // Display results function
556
- function displayResults(results, searchTerm = '') {
557
- const resultsContainer = document.getElementById('resultsContainer');
558
  resultsContainer.innerHTML = '';
 
 
 
 
 
 
559
 
560
  if (results.length === 0) {
561
- resultsContainer.innerHTML = '<p class="text-gray-400">Aucun résultat trouvé.</p>';
 
 
562
  return;
563
  }
564
 
 
 
 
565
  results.forEach(product => {
566
  const productElement = document.createElement('div');
567
- productElement.className = 'bg-gray-800 p-4 rounded neon-border-blue';
568
 
569
- // Highlight search term in results
570
  let highlightedName = product.name;
571
  let highlightedDesc = product.description;
572
 
573
- if (searchTerm) {
574
  const regex = new RegExp(searchTerm, 'gi');
575
  highlightedName = product.name.replace(regex, match =>
576
  `<span class="search-highlight">${match}</span>`
@@ -580,41 +592,112 @@
580
  );
581
  }
582
 
 
 
 
 
 
 
583
  productElement.innerHTML = `
584
- <div class="flex justify-between items-start">
585
- <div>
586
- <h3 class="text-lg font-bold text-blue-400">${highlightedName}</h3>
587
- <p class="text-sm text-gray-400">${product.category}</p>
588
- <p class="text-gray-300 mt-2">${highlightedDesc}</p>
 
 
 
589
  </div>
590
- <div class="flex flex-col items-end">
591
- <code class="text-green-400 font-mono text-sm">${product.code}</code>
592
- <button onclick="copyCode('${product.code}')" class="mt-2 text-xs ${product.type === 'envato' ? 'bg-blue-900 text-blue-300' : 'bg-pink-900 text-pink-300'} px-2 py-1 rounded hover:${product.type === 'envato' ? 'bg-blue-800' : 'bg-pink-800'} transition">
593
- <i class="fas fa-copy mr-1"></i> Copier
594
- </button>
 
 
 
 
 
 
 
 
 
 
 
595
  </div>
596
  </div>
 
 
 
 
 
 
 
 
597
  `;
598
 
599
  resultsContainer.appendChild(productElement);
600
  });
 
 
 
 
 
 
 
601
  }
602
-
603
- // Copy code function
604
- function copyCode(code) {
605
- navigator.clipboard.writeText(code).then(() => {
606
- // Show copied notification
 
 
 
 
607
  const notification = document.createElement('div');
608
- notification.className = 'fixed top-4 right-4 bg-green-900 text-green-300 px-4 py-2 rounded shadow-lg flex items-center';
609
- notification.innerHTML = `<i class="fas fa-check-circle mr-2"></i> Copié: ${code}`;
 
 
 
610
  document.body.appendChild(notification);
611
 
612
  setTimeout(() => {
613
- notification.classList.add('opacity-0', 'transition-opacity', 'duration-500');
614
- setTimeout(() => notification.remove(), 500);
615
- }, 2000);
 
 
 
 
 
 
 
 
616
  });
617
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
618
  </script>
619
  <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=docto41/envato-code" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
620
  </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Envato Search - Recherche de produits</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
10
+ .dropzone {
11
+ border: 2px dashed #3b82f6;
12
+ border-radius: 0.5rem;
13
+ padding: 2rem;
14
+ text-align: center;
15
+ cursor: pointer;
16
+ transition: all 0.3s;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
 
19
+ .dropzone:hover {
20
+ border-color: #10b981;
21
+ background-color: rgba(16, 185, 129, 0.05);
22
  }
23
 
24
+ .dropzone.active {
25
+ border-color: #8b5cf6;
26
+ background-color: rgba(139, 92, 246, 0.05);
 
 
 
 
27
  }
28
 
29
+ .search-highlight {
30
+ background-color: rgba(16, 185, 129, 0.3);
31
+ font-weight: bold;
32
+ padding: 0.1rem 0.2rem;
33
+ border-radius: 0.2rem;
34
  }
35
 
36
+ .envato-badge {
37
+ background-color: #82b440;
 
38
  }
39
 
40
+ .codecanyon-badge {
41
+ background-color: #7e57c2;
 
 
 
 
 
 
42
  }
43
 
44
+ .skeleton {
45
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
46
+ background-color: #e5e7eb;
47
  }
48
 
49
  @keyframes pulse {
50
+ 0%, 100% { opacity: 1; }
51
+ 50% { opacity: 0.5; }
 
52
  }
53
 
54
+ .image-search-preview {
55
+ transition: all 0.3s ease;
56
  }
57
 
58
+ .image-search-preview:hover {
59
+ transform: scale(1.02);
60
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  }
62
  </style>
63
  </head>
64
+ <body class="bg-gray-50 min-h-screen">
65
+ <div class="container mx-auto px-4 py-8 max-w-6xl">
66
+ <!-- Header -->
67
+ <header class="mb-8">
68
+ <div class="flex items-center justify-between">
69
+ <div class="flex items-center">
70
+ <img src="https://assets.envato.com/front/assets/envato-market-6d2a3fe6f4f1c4a16bea9eafb0e2b4b5d3c9188111f805d41a61d3d3b21e5ef1.svg" alt="Envato Market" class="h-10 mr-4">
71
+ <h1 class="text-3xl font-bold text-gray-800">Recherche de produits</h1>
72
+ </div>
73
+ <div class="flex items-center space-x-4">
74
+ <button class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition flex items-center">
75
+ <i class="fas fa-sign-in-alt mr-2"></i> Connexion
76
+ </button>
77
+ </div>
 
 
 
 
 
78
  </div>
79
+ <p class="text-gray-600 mt-2">Recherchez parmi des milliers de produits Envato Market et CodeCanyon</p>
80
+ </header>
81
+
82
+ <!-- Search Section -->
83
+ <div class="bg-white rounded-lg shadow-md p-6 mb-8">
84
+ <div class="flex items-center justify-between mb-6">
85
+ <h2 class="text-xl font-semibold text-gray-800">Options de recherche</h2>
86
+ <div class="flex space-x-2">
87
+ <button id="textSearchTab" class="px-4 py-2 bg-green-600 text-white rounded-md transition">Recherche par texte</button>
88
+ <button id="imageSearchTab" class="px-4 py-2 bg-blue-600 text-white rounded-md transition">Recherche par image</button>
89
  </div>
90
+ </div>
91
+
92
+ <!-- Text Search -->
93
+ <div id="textSearchSection" class="">
94
+ <div class="relative">
95
+ <input type="text" id="searchInput" placeholder="Rechercher par nom de produit, catégorie, auteur..."
96
+ class="w-full px-4 py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500">
97
+ <button id="searchBtn" class="absolute right-2 top-1/2 transform -translate-y-1/2 bg-green-600 text-white px-4 py-2 rounded-md hover:bg-green-700 transition">
98
  <i class="fas fa-search mr-2"></i> Rechercher
99
  </button>
100
  </div>
101
 
102
+ <div class="flex flex-wrap gap-4 mt-4">
103
+ <div class="flex items-center">
104
+ <input type="checkbox" id="filterEnvato" checked class="mr-2">
105
+ <label for="filterEnvato" class="text-gray-700">Envato Market</label>
 
 
 
106
  </div>
107
+ <div class="flex items-center">
108
+ <input type="checkbox" id="filterCodeCanyon" checked class="mr-2">
109
+ <label for="filterCodeCanyon" class="text-gray-700">CodeCanyon</label>
110
+ </div>
111
+ <div class="flex items-center ml-auto">
112
+ <select id="sortBy" class="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
113
+ <option value="relevance">Pertinence</option>
114
+ <option value="popular">Plus populaires</option>
115
+ <option value="newest">Plus récents</option>
116
+ <option value="price_asc">Prix croissant</option>
117
+ <option value="price_desc">Prix décroissant</option>
118
+ </select>
119
  </div>
 
 
 
120
  </div>
121
  </div>
122
 
123
+ <!-- Image Search -->
124
+ <div id="imageSearchSection" class="hidden">
125
+ <div class="mb-6">
126
+ <div id="dropzone" class="dropzone mb-4">
127
+ <i class="fas fa-cloud-upload-alt text-4xl text-blue-500 mb-3"></i>
128
+ <p class="text-lg font-medium text-gray-700">Glissez-déposez une image de produit ici</p>
129
+ <p class="text-gray-500 mt-1">ou cliquez pour sélectionner un fichier</p>
130
+ <input type="file" id="fileInput" accept="image/*" class="hidden">
131
+ </div>
132
+
133
+ <div id="imagePreviewContainer" class="hidden">
134
+ <div class="flex items-center justify-between mb-4">
135
+ <h3 class="text-lg font-medium text-gray-800">Image sélectionnée</h3>
136
+ <button id="clearImageBtn" class="text-red-600 hover:text-red-800">
137
+ <i class="fas fa-times mr-1"></i> Supprimer
138
+ </button>
139
+ </div>
140
+ <div class="flex flex-col md:flex-row gap-6">
141
+ <div class="w-full md:w-1/3">
142
+ <div class="image-search-preview bg-white p-2 rounded-md border border-gray-200">
143
+ <img id="preview" src="#" alt="Aperçu de l'image" class="w-full h-auto rounded-md">
144
+ </div>
145
+ </div>
146
+ <div class="w-full md:w-2/3">
147
+ <div class="space-y-4">
148
+ <div>
149
+ <label for="imageSearchType" class="block text-sm font-medium text-gray-700 mb-1">Type de recherche</label>
150
+ <select id="imageSearchType" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
151
+ <option value="exact">Recherche exacte</option>
152
+ <option value="similar">Produits similaires</option>
153
+ <option value="color">Par palette de couleurs</option>
154
+ </select>
155
+ </div>
156
+ <div>
157
+ <label for="imageSearchConfidence" class="block text-sm font-medium text-gray-700 mb-1">Niveau de correspondance</label>
158
+ <input type="range" id="imageSearchConfidence" min="50" max="100" value="80" class="w-full">
159
+ <div class="flex justify-between text-xs text-gray-500 mt-1">
160
+ <span>Large</span>
161
+ <span>Précis</span>
162
+ </div>
163
+ </div>
164
+ <button id="searchImageBtn" class="w-full md:w-auto px-6 py-3 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition flex items-center justify-center">
165
+ <i class="fas fa-camera mr-2"></i> Lancer la recherche
166
+ </button>
167
+ </div>
168
+ </div>
169
+ </div>
170
+ </div>
171
  </div>
172
+ </div>
173
+ </div>
174
+
175
+ <!-- Results Section -->
176
+ <div id="resultsSection" class="hidden">
177
+ <div class="flex items-center justify-between mb-6">
178
+ <h2 class="text-xl font-semibold text-gray-800">
179
+ Résultats de recherche: <span id="resultsCount" class="text-blue-600">0</span>
180
+ </h2>
181
+ <div class="flex items-center space-x-2">
182
+ <span class="text-sm text-gray-600">Trier par:</span>
183
+ <select id="resultsSortBy" class="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
184
+ <option value="relevance">Pertinence</option>
185
+ <option value="popular">Popularité</option>
186
+ <option value="newest">Plus récents</option>
187
+ <option value="price_asc">Prix croissant</option>
188
+ <option value="price_desc">Prix décroissant</option>
189
+ </select>
190
  </div>
191
  </div>
192
 
193
+ <div id="loadingIndicator" class="hidden">
194
+ <div class="space-y-4">
195
+ <div class="skeleton h-32 rounded-md"></div>
196
+ <div class="skeleton h-32 rounded-md"></div>
197
+ <div class="skeleton h-32 rounded-md"></div>
 
 
 
 
 
 
 
 
198
  </div>
199
  </div>
200
+
201
+ <div id="resultsContainer" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
202
+ <!-- Results will be loaded here -->
203
+ </div>
204
+
205
+ <div id="pagination" class="mt-8 flex justify-center hidden">
206
+ <nav class="inline-flex rounded-md shadow">
207
+ <button class="px-3 py-1 rounded-l-md border border-gray-300 bg-white text-gray-500 hover:bg-gray-50">
208
+ Précédent
209
+ </button>
210
+ <button class="px-3 py-1 border-t border-b border-gray-300 bg-blue-50 text-blue-600 font-medium">
211
+ 1
212
+ </button>
213
+ <button class="px-3 py-1 border border-gray-300 bg-white text-gray-500 hover:bg-gray-50">
214
+ 2
215
+ </button>
216
+ <button class="px-3 py-1 border border-gray-300 bg-white text-gray-500 hover:bg-gray-50">
217
+ 3
218
+ </button>
219
+ <button class="px-3 py-1 rounded-r-md border border-gray-300 bg-white text-gray-500 hover:bg-gray-50">
220
+ Suivant
221
+ </button>
222
+ </nav>
223
+ </div>
224
+
225
+ <div id="noResults" class="hidden text-center py-12">
226
+ <i class="fas fa-search fa-3x text-gray-300 mb-4"></i>
227
+ <h3 class="text-xl font-medium text-gray-700">Aucun résultat trouvé</h3>
228
+ <p class="text-gray-500 mt-2">Essayez de modifier vos critères de recherche</p>
229
+ </div>
230
  </div>
231
 
232
+ <!-- Footer -->
233
+ <footer class="mt-12 pt-8 border-t border-gray-200">
234
+ <div class="flex flex-col md:flex-row justify-between items-center">
235
+ <div class="mb-4 md:mb-0">
236
+ <img src="https://assets.envato.com/front/assets/envato-market-6d2a3fe6f4f1c4a16bea9eafb0e2b4b5d3c9188111f805d41a61d3d3b21e5ef1.svg" alt="Envato Market" class="h-8">
237
+ <p class="text-gray-500 text-sm mt-2">© 2023 Envato Pty Ltd. Tous droits réservés.</p>
238
+ </div>
239
+ <div class="flex space-x-6">
240
+ <a href="#" class="text-gray-600 hover:text-gray-900">Conditions</a>
241
+ <a href="#" class="text-gray-600 hover:text-gray-900">Politique de confidentialité</a>
242
+ <a href="#" class="text-gray-600 hover:text-gray-900">API</a>
243
+ <a href="#" class="text-gray-600 hover:text-gray-900">Support</a>
244
+ </div>
245
+ </div>
246
+ </footer>
247
  </div>
248
 
249
  <script>
250
+ // Sample product database (in a real app, this would come from an API)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  const products = [
252
+ {
253
+ id: "avada",
254
+ name: "Avada | Website Builder For WordPress & WooCommerce",
255
+ type: "envato",
256
+ category: "Thème WordPress",
257
+ author: "ThemeFusion",
258
+ price: 69,
259
+ sales: 842000,
260
+ rating: 4.82,
261
+ updated: "2023-10-15",
262
+ description: "Avada est le meilleur vendeur #1 de tous les temps sur ThemeForest avec 840 000 ventes. Il s'agit d'un thème WordPress ultra-personnalisable avec un constructeur de page avancé.",
263
+ image: "https://themeforest.img.customer.envatousercontent.com/files/459385881/avada-preview.jpg?auto=compress%2Cformat&fit=crop&crop=top&w=590&h=300&s=7b1b0c0b1b1b1b1b1b1b1b1b1b1b1b1",
264
+ tags: ["wordpress", "builder", "woocommerce", "responsive"]
265
+ },
266
+ {
267
+ id: "revolution",
268
+ name: "Slider Revolution - More Than Just a WordPress Slider",
269
+ type: "codecanyon",
270
+ category: "Plugin WordPress",
271
+ author: "ThemePunch",
272
+ price: 39,
273
+ sales: 320000,
274
+ rating: 4.78,
275
+ updated: "2023-09-28",
276
+ description: "Slider Revolution est un plugin de création de sliders et animations avancées pour WordPress. Créez des présentations époustouflantes avec des effets visuels impressionnants.",
277
+ image: "https://s3.envato.com/files/328384320/slider-revolution-preview.jpg",
278
+ tags: ["slider", "animation", "wordpress", "visual"]
279
+ },
280
+ {
281
+ id: "betheme",
282
+ name: "BeTheme - Responsive Multi-Purpose WordPress Theme",
283
+ type: "envato",
284
  category: "Thème WordPress",
285
+ author: "Muffin group",
286
+ price: 59,
287
+ sales: 235000,
288
+ rating: 4.75,
289
+ updated: "2023-08-10",
290
+ description: "BeTheme est un thème WordPress multi-usage avec plus de 600 démos pré-construites. Idéal pour créer tout type de site web rapidement et facilement.",
291
+ image: "https://themeforest.img.customer.envatousercontent.com/files/459385881/betheme-preview.jpg?auto=compress%2Cformat&fit=crop&crop=top&w=590&h=300&s=7b1b0c0b1b1b1b1b1b1b1b1b1b1b1b1",
292
+ tags: ["wordpress", "multipurpose", "responsive", "demos"]
293
  },
294
+ {
295
+ id: "wpbakery",
296
+ name: "WPBakery Page Builder (formerly Visual Composer)",
297
+ type: "codecanyon",
298
  category: "Plugin WordPress",
299
+ author: "WPBakery",
300
+ price: 45,
301
+ sales: 410000,
302
+ rating: 4.72,
303
+ updated: "2023-07-22",
304
+ description: "WPBakery Page Builder est un constructeur de page visuel pour WordPress. Créez des mises en page complexes sans coder avec une interface glisser-déposer intuitive.",
305
+ image: "https://s3.envato.com/files/328384320/wpbakery-preview.jpg",
306
+ tags: ["page builder", "wordpress", "drag and drop", "visual"]
307
  },
308
+ {
309
+ id: "the7",
310
+ name: "The7 — Website and eCommerce Builder for WordPress",
311
+ type: "envato",
312
  category: "Thème WordPress",
313
+ author: "Dream-Theme",
314
+ price: 39,
315
+ sales: 125000,
316
+ rating: 4.81,
317
+ updated: "2023-10-05",
318
+ description: "The7 est un thème WordPress ultra-personnalisable avec options avancées. Compatible avec WooCommerce pour créer des boutiques en ligne performantes.",
319
+ image: "https://themeforest.img.customer.envatousercontent.com/files/459385881/the7-preview.jpg?auto=compress%2Cformat&fit=crop&crop=top&w=590&h=300&s=7b1b0c0b1b1b1b1b1b1b1b1b1b1b1b1",
320
+ tags: ["wordpress", "woocommerce", "responsive", "customizable"]
321
  },
322
+ {
323
+ id: "elementor",
324
+ name: "Elementor Pro — Premium Drag & Drop Page Builder",
325
+ type: "codecanyon",
326
  category: "Plugin WordPress",
327
+ author: "Elementor.com",
328
+ price: 49,
329
+ sales: 380000,
330
+ rating: 4.85,
331
+ updated: "2023-09-15",
332
+ description: "Elementor Pro est un constructeur de page avancé avec fonctionnalités pro. Créez des sites web professionnels avec une interface glisser-déposer intuitive et des widgets avancés.",
333
+ image: "https://s3.envato.com/files/328384320/elementor-preview.jpg",
334
+ tags: ["page builder", "wordpress", "drag and drop", "pro"]
335
  },
336
+ {
337
+ id: "flatsome",
338
+ name: "Flatsome | Multi-Purpose Responsive WooCommerce Theme",
339
+ type: "envato",
340
  category: "Thème WordPress",
341
+ author: "UX-Themes",
342
+ price: 59,
343
+ sales: 185000,
344
+ rating: 4.83,
345
+ updated: "2023-08-28",
346
+ description: "Flatsome est un thème WordPress spécialement conçu pour WooCommerce. Il offre des fonctionnalités avancées pour créer des boutiques en ligne performantes et esthétiques.",
347
+ image: "https://themeforest.img.customer.envatousercontent.com/files/459385881/flatsome-preview.jpg?auto=compress%2Cformat&fit=crop&crop=top&w=590&h=300&s=7b1b0c0b1b1b1b1b1b1b1b1b1b1b1b1",
348
+ tags: ["wordpress", "woocommerce", "ecommerce", "responsive"]
349
  },
350
+ {
351
+ id: "ultimate",
352
+ name: "Ultimate Addons for Elementor - Power-up Your Elementor Page Builder",
353
+ type: "codecanyon",
354
  category: "Plugin WordPress",
355
+ author: "Brainstorm Force",
356
+ price: 25,
357
+ sales: 95000,
358
+ rating: 4.79,
359
+ updated: "2023-07-30",
360
+ description: "Ultimate Addons étend les fonctionnalités d'Elementor avec des widgets et modules supplémentaires. Créez des mises en page encore plus impressionnantes avec ces outils avancés.",
361
+ image: "https://s3.envato.com/files/328384320/ultimate-addons-preview.jpg",
362
+ tags: ["elementor", "wordpress", "addons", "widgets"]
363
  }
364
  ];
365
+
366
+ // DOM Elements
367
+ const textSearchTab = document.getElementById('textSearchTab');
368
+ const imageSearchTab = document.getElementById('imageSearchTab');
369
+ const textSearchSection = document.getElementById('textSearchSection');
370
+ const imageSearchSection = document.getElementById('imageSearchSection');
371
+ const searchInput = document.getElementById('searchInput');
372
+ const searchBtn = document.getElementById('searchBtn');
 
 
 
 
 
 
 
 
 
373
  const dropzone = document.getElementById('dropzone');
374
  const fileInput = document.getElementById('fileInput');
375
+ const imagePreviewContainer = document.getElementById('imagePreviewContainer');
376
  const preview = document.getElementById('preview');
377
+ const clearImageBtn = document.getElementById('clearImageBtn');
378
+ const searchImageBtn = document.getElementById('searchImageBtn');
379
+ const resultsSection = document.getElementById('resultsSection');
380
+ const resultsContainer = document.getElementById('resultsContainer');
381
+ const resultsCount = document.getElementById('resultsCount');
382
+ const loadingIndicator = document.getElementById('loadingIndicator');
383
+ const noResults = document.getElementById('noResults');
384
+ const pagination = document.getElementById('pagination');
385
+ const filterEnvato = document.getElementById('filterEnvato');
386
+ const filterCodeCanyon = document.getElementById('filterCodeCanyon');
387
+ const sortBy = document.getElementById('sortBy');
388
+ const resultsSortBy = document.getElementById('resultsSortBy');
389
+
390
+ // Tab switching
391
+ textSearchTab.addEventListener('click', () => {
392
+ textSearchTab.classList.add('bg-green-600');
393
+ imageSearchTab.classList.remove('bg-blue-600');
394
+ textSearchSection.classList.remove('hidden');
395
+ imageSearchSection.classList.add('hidden');
396
+ });
397
+
398
+ imageSearchTab.addEventListener('click', () => {
399
+ imageSearchTab.classList.add('bg-blue-600');
400
+ textSearchTab.classList.remove('bg-green-600');
401
+ imageSearchSection.classList.remove('hidden');
402
+ textSearchSection.classList.add('hidden');
403
+ });
404
+
405
+ // Image upload handling
406
  ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
407
  dropzone.addEventListener(eventName, preventDefaults, false);
408
  });
409
+
410
  function preventDefaults(e) {
411
  e.preventDefault();
412
  e.stopPropagation();
413
  }
414
+
415
  ['dragenter', 'dragover'].forEach(eventName => {
416
  dropzone.addEventListener(eventName, highlight, false);
417
  });
418
+
419
  ['dragleave', 'drop'].forEach(eventName => {
420
  dropzone.addEventListener(eventName, unhighlight, false);
421
  });
422
+
423
  function highlight() {
424
+ dropzone.classList.add('border-blue-500', 'bg-blue-50');
425
  }
426
+
427
  function unhighlight() {
428
+ dropzone.classList.remove('border-blue-500', 'bg-blue-50');
429
  }
430
+
431
  dropzone.addEventListener('drop', handleDrop, false);
432
  dropzone.addEventListener('click', () => fileInput.click(), false);
433
+
434
  fileInput.addEventListener('change', function() {
435
  handleFiles(this.files);
436
  });
437
+
438
  function handleDrop(e) {
439
  const dt = e.dataTransfer;
440
  const files = dt.files;
441
  handleFiles(files);
442
  }
443
+
444
  function handleFiles(files) {
445
  if (files.length) {
446
  const file = files[0];
 
448
  const reader = new FileReader();
449
  reader.onload = function(e) {
450
  preview.src = e.target.result;
451
+ imagePreviewContainer.classList.remove('hidden');
452
+ dropzone.classList.add('hidden');
453
  };
454
  reader.readAsDataURL(file);
455
  }
456
  }
457
  }
458
+
459
+ clearImageBtn.addEventListener('click', function() {
460
+ preview.src = '#';
461
+ fileInput.value = '';
462
+ imagePreviewContainer.classList.add('hidden');
463
+ dropzone.classList.remove('hidden');
464
+ });
465
+
466
+ // Search functions
467
+ searchBtn.addEventListener('click', performTextSearch);
468
+ searchInput.addEventListener('keypress', function(e) {
469
+ if (e.key === 'Enter') {
470
+ performTextSearch();
471
  }
472
  });
473
+
474
+ searchImageBtn.addEventListener('click', performImageSearch);
475
+
476
+ function performTextSearch() {
477
+ const searchTerm = searchInput.value.trim().toLowerCase();
478
+ if (searchTerm) {
479
+ showLoading();
480
+
481
+ // Simulate API delay
482
+ setTimeout(() => {
483
+ const filteredProducts = filterProducts(searchTerm);
484
+ displayResults(filteredProducts, searchTerm);
485
+ }, 800);
486
+ }
487
+ }
488
+
489
+ function performImageSearch() {
490
  if (preview.src && !preview.src.endsWith('#')) {
491
+ showLoading();
492
+
493
  // Simulate image search with random results
494
+ setTimeout(() => {
495
+ const randomProducts = [...products].sort(() => 0.5 - Math.random()).slice(0, 6);
496
+ displayResults(randomProducts, '', true);
497
+ }, 1200);
 
498
  } else {
499
  alert("Veuillez d'abord sélectionner une image.");
500
  }
501
+ }
502
+
503
+ function filterProducts(searchTerm) {
504
+ const showEnvato = filterEnvato.checked;
505
+ const showCodeCanyon = filterCodeCanyon.checked;
506
+ const sortMethod = sortBy.value;
507
+
508
+ let filtered = products.filter(product => {
509
+ // Filter by type
510
+ if ((product.type === 'envato' && !showEnvato) ||
511
+ (product.type === 'codecanyon' && !showCodeCanyon)) {
512
+ return false;
513
+ }
514
+
515
+ // Filter by search term
516
+ return product.name.toLowerCase().includes(searchTerm) ||
517
+ product.description.toLowerCase().includes(searchTerm) ||
518
+ product.category.toLowerCase().includes(searchTerm) ||
519
+ product.author.toLowerCase().includes(searchTerm) ||
520
+ product.tags.some(tag => tag.toLowerCase().includes(searchTerm));
521
+ });
522
 
523
+ // Sort results
524
+ switch(sortMethod) {
525
+ case 'popular':
526
+ filtered.sort((a, b) => b.sales - a.sales);
527
+ break;
528
+ case 'newest':
529
+ filtered.sort((a, b) => new Date(b.updated) - new Date(a.updated));
530
+ break;
531
+ case 'price_asc':
532
+ filtered.sort((a, b) => a.price - b.price);
533
+ break;
534
+ case 'price_desc':
535
+ filtered.sort((a, b) => b.price - a.price);
536
+ break;
537
+ default: // relevance
538
+ // Simple relevance scoring - more matches = higher relevance
539
+ filtered.forEach(product => {
540
+ let score = 0;
541
+ if (product.name.toLowerCase().includes(searchTerm)) score += 3;
542
+ if (product.description.toLowerCase().includes(searchTerm)) score += 2;
543
+ if (product.category.toLowerCase().includes(searchTerm)) score += 1;
544
+ if (product.author.toLowerCase().includes(searchTerm)) score += 1;
545
+ product.tags.forEach(tag => {
546
+ if (tag.toLowerCase().includes(searchTerm)) score += 1;
547
+ });
548
+ product.relevance = score;
549
+ });
550
+ filtered.sort((a, b) => b.relevance - a.relevance);
551
+ }
552
+
553
+ return filtered;
554
  }
555
+
556
+ function showLoading() {
557
+ resultsSection.classList.remove('hidden');
558
+ loadingIndicator.classList.remove('hidden');
559
  resultsContainer.innerHTML = '';
560
+ noResults.classList.add('hidden');
561
+ pagination.classList.add('hidden');
562
+ }
563
+
564
+ function displayResults(results, searchTerm = '', isImageSearch = false) {
565
+ loadingIndicator.classList.add('hidden');
566
 
567
  if (results.length === 0) {
568
+ noResults.classList.remove('hidden');
569
+ resultsCount.textContent = '0';
570
+ pagination.classList.add('hidden');
571
  return;
572
  }
573
 
574
+ resultsCount.textContent = results.length;
575
+ resultsContainer.innerHTML = '';
576
+
577
  results.forEach(product => {
578
  const productElement = document.createElement('div');
579
+ productElement.className = 'bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition';
580
 
581
+ // Highlight search term in results (for text search only)
582
  let highlightedName = product.name;
583
  let highlightedDesc = product.description;
584
 
585
+ if (searchTerm && !isImageSearch) {
586
  const regex = new RegExp(searchTerm, 'gi');
587
  highlightedName = product.name.replace(regex, match =>
588
  `<span class="search-highlight">${match}</span>`
 
592
  );
593
  }
594
 
595
+ // Format price
596
+ const formattedPrice = new Intl.NumberFormat('fr-FR', {
597
+ style: 'currency',
598
+ currency: 'USD'
599
+ }).format(product.price);
600
+
601
  productElement.innerHTML = `
602
+ <div class="relative">
603
+ <img src="${product.image}" alt="${product.name}" class="w-full h-48 object-cover">
604
+ <span class="absolute top-2 left-2 px-2 py-1 rounded-md text-xs font-semibold text-white ${product.type === 'envato' ? 'envato-badge' : 'codecanyon-badge'}">
605
+ ${product.type === 'envato' ? 'Envato' : 'CodeCanyon'}
606
+ </span>
607
+ ${isImageSearch ? `
608
+ <div class="absolute top-2 right-2 bg-white bg-opacity-90 px-2 py-1 rounded-md text-xs font-semibold">
609
+ <i class="fas fa-percentage mr-1"></i> ${Math.floor(Math.random() * 20) + 80}% match
610
  </div>
611
+ ` : ''}
612
+ </div>
613
+ <div class="p-4">
614
+ <h3 class="font-bold text-lg text-gray-800 mb-1">${highlightedName}</h3>
615
+ <p class="text-sm text-gray-600 mb-2">Par ${product.author}</p>
616
+ <p class="text-gray-700 text-sm mb-3 line-clamp-2">${highlightedDesc}</p>
617
+ <div class="flex items-center justify-between">
618
+ <div>
619
+ <span class="font-bold text-gray-900">${formattedPrice}</span>
620
+ <span class="text-xs text-gray-500 ml-1">+ TVA si applicable</span>
621
+ </div>
622
+ <div class="flex items-center">
623
+ <i class="fas fa-star text-yellow-400 mr-1"></i>
624
+ <span class="text-sm font-medium">${product.rating}</span>
625
+ <span class="text-xs text-gray-500 ml-1">(${Math.floor(product.sales / 1000)}k)</span>
626
+ </div>
627
  </div>
628
  </div>
629
+ <div class="px-4 py-3 bg-gray-50 border-t border-gray-100 flex justify-between">
630
+ <a href="#" class="text-blue-600 hover:text-blue-800 text-sm font-medium">
631
+ <i class="far fa-eye mr-1"></i> Voir détails
632
+ </a>
633
+ <button class="text-green-600 hover:text-green-800 text-sm font-medium add-to-cart" data-id="${product.id}">
634
+ <i class="fas fa-cart-plus mr-1"></i> Ajouter
635
+ </button>
636
+ </div>
637
  `;
638
 
639
  resultsContainer.appendChild(productElement);
640
  });
641
+
642
+ // Show pagination if enough results
643
+ if (results.length > 6) {
644
+ pagination.classList.remove('hidden');
645
+ } else {
646
+ pagination.classList.add('hidden');
647
+ }
648
  }
649
+
650
+ // Add to cart functionality
651
+ document.addEventListener('click', function(e) {
652
+ if (e.target.classList.contains('add-to-cart') || e.target.closest('.add-to-cart')) {
653
+ const button = e.target.classList.contains('add-to-cart') ? e.target : e.target.closest('.add-to-cart');
654
+ const productId = button.getAttribute('data-id');
655
+ const product = products.find(p => p.id === productId);
656
+
657
+ // Show added notification
658
  const notification = document.createElement('div');
659
+ notification.className = 'fixed top-4 right-4 bg-green-600 text-white px-4 py-2 rounded-md shadow-lg flex items-center animate-fade-in';
660
+ notification.innerHTML = `
661
+ <i class="fas fa-check-circle mr-2"></i>
662
+ "${product.name}" ajouté au panier
663
+ `;
664
  document.body.appendChild(notification);
665
 
666
  setTimeout(() => {
667
+ notification.classList.add('animate-fade-out');
668
+ setTimeout(() => notification.remove(), 300);
669
+ }, 3000);
670
+ }
671
+ });
672
+
673
+ // Results sorting
674
+ resultsSortBy.addEventListener('change', function() {
675
+ const currentResults = Array.from(resultsContainer.children).map(el => {
676
+ const id = el.querySelector('.add-to-cart').getAttribute('data-id');
677
+ return products.find(p => p.id === id);
678
  });
679
+
680
+ const sortMethod = this.value;
681
+
682
+ switch(sortMethod) {
683
+ case 'popular':
684
+ currentResults.sort((a, b) => b.sales - a.sales);
685
+ break;
686
+ case 'newest':
687
+ currentResults.sort((a, b) => new Date(b.updated) - new Date(a.updated));
688
+ break;
689
+ case 'price_asc':
690
+ currentResults.sort((a, b) => a.price - b.price);
691
+ break;
692
+ case 'price_desc':
693
+ currentResults.sort((a, b) => b.price - a.price);
694
+ break;
695
+ default: // relevance - keep original order
696
+ break;
697
+ }
698
+
699
+ displayResults(currentResults);
700
+ });
701
  </script>
702
  <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=docto41/envato-code" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
703
  </html>
prompts.txt CHANGED
@@ -1,2 +1,3 @@
1
  hacker code d'achat envato et codecanyon
2
- je veux rechercher par non du produit ou image
 
 
1
  hacker code d'achat envato et codecanyon
2
+ je veux rechercher par non du produit ou image
3
+ je veux pas demonstation je veux du vrai du reel