Files
nanodrop/src/views/file-list.ts
Brendan Chen 5a47ae938e Fix four bugs and add logo/branding polish
- docker-compose: add register-user service (profiles: [tools]) with YAML anchor to avoid env duplication
- src/index.ts: show localhost instead of 0.0.0.0 in startup message
- file-view: render <img> inline for image/* MIME types
- file-list: add Copy link button per row (requires baseUrl param)
- layout: add hideLogo option; file view page hides the logo
- style.css: remove uppercase from .logo (Nanodrop not NANODROP), add button.copy-link styles, add .file-view img styles, widen last td

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-03 16:18:34 -08:00

43 lines
1.5 KiB
TypeScript

import { layout, escHtml } from './layout.ts';
import type { FileRow } from '../db/files.ts';
export function fileListPage(files: FileRow[], baseUrl: string): string {
const rows = files.length === 0
? '<tr><td colspan="5">No files yet. <a href="/upload">Upload one.</a></td></tr>'
: files.map((f) => {
const shareUrl = `${baseUrl}/f/${escHtml(f.id)}`;
return `
<tr>
<td><a href="/f/${escHtml(f.id)}">${escHtml(f.original_name)}</a></td>
<td>${escHtml(f.mime_type)}</td>
<td>${formatBytes(f.size)}</td>
<td>${escHtml(f.created_at)}</td>
<td>
<button class="copy-link" onclick="navigator.clipboard.writeText('${shareUrl}')">Copy link</button>
<form method="POST" action="/files/${escHtml(f.id)}/delete" style="display:inline">
<button type="submit" class="danger">Delete</button>
</form>
</td>
</tr>`;
}).join('');
return layout('My files', `
<h1>My files</h1>
<p><a href="/upload">Upload new file</a></p>
<table>
<thead>
<tr>
<th>Name</th><th>Type</th><th>Size</th><th>Uploaded</th><th></th>
</tr>
</thead>
<tbody>${rows}</tbody>
</table>
`, { authed: true });
}
function formatBytes(bytes: number): string {
if (bytes < 1024) return `${bytes} B`;
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}