fix: a tiny bit better upload ui
This commit is contained in:
parent
0d2a73b508
commit
6b097e0860
|
@ -174,13 +174,6 @@ export const GeneralLayout = ({ children }: React.PropsWithChildren) => {
|
||||||
</PinningProvider>
|
</PinningProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const UploadFormSchema = z.object({
|
|
||||||
uppyFiles: z.array(z.any()).min(1, {
|
|
||||||
message: "At least one file must be uploaded",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const UploadFileForm = () => {
|
const UploadFileForm = () => {
|
||||||
const {
|
const {
|
||||||
getRootProps,
|
getRootProps,
|
||||||
|
@ -193,44 +186,21 @@ const UploadFileForm = () => {
|
||||||
upload,
|
upload,
|
||||||
} = useUppy();
|
} = useUppy();
|
||||||
|
|
||||||
const [form, fields] = useForm({
|
|
||||||
constraint: getZodConstraint(UploadFormSchema),
|
|
||||||
shouldValidate: "onInput",
|
|
||||||
onValidate: ({ formData }) => {
|
|
||||||
const result = parseWithZod(formData, {
|
|
||||||
schema: UploadFormSchema,
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
onSubmit: (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
return upload();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const inputProps = getInputProps();
|
const inputProps = getInputProps();
|
||||||
const files = useInputControl({
|
|
||||||
key: fields.uppyFiles.key,
|
|
||||||
name: fields.uppyFiles.name,
|
|
||||||
formId: form.id
|
|
||||||
});
|
|
||||||
|
|
||||||
const isUploading = state === "uploading";
|
const isUploading = state === "uploading";
|
||||||
const isCompleted = state === "completed";
|
const isCompleted = state === "completed";
|
||||||
const hasErrored = state === "error";
|
const hasErrored = state === "error";
|
||||||
const hasStarted = state !== "idle" && state !== "initializing";
|
const hasStarted = state !== "idle" && state !== "initializing";
|
||||||
const isValid = form.valid || getFiles().length > 0;
|
const isValid = getFiles().length > 0;
|
||||||
const getFailedState = (id: string) =>
|
const getFailedState = (id: string) =>
|
||||||
failedFiles.find((file) => file.id === id);
|
failedFiles.find((file) => file.id === id);
|
||||||
|
|
||||||
console.log({ files: getFiles() });
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DialogHeader className="mb-6">
|
<DialogHeader className="mb-6">
|
||||||
<DialogTitle>Upload Files</DialogTitle>
|
<DialogTitle>Upload Files</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<Form {...getFormProps(form)} className="flex flex-col">
|
|
||||||
{!hasStarted ? (
|
{!hasStarted ? (
|
||||||
<div
|
<div
|
||||||
{...getRootProps()}
|
{...getRootProps()}
|
||||||
|
@ -240,13 +210,8 @@ const UploadFileForm = () => {
|
||||||
aria-hidden
|
aria-hidden
|
||||||
key={new Date().toISOString()}
|
key={new Date().toISOString()}
|
||||||
multiple
|
multiple
|
||||||
name={fields.uppyFiles.name}
|
name="uppyFiles[]"
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
value={files.value}
|
|
||||||
onChange={() => {
|
|
||||||
//@ts-expect-error -- conform has shitty typeinference for controls
|
|
||||||
files.change(getFiles());
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<CloudUploadIcon className="w-24 h-24 stroke stroke-primary-dark" />
|
<CloudUploadIcon className="w-24 h-24 stroke stroke-primary-dark" />
|
||||||
<p>Drag & Drop Files or Browse</p>
|
<p>Drag & Drop Files or Browse</p>
|
||||||
|
@ -268,7 +233,6 @@ const UploadFileForm = () => {
|
||||||
|
|
||||||
<ErrorList
|
<ErrorList
|
||||||
errors={[
|
errors={[
|
||||||
...(fields.uppyFiles.errors ?? []),
|
|
||||||
...(hasErrored ? ["An error occurred"] : []),
|
...(hasErrored ? ["An error occurred"] : []),
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
@ -302,12 +266,12 @@ const UploadFileForm = () => {
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
size={"lg"}
|
size={"lg"}
|
||||||
|
onClick={isValid ? upload : () => {}}
|
||||||
className="mt-6"
|
className="mt-6"
|
||||||
disabled={!isValid}>
|
disabled={!isValid}>
|
||||||
Upload
|
Upload
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
</Form>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -57,14 +57,12 @@ export function useUppy() {
|
||||||
"completed" | "idle" | "initializing" | "error" | "uploading"
|
"completed" | "idle" | "initializing" | "error" | "uploading"
|
||||||
>("initializing");
|
>("initializing");
|
||||||
|
|
||||||
const [inputProps, setInputProps] = useState<
|
const [inputProps, setInputProps] = useState<{
|
||||||
| {
|
|
||||||
ref: typeof inputRef;
|
ref: typeof inputRef;
|
||||||
type: "file";
|
type: "file";
|
||||||
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
|
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
|
||||||
}
|
}
|
||||||
| object
|
>();
|
||||||
>({});
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const [failedFiles, setFailedFiles] = useState<FailedUppyFile<Record<string, any>, Record<string, any>>[]>([])
|
const [failedFiles, setFailedFiles] = useState<FailedUppyFile<Record<string, any>, Record<string, any>>[]>([])
|
||||||
const getRootProps = useMemo(
|
const getRootProps = useMemo(
|
||||||
|
@ -76,7 +74,6 @@ export function useUppy() {
|
||||||
//@ts-expect-error -- dumb html
|
//@ts-expect-error -- dumb html
|
||||||
inputRef.current.value = null;
|
inputRef.current.value = null;
|
||||||
inputRef.current.click();
|
inputRef.current.click();
|
||||||
console.log("clicked", { input: inputRef.current });
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
role: "presentation",
|
role: "presentation",
|
||||||
|
|
Loading…
Reference in New Issue