Displaying file info

The list doesn’t look very good. Let’s add some more stuff — the file icon from Lucide, a link to a details page, and date and size information:

<div role="listitem">
	<div class="file">
		<FileIcon />

		<a href="" class="name">{f.name}</a>

		<span class="date">{f.created_at}</span>
		<span class="size">{f.size}</span>
	</div>
</div>

Still doesn’t look great! Fix the CSS:

.file {
	display: flex;
	height: 2.5rem;
	align-items: center;
	gap: 0.5rem;
	padding: 0 0.5rem;
	user-select: none;

	&:hover {
		background: rgb(255 255 255 / 0.4);
	}

	.name {
		display: flex;
		align-items: center;
		flex: 1;
		text-wrap: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
		width: 0;
		height: 100%;
	}

	a {
		text-decoration: none;
		padding: 0 0.5rem;

		&:hover {
			text-decoration: underline;
		}
	}
}

Add a src/lib/utils.ts file, and use ago(f.created_at, new Date()) in the template:

const ONE_SECOND = 1000;
const ONE_MINUTE = 60 * ONE_SECOND;
const ONE_HOUR = 60 * ONE_MINUTE;
const ONE_DAY = 24 * ONE_HOUR;
const ONE_WEEK = 7 * ONE_DAY;
const ONE_YEAR = 365 * ONE_DAY;
const ONE_MONTH = ONE_YEAR / 12;

export function timeago(date: Date, now: Date) {
	const elapsed = now.getTime() - date.getTime();

	if (elapsed < ONE_MINUTE) {
		return 'just now';
	}

	if (elapsed < ONE_HOUR) {
		return pluralise('minute', Math.floor(elapsed / ONE_MINUTE));
	}

	if (elapsed < ONE_DAY) {
		return pluralise('hour', Math.floor(elapsed / ONE_HOUR));
	}

	if (elapsed < ONE_WEEK) {
		return pluralise('day', Math.floor(elapsed / ONE_DAY));
	}

	if (elapsed < ONE_MONTH) {
		return pluralise('week', Math.floor(elapsed / ONE_WEEK));
	}

	if (elapsed < ONE_YEAR) {
		return pluralise('month', Math.floor(elapsed / ONE_MONTH));
	}

	return pluralise('year', Math.floor(elapsed / ONE_YEAR));
}

function pluralise(word: string, count: number) {
	return `${count} ${count === 1 ? word : word + 's'} ago`;
}

For the size, install pretty-bytes and use it in the template:

pnpm add pretty-bytes

Add a couple more styles:

.date {
	width: 8rem;
}

.size {
	width: 4rem;
}