itsusony's picture
メール添付ファイルのマネージメントシステムを書いて。ファイルアプロードができて、リストもできる、パスワード入力もあるものを書いて。ログインページ入らない、ハッシュコードつきURLから入るから
8969ab9 verified
document.addEventListener('DOMContentLoaded', function() {
// Password section functionality
const passwordInput = document.getElementById('passwordInput');
const unlockBtn = document.getElementById('unlockBtn');
const passwordSection = document.getElementById('passwordSection');
const fileSection = document.getElementById('fileSection');
// Upload functionality
const uploadBtn = document.getElementById('uploadBtn');
const fileInput = document.getElementById('fileInput');
const fileList = document.getElementById('fileList');
// Sample files data (in a real app, this would come from an API)
let files = [];
// Check if we have a hash in URL (simulating hash-based access)
const urlHash = window.location.hash.substring(1);
if (urlHash) {
console.log('Vault accessed via hash:', urlHash);
// In a real app, you would validate this hash with your backend
}
// Unlock vault
unlockBtn.addEventListener('click', function() {
const password = passwordInput.value.trim();
if (!password) {
alert('Please enter a password');
return;
}
// In a real app, you would verify the password with your backend
// For demo purposes, we'll just check if any password was entered
passwordSection.classList.add('hidden');
fileSection.classList.remove('hidden');
// Load files (in a real app, this would be an API call)
loadFiles();
});
// Handle Enter key in password field
passwordInput.addEventListener('keyup', function(e) {
if (e.key === 'Enter') {
unlockBtn.click();
}
});
// Upload file
uploadBtn.addEventListener('click', function() {
fileInput.click();
});
fileInput.addEventListener('change', function(e) {
if (e.target.files.length > 0) {
const file = e.target.files[0];
uploadFile(file);
}
});
function uploadFile(file) {
// In a real app, you would upload to your server here
// For demo, we'll just add to the local list
const newFile = {
id: Date.now(),
name: file.name,
type: getFileType(file.name),
size: formatFileSize(file.size),
date: new Date().toLocaleDateString(),
file: file // Actual file object
};
files.unshift(newFile);
renderFiles();
// Reset file input
fileInput.value = '';
}
function loadFiles() {
// Simulate loading from API
setTimeout(() => {
// Sample files
files = [
{ id: 1, name: 'Project_Documentation.pdf', type: 'pdf', size: '2.4 MB', date: '2023-05-15' },
{ id: 2, name: 'Budget_2023.xlsx', type: 'sheet', size: '1.1 MB', date: '2023-04-22' },
{ id: 3, name: 'Team_Photo.jpg', type: 'image', size: '3.7 MB', date: '2023-03-10' },
{ id: 4, name: 'Backup_Archive.zip', type: 'zip', size: '45.2 MB', date: '2023-02-05' }
];
renderFiles();
}, 800);
}
function renderFiles() {
fileList.innerHTML = '';
if (files.length === 0) {
fileList.innerHTML = `
<div class="p-4 text-center text-gray-500">
<i data-feather="folder" class="w-12 h-12 mx-auto text-gray-400 mb-2"></i>
<p>No files in this vault yet</p>
</div>
`;
feather.replace();
return;
}
files.forEach(file => {
const fileItem = document.createElement('div');
fileItem.className = 'file-item px-4 py-3 hover:bg-gray-50 transition duration-150';
fileItem.innerHTML = `
<div class="grid grid-cols-12 gap-4 items-center">
<div class="col-span-6 flex items-center">
<i data-feather="${getFileIcon(file.type)}" class="mr-3 ${getFileTypeClass(file.type)}"></i>
<span class="truncate">${file.name}</span>
</div>
<div class="col-span-2 text-sm text-gray-500">${getFileTypeName(file.type)}</div>
<div class="col-span-2 text-sm text-gray-500">${file.size}</div>
<div class="col-span-2 flex justify-end space-x-2">
<button class="download-btn p-2 text-gray-500 hover:text-blue-600 rounded-full hover:bg-blue-50" data-id="${file.id}">
<i data-feather="download"></i>
</button>
<button class="delete-btn p-2 text-gray-500 hover:text-red-600 rounded-full hover:bg-red-50" data-id="${file.id}">
<i data-feather="trash-2"></i>
</button>
</div>
</div>
`;
fileList.appendChild(fileItem);
});
feather.replace();
// Add event listeners to buttons
document.querySelectorAll('.download-btn').forEach(btn => {
btn.addEventListener('click', function() {
const fileId = parseInt(this.getAttribute('data-id'));
downloadFile(fileId);
});
});
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.addEventListener('click', function() {
const fileId = parseInt(this.getAttribute('data-id'));
deleteFile(fileId);
});
});
}
function downloadFile(fileId) {
const file = files.find(f => f.id === fileId);
if (file) {
alert(`Downloading: ${file.name}\n\nIn a real app, this would download the file.`);
}
}
function deleteFile(fileId) {
if (confirm('Are you sure you want to delete this file?')) {
files = files.filter(f => f.id !== fileId);
renderFiles();
}
}
// Helper functions
function getFileType(filename) {
const extension = filename.split('.').pop().toLowerCase();
if (['pdf'].includes(extension)) return 'pdf';
if (['jpg', 'jpeg', 'png', 'gif', 'svg'].includes(extension)) return 'image';
if (['doc', 'docx'].includes(extension)) return 'doc';
if (['xls', 'xlsx'].includes(extension)) return 'sheet';
if (['ppt', 'pptx'].includes(extension)) return 'ppt';
if (['zip', 'rar', '7z'].includes(extension)) return 'zip';
return 'other';
}
function getFileIcon(type) {
const icons = {
'pdf': 'file-text',
'image': 'image',
'doc': 'file-text',
'sheet': 'file-text',
'ppt': 'file-text',
'zip': 'archive',
'other': 'file'
};
return icons[type] || 'file';
}
function getFileTypeClass(type) {
return `file-type-${type}`;
}
function getFileTypeName(type) {
const names = {
'pdf': 'PDF',
'image': 'Image',
'doc': 'Document',
'sheet': 'Spreadsheet',
'ppt': 'Presentation',
'zip': 'Archive',
'other': 'File'
};
return names[type] || 'File';
}
function formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
});