9e1ed2c9cb
Hop-State: A_06FPAF0M83E7T0JJ7EP2WQ0 Hop-Proposal: R_06FPAF04S0D4G8TA8TNK3C0 Hop-Task: T_06FPADTV2YD4PD5GMTK3150 Hop-Attempt: AT_06FPADTV2ZYKEY8GH3JTK98
65 lines
1.9 KiB
TypeScript
65 lines
1.9 KiB
TypeScript
import type { ChangeEvent } from "react";
|
|
import {
|
|
useStuffboxUpload,
|
|
type UploadTransport,
|
|
} from "@stuffbox/sdk/react";
|
|
|
|
async function responseJson<T>(response: Response): Promise<T> {
|
|
if (!response.ok) {
|
|
throw new Error(`Upload endpoint failed with status ${response.status}`);
|
|
}
|
|
return response.json() as Promise<T>;
|
|
}
|
|
|
|
export const uploadTransport: UploadTransport = {
|
|
async createUpload(input, options) {
|
|
const response = await fetch("/api/stuffbox/uploads", {
|
|
method: "POST",
|
|
headers: { "content-type": "application/json" },
|
|
body: JSON.stringify(input),
|
|
...(options?.signal ? { signal: options.signal } : {}),
|
|
});
|
|
return responseJson(response);
|
|
},
|
|
|
|
async completeUpload(uploadId, input, options) {
|
|
const response = await fetch(`/api/stuffbox/uploads/${uploadId}/complete`, {
|
|
method: "POST",
|
|
headers: { "content-type": "application/json" },
|
|
body: JSON.stringify(input ?? {}),
|
|
...(options?.signal ? { signal: options.signal } : {}),
|
|
});
|
|
return responseJson(response);
|
|
},
|
|
};
|
|
|
|
export function StuffboxUploadButton() {
|
|
const { state, upload, abort, reset } = useStuffboxUpload(uploadTransport);
|
|
|
|
function chooseFile(event: ChangeEvent<HTMLInputElement>) {
|
|
const file = event.currentTarget.files?.[0];
|
|
if (file) void upload(file).catch(() => undefined);
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<input type="file" onChange={chooseFile} disabled={state.status === "uploading"} />
|
|
|
|
{state.status === "uploading" && (
|
|
<button type="button" onClick={abort}>
|
|
Cancel upload ({Math.round(state.progress.percent)}%)
|
|
</button>
|
|
)}
|
|
|
|
{state.status === "complete" && (
|
|
<p>
|
|
Uploaded <a href={state.asset.url}>{state.asset.filename}</a>{" "}
|
|
<button type="button" onClick={reset}>Upload another</button>
|
|
</p>
|
|
)}
|
|
|
|
{state.status === "error" && <p role="alert">{state.error.message}</p>}
|
|
</div>
|
|
);
|
|
}
|