feat(web): redesign frontend UI with modern card layout, drag-drop upload, toast notifications, and responsive design

This commit is contained in:
2026-08-27 00:04:03 +08:00
parent 877e92cb24
commit cef31b9248
4 changed files with 498 additions and 47 deletions
+40 -9
View File
@@ -2,6 +2,8 @@ function app() {
return {
inboxFiles: [],
outboxFiles: [],
dragover: false,
toast: { show: false, message: '' },
async loadFiles() {
const [inbox, outbox] = await Promise.all([
fetch('/api/files?dir=inbox').then(r => r.json()),
@@ -10,28 +12,57 @@ function app() {
this.inboxFiles = inbox.files || [];
this.outboxFiles = outbox.files || [];
},
showToast(msg) {
this.toast.message = msg;
this.toast.show = true;
setTimeout(() => { this.toast.show = false; }, 2500);
},
async upload(event, dir) {
const file = event.target.files[0];
const form = new FormData();
form.append('file', file);
form.append('dir', dir);
await fetch('/api/upload', {method: 'POST', body: form});
const files = event.target.files;
if (!files || !files.length) return;
for (const file of files) {
const form = new FormData();
form.append('file', file);
form.append('dir', dir);
await fetch('/api/upload', { method: 'POST', body: form });
}
event.target.value = '';
this.showToast('File uploaded');
this.loadFiles();
},
async uploadDropped(event, dir) {
const files = event.dataTransfer.files;
if (!files || !files.length) return;
for (const file of files) {
const form = new FormData();
form.append('file', file);
form.append('dir', dir);
await fetch('/api/upload', { method: 'POST', body: form });
}
this.showToast('File uploaded');
this.loadFiles();
},
download(id) {
window.location.href = '/api/files/' + id + '/download';
},
async deleteFile(id) {
await fetch('/api/files/' + id, {method: 'DELETE'});
if (!confirm('Delete this file?')) return;
await fetch('/api/files/' + id, { method: 'DELETE' });
this.showToast('File deleted');
this.loadFiles();
},
async share(id) {
const res = await fetch('/api/files/' + id + '/share', {method: 'POST'});
const res = await fetch('/api/files/' + id + '/share', { method: 'POST' });
const data = await res.json();
alert('Share URL: ' + data.url);
try {
await navigator.clipboard.writeText(data.url);
this.showToast('Share link copied to clipboard');
} catch (_) {
alert('Share URL: ' + data.url);
}
},
async logout() {
await fetch('/api/logout', {method: 'POST'});
await fetch('/api/logout', { method: 'POST' });
window.location.href = '/login';
}
};