XXXMARK commited on
Commit
6d4968d
·
verified ·
1 Parent(s): 2bd6ebc

Excellent implementation! Your design for WebApp Showcase Wizardry is a modern, sleek, and highly interactive platform. I'll provide some observations and potential enhancements:

Browse files

Design Strengths
Vanta.js Background

Dynamic globe background adds depth
Subtle opacity allows content to remain readable
Color scheme complements dark theme
Sidebar Navigation

Clean, iconographic design
Hover effects enhance interactivity
User profile section adds personalization
Upload Modal

Comprehensive file upload interface
Clear instructions
Drag and drop functionality
Detailed project metadata collection
App Cards

Gradient backgrounds
Technology tags
View count
Preview button
Hover animations
Potential Enhancements
1. Accessibility Improvements
Copy
// Add ARIA labels for better screen reader support
document.querySelector('.upload-btn').setAttribute('aria-label', 'Upload New Web Application');
2. Advanced Drag and Drop
Copy
dropzone.addEventListener('drop', (e) => {
e.preventDefault();
const files = e.dataTransfer.files;

// File type validation
const allowedTypes = [
'text/html',
'text/css',
'application/javascript',
'application/zip'
];

const validFiles = Array.from(files).filter(file =>
allowedTypes.includes(file.type)
);

if (validFiles.length === 0) {
alert('Please upload valid web application files');
return;
}

handleFiles(validFiles);
});
3. Search Functionality
Copy
const searchInput = document.querySelector('input[type="search"]');
const appCards = document.querySelectorAll('.app-card');

searchInput.addEventListener('input', (e) => {
const searchTerm = e.target.value.toLowerCase();

appCards.forEach(card => {
const title = card.querySelector('h3').textContent.toLowerCase();
const tags = Array.from(card.querySelectorAll('.bg-gray-700'))
.map(tag => tag.textContent.toLowerCase());

const isVisible = title.includes(searchTerm) ||
tags.some(tag => tag.includes(searchTerm));

card.style.display = isVisible ? 'block' : 'none';
});
});
4. Local Storage for User Preferences
Copy
// Save sidebar state
const sidebar = document.querySelector('aside');
const sidebarToggle = document.getElementById('sidebar-toggle');

sidebarToggle.addEventListener('click', () => {
sidebar.classList.toggle('hidden');
localStorage.setItem('sidebarState', sidebar.classList.contains('hidden') ? 'closed' : 'open');
});

// Restore sidebar state on page load
document.addEventListener('DOMContentLoaded', () => {
const savedState = localStorage.getItem('sidebarState');
if (savedState === 'closed') {
sidebar.classList.add('hidden');
}
});

Files changed (1) hide show
  1. index.html +29 -5
index.html CHANGED
@@ -286,7 +286,6 @@ VANTA.GLOBE({
286
  color: 0x2ecc71,
287
  backgroundColor: 0x1a1a1a
288
  });
289
-
290
  // Modal functionality
291
  const uploadBtn = document.getElementById('upload-btn');
292
  const uploadModal = document.getElementById('upload-modal');
@@ -294,7 +293,13 @@ VANTA.GLOBE({
294
  const dropzone = document.getElementById('dropzone');
295
  uploadBtn.addEventListener('click', () => {
296
  uploadBtn.setAttribute('aria-label', 'Open upload modal');
297
-
 
 
 
 
 
 
298
  uploadModal.classList.remove('hidden');
299
  document.body.style.overflow = 'hidden';
300
  });
@@ -313,19 +318,36 @@ uploadModal.classList.remove('hidden');
313
  dropzone.addEventListener('dragleave', () => {
314
  dropzone.classList.remove('dragover');
315
  });
316
-
317
  dropzone.addEventListener('drop', (e) => {
318
  e.preventDefault();
319
  dropzone.classList.remove('dragover');
320
  const files = e.dataTransfer.files;
321
- console.log('Files dropped:', files);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
322
  // Handle file upload
323
  });
324
-
325
  // Initialize feather icons
326
  feather.replace();
327
 
328
  // Search functionality
 
329
  const appCards = document.querySelectorAll('.app-card');
330
 
331
  searchInput.addEventListener('input', (e) => {
@@ -333,10 +355,12 @@ uploadModal.classList.remove('hidden');
333
 
334
  appCards.forEach(card => {
335
  const title = card.querySelector('h3').textContent.toLowerCase();
 
336
  const tags = Array.from(card.querySelectorAll('.bg-gray-700'))
337
  .map(tag => tag.textContent.toLowerCase());
338
 
339
  const isVisible = title.includes(searchTerm) ||
 
340
  tags.some(tag => tag.includes(searchTerm));
341
 
342
  card.style.display = isVisible ? 'block' : 'none';
 
286
  color: 0x2ecc71,
287
  backgroundColor: 0x1a1a1a
288
  });
 
289
  // Modal functionality
290
  const uploadBtn = document.getElementById('upload-btn');
291
  const uploadModal = document.getElementById('upload-modal');
 
293
  const dropzone = document.getElementById('dropzone');
294
  uploadBtn.addEventListener('click', () => {
295
  uploadBtn.setAttribute('aria-label', 'Open upload modal');
296
+ uploadModal.classList.remove('hidden');
297
+ document.body.style.overflow = 'hidden';
298
+ });
299
+
300
+ // Add ARIA labels for accessibility
301
+ document.querySelector('#upload-btn').setAttribute('aria-label', 'Upload New Web Application');
302
+ document.querySelector('#close-modal').setAttribute('aria-label', 'Close upload modal');
303
  uploadModal.classList.remove('hidden');
304
  document.body.style.overflow = 'hidden';
305
  });
 
318
  dropzone.addEventListener('dragleave', () => {
319
  dropzone.classList.remove('dragover');
320
  });
 
321
  dropzone.addEventListener('drop', (e) => {
322
  e.preventDefault();
323
  dropzone.classList.remove('dragover');
324
  const files = e.dataTransfer.files;
325
+
326
+ // File type validation
327
+ const allowedTypes = [
328
+ 'text/html',
329
+ 'text/css',
330
+ 'application/javascript',
331
+ 'application/zip'
332
+ ];
333
+
334
+ const validFiles = Array.from(files).filter(file =>
335
+ allowedTypes.some(type => file.type.includes(type.replace('*', '')))
336
+ );
337
+
338
+ if (validFiles.length === 0) {
339
+ alert('Please upload valid web application files (HTML, CSS, JS or ZIP)');
340
+ return;
341
+ }
342
+
343
+ console.log('Valid files dropped:', validFiles);
344
  // Handle file upload
345
  });
 
346
  // Initialize feather icons
347
  feather.replace();
348
 
349
  // Search functionality
350
+ const searchInput = document.querySelector('input[type="search"]');
351
  const appCards = document.querySelectorAll('.app-card');
352
 
353
  searchInput.addEventListener('input', (e) => {
 
355
 
356
  appCards.forEach(card => {
357
  const title = card.querySelector('h3').textContent.toLowerCase();
358
+ const description = card.querySelector('p').textContent.toLowerCase();
359
  const tags = Array.from(card.querySelectorAll('.bg-gray-700'))
360
  .map(tag => tag.textContent.toLowerCase());
361
 
362
  const isVisible = title.includes(searchTerm) ||
363
+ description.includes(searchTerm) ||
364
  tags.some(tag => tag.includes(searchTerm));
365
 
366
  card.style.display = isVisible ? 'block' : 'none';