half broken dropzone component to be used later fr

This commit is contained in:
grngxd 2025-06-10 01:19:27 +01:00
parent 39005e75e0
commit 7be62fcbb2
4 changed files with 99 additions and 3 deletions

View file

@ -0,0 +1,62 @@
import { component$, useVisibleTask$ } from "@builder.io/qwik";
import { useDropzone } from "~/hooks/dropzone";
import { useNanostore$ } from "~/hooks/nanostores";
import { api } from "~/lib/api";
import { dashboardFiles } from "~/lib/stores";
import { StereoFile } from "~/lib/types";
export default component$(() => {
const dashfiles = useNanostore$<StereoFile[]>(dashboardFiles);
const {
highlight,
onDragOver,
onDragLeave,
onInputChange,
triggerFileInput,
fileInputRef,
} = useDropzone();
useVisibleTask$(() => {
const dropzone = document.getElementById("dropzone");
if (!dropzone) return;
const handler = async (e: DragEvent) => {
e.preventDefault();
highlight.value = false;
const files = Array.from(e.dataTransfer?.files || []);
for (const file of files) {
const name = file.name.replace(/[^a-zA-Z0-9_.-]/g, "_");
const f = new File([file], name, { type: file.type });
await api.upload(f);
dashfiles.value = await api.list();
}
};
dropzone.addEventListener("drop", handler);
return () => dropzone.removeEventListener("drop", handler);
});
return (
<div
id="dropzone"
preventdefault:drop
class={{
"relative z-10 border-2 border-dashed rounded-lg p-10 transition-colors": true,
"border-white bg-black/20": highlight.value,
"border-neutral-800": !highlight.value,
}}
onDragOver$={onDragOver}
onDragLeave$={onDragLeave}
onClick$={triggerFileInput}
>
<p class="text-center text-neutral-500 pointer-events-none">drop file ehre</p>
<input
type="file"
ref={fileInputRef}
multiple
accept="image/*"
class="hidden"
onChange$={onInputChange}
/>
</div>
);
});

View file

@ -65,14 +65,18 @@ export default component$(({ file }: FileProps) => {
return (
<div class="rounded-xl bg-neutral-900 flex flex-col group overflow-hidden hover:bg-neutral-800 transition-all duration-200">
<div class="relative">
<a href={`/api/${file.Owner}/${file.Name}`} target="_blank">
<a
href={`/api/${file.Owner}/${file.Name}`}
target="_blank"
class="block w-full h-60 overflow-clip"
>
{ (file.Name.endsWith(".png") || file.Name.endsWith(".jpg") || file.Name.endsWith(".jpeg")) && (
<img
width={400}
height={300}
src={`/api/${file.Owner}/${file.Name}`}
alt={file.Name}
class="w-full h-60 object-cover bg-neutral-800 flex-grow"
class="w-full h-60 object-cover bg-neutral-800 flex-grow group-hover:scale-110 group-hover:saturate-150 transition-all duration-500"
/>
)}
</a>

28
src/hooks/dropzone.tsx Normal file
View file

@ -0,0 +1,28 @@
import { $, useSignal } from '@builder.io/qwik';
export const useDropzone = () => {
const highlight = useSignal(false);
const onInputChange = $(async (e: Event) => {
e.preventDefault();
});
const fileInputRef = useSignal<HTMLInputElement | undefined>(undefined);
return {
highlight,
onDragOver: $((e: DragEvent) => {
e.preventDefault();
highlight.value = true;
}),
onDragLeave: $((e: DragEvent) => {
e.preventDefault();
highlight.value = false;
}),
onInputChange,
triggerFileInput: $(() => {
fileInputRef.value?.click();
}),
fileInputRef,
};
}

View file

@ -1,6 +1,7 @@
import { component$, useVisibleTask$ } from "@builder.io/qwik";
import { routeLoader$, type DocumentHead } from "@builder.io/qwik-city";
import Controlbar from "~/components/Controlbar";
// import Dropzone from "~/components/Dropzone";
import File from "~/components/File";
import { SolarUploadLinear, SvgSpinnersBarsRotateFade } from "~/components/Icons";
import { useNanostore$ } from "~/hooks/nanostores";
@ -28,6 +29,7 @@ export default component$(() => {
return (
<>
{/* <Dropzone /> */}
<Controlbar />
{!loaded.value ? (
<div class="absolute w-full h-screen flex justify-center items-center flex-col">
@ -44,7 +46,7 @@ export default component$(() => {
</div>
)
: (
<div class="grid grid-cols-4 gap-4 p-4 mb-18">
<div class="grid grid-cols-4 gap-4 p-4 mb-16">
{files.value.map((file) => (
<File key={file.Name} file={file} />
))}