92 lines
2.7 KiB
TypeScript
92 lines
2.7 KiB
TypeScript
import "@shoelace-style/shoelace/dist/components/button/button.js";
|
|
import "@shoelace-style/shoelace/dist/components/details/details.js";
|
|
import "@shoelace-style/shoelace/dist/components/icon/icon.js";
|
|
import "@shoelace-style/shoelace/dist/components/input/input.js";
|
|
import "@shoelace-style/shoelace/dist/components/textarea/textarea.js";
|
|
|
|
import "./shoelace.js";
|
|
|
|
import "./camera.ts";
|
|
|
|
import CameraInput from "./camera.ts";
|
|
import SlButton from "@shoelace-style/shoelace/dist/components/button/button.js";
|
|
|
|
import { notify, notifyError } from "./alert";
|
|
import { getResponseError } from "./ajaxUtil.js";
|
|
|
|
const form = document.forms[0];
|
|
const cameraInput = form.querySelector("camera-input") as CameraInput;
|
|
const btnSubmit = form.querySelector("sl-button[type='submit']") as SlButton;
|
|
const btnUpload = form.querySelector(
|
|
"sl-button[class='choose-file']",
|
|
) as SlButton;
|
|
const inpImage = form.photo as HTMLInputElement;
|
|
const imgPreview = document.getElementById("upload-preview") as HTMLImageElement;
|
|
|
|
form.addEventListener("submit", async (evt) => {
|
|
evt.preventDefault();
|
|
btnSubmit.loading = true;
|
|
const data = new FormData(form);
|
|
if (!inpImage.files?.length) {
|
|
data.delete("photo");
|
|
const blob = await cameraInput.getBlob();
|
|
if (blob) {
|
|
data.append("photo", blob, "photo.jpg");
|
|
}
|
|
}
|
|
let r: Response;
|
|
try {
|
|
r = await fetch("", {
|
|
method: "POST",
|
|
body: data,
|
|
});
|
|
} catch (e) {
|
|
notifyError(`Failed to submit form: ${e}`);
|
|
return;
|
|
} finally {
|
|
btnSubmit.loading = false;
|
|
}
|
|
if (r.ok) {
|
|
notify("Successfully uploaded receipt", undefined, undefined, null);
|
|
window.location.href = "/receipts";
|
|
} else {
|
|
const err = await getResponseError(r);
|
|
notifyError(err);
|
|
}
|
|
});
|
|
|
|
cameraInput.addEventListener("ready", ((evt: CustomEvent) => {
|
|
btnSubmit.disabled = !evt.detail.hasPhoto;
|
|
btnUpload.disabled = !!evt.detail.hasPhoto;
|
|
if (!!evt.detail.hasPhoto) {
|
|
inpImage.value = "";
|
|
imgPreview.src = "";
|
|
}
|
|
}) as EventListener);
|
|
|
|
const cameraDetails = document.querySelector(
|
|
"sl-details[summary='Take Photo']",
|
|
)!;
|
|
let cameraInitialized = false;
|
|
cameraDetails.addEventListener("sl-show", () => {
|
|
if (!cameraInitialized) {
|
|
cameraInitialized = true;
|
|
cameraInput.startCamera();
|
|
}
|
|
});
|
|
|
|
btnUpload.addEventListener("click", (evt) => {
|
|
evt.preventDefault();
|
|
form.photo.showPicker();
|
|
});
|
|
|
|
inpImage.addEventListener("change", () => {
|
|
if (inpImage.files) {
|
|
const file = inpImage.files[0];
|
|
if (file) {
|
|
btnSubmit.disabled = false;
|
|
imgPreview.src = URL.createObjectURL(file);
|
|
}
|
|
}
|
|
});
|