Add file preview component and enhance file size formatting in dashboard

This commit is contained in:
grngxd 2025-06-21 22:37:32 +01:00
parent 3217373024
commit f843155394

View file

@ -1,4 +1,4 @@
import { component$, Signal, useVisibleTask$ } from "@builder.io/qwik"; import { component$, Signal, useSignal, useTask$, useVisibleTask$ } from "@builder.io/qwik";
import { routeLoader$, type DocumentHead } from "@builder.io/qwik-city"; import { routeLoader$, type DocumentHead } from "@builder.io/qwik-city";
import OSBar from "~/components/dashboard/OSBar"; import OSBar from "~/components/dashboard/OSBar";
import TitleBar from "~/components/dashboard/TitleBar"; import TitleBar from "~/components/dashboard/TitleBar";
@ -34,6 +34,13 @@ export default component$(() => {
); );
}); });
const formatSize = (bytes: number) => {
if (bytes < 1024) return `${bytes} B`;
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
}
const Files = component$<{ const Files = component$<{
files: Signal<StereoFile[]>; files: Signal<StereoFile[]>;
loaded: Signal<boolean>; loaded: Signal<boolean>;
@ -41,9 +48,89 @@ const Files = component$<{
}>(({ files, loaded }) => { }>(({ files, loaded }) => {
const File = component$(({ file }: { file: StereoFile }) => { const File = component$(({ file }: { file: StereoFile }) => {
const Preview = component$(() => {
type FileType =
| "image"
| "video"
| "audio"
| "other";
const fileType: Signal<FileType> = useSignal<FileType>("other");
const type = file.Mime.split("/")[1];
useTask$(async () => {
if (
["jpeg", "jpg", "png", "gif", "webp"]
.includes(type)
) fileType.value = "image";
else if (
["mp4", "webm", "ogg", "avi", "mov"]
.includes(type)
) fileType.value = "video";
else if (
["mp3", "wav", "flac", "aac"]
.includes(type)
) fileType.value = "audio";
else fileType.value = "other";
});
return ( return (
<div class="bg-stereo/15 h-84 rounded-3xl flex items-center justify-center"> <div class="w-full h-60 object-cover flex-grow relative">
{file.Name} {fileType.value === "image" && (
<img
width={400}
height={300}
src={`/api/${file.ID}`}
alt={file.Name}
class="w-full h-60 object-cover flex-grow"
/>
)}
{fileType.value === "video" && (
<video
width={400}
height={300}
src={`/api/${file.ID}`}
controls
class="w-full h-60 object-cover flex-grow"
/>
)}
{fileType.value === "audio" && (
<audio
src={`/api/${file.ID}`}
controls
class="w-full h-60 object-cover flex-grow"
/>
)}
{fileType.value === "other" && (
<div class="w-full h-60 flex items-center justify-center bg-gray-200 text-gray-500">
<p>Unsupported file type</p>
</div>
)}
</div>
)
})
return (
<div style={{
background: "linear-gradient(180deg, rgba(255, 38, 78, 0.00) 57.21%, rgba(255, 38, 78, 0.17) 100%); ",
boxShadow: "0px 4px 21.2px 2px rgba(255, 38, 78, 0.05)",
}} class="transition-all rounded-3xl flex flex-col overflow-clip items-center justify-center">
<Preview />
<div class="flex flex-col items-center justify-center text-center w-full h-full p-5">
<p class="text-xl">{file.Name}</p>
<p class="text-stereo/50 text-lg">
{formatSize(file.Size)}
<span class="text-stereo/40"> </span>
Uploaded on {new Date(file.CreatedAt).toLocaleDateString()}
</p>
</div>
</div> </div>
) )
}) })