o2satz commited on
Commit
1ecbd9c
·
verified ·
1 Parent(s): ecbdee5

Add 1 files

Browse files
Files changed (1) hide show
  1. index.html +280 -1
index.html CHANGED
@@ -67,6 +67,12 @@
67
  ::-webkit-scrollbar-thumb:hover {
68
  background: #94a3b8;
69
  }
 
 
 
 
 
 
70
  </style>
71
  </head>
72
  <body class="bg-slate-50">
@@ -751,5 +757,278 @@
751
  const newFile = {
752
  id: Math.max(...newFiles.map(f => f.id)) + 1,
753
  name: ['New Document.docx', 'Report.pdf', 'Image.jpg', 'Archive.zip', 'Data.xlsx'][Math.floor(Math.random() * 5)],
754
- path: ['Documents', 'Downloads', 'Pictures', 'Music', 'Videos'][Math.floor(Math
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
755
  </html>
 
67
  ::-webkit-scrollbar-thumb:hover {
68
  background: #94a3b8;
69
  }
70
+ .modal-enter-active, .modal-leave-active {
71
+ transition: opacity 0.3s ease;
72
+ }
73
+ .modal-enter-from, .modal-leave-to {
74
+ opacity: 0;
75
+ }
76
  </style>
77
  </head>
78
  <body class="bg-slate-50">
 
757
  const newFile = {
758
  id: Math.max(...newFiles.map(f => f.id)) + 1,
759
  name: ['New Document.docx', 'Report.pdf', 'Image.jpg', 'Archive.zip', 'Data.xlsx'][Math.floor(Math.random() * 5)],
760
+ path: ['Documents', 'Downloads', 'Pictures', 'Music', 'Videos'][Math.floor(Math.random() * 5)],
761
+ author: authors[Math.floor(Math.random() * authors.length)],
762
+ type: ['PDF Document', 'Word Document', 'Excel Spreadsheet', 'JPEG Image', 'ZIP Archive'][Math.floor(Math.random() * 5)],
763
+ size: Math.floor(Math.random() * 10000),
764
+ modified: new Date().toISOString(),
765
+ isFavorite: Math.random() > 0.8
766
+ };
767
+ newFiles.push(newFile);
768
+ }
769
+ state.set('files', newFiles);
770
+ }
771
+ }
772
+
773
+ function selectLocation(location) {
774
+ state.set('currentLocation', location);
775
+ state.set('searchQuery', '');
776
+ state.set('selectedFiles', []);
777
+ }
778
+
779
+ function sortBy(column) {
780
+ if (state.get('activeSort') === column) {
781
+ state.set('sortDirection', state.get('sortDirection') === 'asc' ? 'desc' : 'asc');
782
+ } else {
783
+ state.set('activeSort', column);
784
+ state.set('sortDirection', 'asc');
785
+ }
786
+ }
787
+
788
+ function toggleSelectAll(e) {
789
+ const allFiles = computedFilteredFiles();
790
+ if (e.target.checked) {
791
+ state.set('selectedFiles', [...allFiles]);
792
+ } else {
793
+ state.set('selectedFiles', []);
794
+ }
795
+ }
796
+
797
+ function toggleFileSelection(file, e) {
798
+ const selected = [...state.get('selectedFiles')];
799
+ if (e.target.checked) {
800
+ selected.push(file);
801
+ } else {
802
+ const index = selected.findIndex(f => f.id === file.id);
803
+ if (index !== -1) {
804
+ selected.splice(index, 1);
805
+ }
806
+ }
807
+ state.set('selectedFiles', selected);
808
+ }
809
+
810
+ function openFile(file) {
811
+ if (file.type === 'Folder') {
812
+ // Navigate to folder
813
+ const newLocation = {
814
+ id: Date.now(),
815
+ name: file.name,
816
+ icon: 'fas fa-folder'
817
+ };
818
+ state.set('currentLocation', newLocation);
819
+ state.set('selectedFiles', []);
820
+ } else {
821
+ // Open file (simulated)
822
+ alert(`Opening file: ${file.name}`);
823
+ }
824
+ }
825
+
826
+ function deleteSelectedFiles() {
827
+ const filesToDelete = [...state.get('selectedFiles')];
828
+ const currentFiles = [...state.get('files')];
829
+
830
+ const updatedFiles = currentFiles.filter(file =>
831
+ !filesToDelete.some(f => f.id === file.id)
832
+ );
833
+
834
+ state.set('files', updatedFiles);
835
+ state.set('selectedFiles', []);
836
+ state.set('showDeleteConfirm', false);
837
+
838
+ // Show success notification
839
+ alert(`Successfully deleted ${filesToDelete.length} file(s)`);
840
+ }
841
+
842
+ // Bind UI elements to state
843
+ const app = document.getElementById('app');
844
+
845
+ function render() {
846
+ const data = state.data;
847
+ const filteredLocations = computedFilteredLocations();
848
+ const filteredFiles = computedFilteredFiles();
849
+
850
+ // Sidebar search
851
+ app.querySelector('input[placeholder="Search locations..."]').value = data.sidebarSearch;
852
+
853
+ // Main search
854
+ app.querySelector('input[placeholder="Search files..."]').value = data.searchQuery;
855
+
856
+ // Sidebar locations
857
+ const sidebarLocations = app.querySelector('.flex-1.overflow-y-auto .p-2');
858
+ sidebarLocations.innerHTML = '';
859
+ filteredLocations.forEach(location => {
860
+ const locationEl = document.createElement('div');
861
+ locationEl.className = `sidebar-item px-3 py-2.5 rounded-lg cursor-pointer flex items-center transition-all group ${
862
+ data.currentLocation.id === location.id ? 'bg-indigo-50' : ''
863
+ }`;
864
+ locationEl.innerHTML = `
865
+ <div class="w-8 h-8 rounded-md flex items-center justify-center mr-2 ${
866
+ data.currentLocation.id === location.id ? 'bg-indigo-100' : 'bg-slate-100 group-hover:bg-slate-200'
867
+ }">
868
+ <i class="${location.icon} text-slate-600 group-hover:text-slate-800 ${
869
+ data.currentLocation.id === location.id ? 'text-indigo-500' : ''
870
+ }"></i>
871
+ </div>
872
+ <span class="text-sm font-medium truncate ${
873
+ data.currentLocation.id === location.id ? 'text-indigo-600' : 'text-slate-700 group-hover:text-slate-900'
874
+ }">
875
+ ${location.name}
876
+ </span>
877
+ `;
878
+ locationEl.addEventListener('click', () => selectLocation(location));
879
+ sidebarLocations.appendChild(locationEl);
880
+ });
881
+
882
+ // File list
883
+ const fileList = app.querySelector('.flex-1.overflow-y-auto.bg-white');
884
+ if (filteredFiles.length === 0) {
885
+ fileList.innerHTML = `
886
+ <div class="flex flex-col items-center justify-center h-64 text-slate-400">
887
+ <i class="fas fa-folder-open text-5xl mb-4 opacity-30"></i>
888
+ <p class="text-lg font-medium text-slate-500">No files found</p>
889
+ <p class="text-sm mt-1 text-slate-400">Try adjusting your search or filters</p>
890
+ </div>
891
+ `;
892
+ } else {
893
+ fileList.innerHTML = '';
894
+ filteredFiles.forEach(file => {
895
+ const fileEl = document.createElement('div');
896
+ fileEl.className = `file-row px-5 py-3 border-b border-slate-100 grid grid-cols-12 gap-4 text-sm items-center transition-all ${
897
+ data.selectedFiles.includes(file) ? 'highlight' : ''
898
+ }`;
899
+ fileEl.innerHTML = `
900
+ <div class="col-span-5 flex items-center truncate">
901
+ <input
902
+ type="checkbox"
903
+ class="mr-3 h-4 w-4 text-indigo-600 rounded border-slate-300 focus:ring-indigo-500"
904
+ ${data.selectedFiles.includes(file) ? 'checked' : ''}
905
+ >
906
+ <div class="w-8 h-8 rounded-md flex items-center justify-center mr-2 ${
907
+ data.selectedFiles.includes(file) ? 'bg-indigo-50' : 'bg-slate-100'
908
+ }">
909
+ <i class="${getFileIcon(file)} text-slate-600"></i>
910
+ </div>
911
+ <div class="truncate">
912
+ <div class="font-medium text-slate-800 truncate">${file.name}</div>
913
+ <div class="text-xs text-slate-500 truncate">${file.path || data.currentLocation.name}</div>
914
+ </div>
915
+ ${file.isFavorite ? '<i class="fas fa-star text-yellow-400 ml-2 text-xs"></i>' : ''}
916
+ </div>
917
+ <div class="col-span-2 text-slate-600 truncate">
918
+ <span class="inline-flex items-center">
919
+ <i class="fas fa-user-circle mr-2 text-slate-400"></i>
920
+ ${file.author || 'Unknown'}
921
+ </span>
922
+ </div>
923
+ <div class="col-span-2 text-slate-600 truncate text-sm">${file.type}</div>
924
+ <div class="col-span-2 text-slate-600 text-right text-sm">${formatFileSize(file.size)}</div>
925
+ <div class="col-span-1 text-slate-600 text-right text-sm">${formatDate(file.modified)}</div>
926
+ `;
927
+
928
+ // Add event listeners
929
+ const checkbox = fileEl.querySelector('input[type="checkbox"]');
930
+ checkbox.addEventListener('change', (e) => toggleFileSelection(file, e));
931
+
932
+ fileEl.addEventListener('dblclick', () => openFile(file));
933
+
934
+ fileList.appendChild(fileEl);
935
+ });
936
+ }
937
+
938
+ // Status bar
939
+ const statusBar = app.querySelector('.bg-slate-50.border-t.border-slate-200');
940
+ statusBar.innerHTML = `
941
+ <div>
942
+ <span class="${data.selectedFiles.length > 0 ? 'font-medium' : ''}">
943
+ ${data.selectedFiles.length > 0 ? `${data.selectedFiles.length} selected` : `${filteredFiles.length} items`}
944
+ </span>
945
+ </div>
946
+ <div class="flex items-center space-x-5">
947
+ <div class="flex items-center">
948
+ <span class="mr-2">Index status:</span>
949
+ ${data.isIndexing ? `
950
+ <span class="text-indigo-600 font-medium flex items-center">
951
+ <span class="w-2 h-2 rounded-full bg-indigo-500 mr-1.5 animate-pulse"></span>
952
+ Running
953
+ </span>
954
+ ` : '<span class="text-slate-400">Idle</span>'}
955
+ </div>
956
+ <div class="flex items-center">
957
+ <i class="fas fa-circle text-xs mr-1.5 ${
958
+ data.performanceRating === 'fast' ? 'text-emerald-500' :
959
+ data.performanceRating === 'normal' ? 'text-amber-500' : 'text-rose-500'
960
+ }"></i>
961
+ <span>${data.performanceRating} performance</span>
962
+ </div>
963
+ </div>
964
+ `;
965
+
966
+ // Select all checkbox
967
+ const selectAllCheckbox = app.querySelector('input[type="checkbox"][class*="mr-3 h-4 w-4"]');
968
+ selectAllCheckbox.checked = data.selectedFiles.length === filteredFiles.length && filteredFiles.length > 0;
969
+ selectAllCheckbox.addEventListener('change', toggleSelectAll);
970
+
971
+ // Advanced search panel
972
+ const advancedSearchPanel = app.querySelector('.bg-white.border-b.border-slate-200');
973
+ advancedSearchPanel.style.maxHeight = data.showAdvancedSearch ? '240px' : '0';
974
+
975
+ // Modal
976
+ const modal = app.querySelector('.fixed.inset-0');
977
+ if (data.showDeleteConfirm) {
978
+ modal.style.display = 'flex';
979
+ } else {
980
+ modal.style.display = 'none';
981
+ }
982
+ }
983
+
984
+ // Initialize event listeners
985
+ function initEventListeners() {
986
+ // Sidebar search
987
+ const sidebarSearch = app.querySelector('input[placeholder="Search locations..."]');
988
+ sidebarSearch.addEventListener('input', (e) => {
989
+ state.set('sidebarSearch', e.target.value);
990
+ });
991
+
992
+ // Main search
993
+ const mainSearch = app.querySelector('input[placeholder="Search files..."]');
994
+ mainSearch.addEventListener('input', (e) => {
995
+ state.set('searchQuery', e.target.value);
996
+ });
997
+
998
+ // Refresh button
999
+ const refreshBtn = app.querySelector('button:has(.fa-sync-alt)');
1000
+ refreshBtn.addEventListener('click', refreshFiles);
1001
+
1002
+ // Index button
1003
+ const indexBtn = app.querySelector('button:has(.fa-database)');
1004
+ indexBtn.addEventListener('click', toggleIndexing);
1005
+
1006
+ // Filters button
1007
+ const filtersBtn = app.querySelector('button:has(.fa-sliders-h)');
1008
+ filtersBtn.addEventListener('click', () => {
1009
+ state.set('showAdvancedSearch', !state.get('showAdvancedSearch'));
1010
+ });
1011
+
1012
+ // Delete confirmation modal buttons
1013
+ const modalCancelBtn = app.querySelector('.fixed.inset-0 button:first-of-type');
1014
+ const modalDeleteBtn = app.querySelector('.fixed.inset-0 button:last-of-type');
1015
+
1016
+ if (modalCancelBtn && modalDeleteBtn) {
1017
+ modalCancelBtn.addEventListener('click', () => {
1018
+ state.set('showDeleteConfirm', false);
1019
+ });
1020
+
1021
+ modalDeleteBtn.addEventListener('click', deleteSelectedFiles);
1022
+ }
1023
+ }
1024
+
1025
+ // Subscribe to state changes
1026
+ state.subscribe(render);
1027
+
1028
+ // Initial render
1029
+ render();
1030
+ initEventListeners();
1031
+ });
1032
+ </script>
1033
+ </body>
1034
  </html>