Spaces:
Runtime error
Runtime error
| import React, { useState, useEffect } from "react"; | |
| import { VoiceAssistAtom, rollsAtom } from "../Variables"; | |
| import { useAtom } from "jotai"; | |
| function AddRollPage() { | |
| const [name, setName] = useState(""); | |
| const [client, setClient] = useState(""); | |
| const [stock, setStock] = useState(""); | |
| const [description, setDescription] = useState(""); | |
| const [image, setImage] = useState(null); | |
| const [success, setSuccess] = useState(null); | |
| const [error, setError] = useState(null); | |
| const [voiceAssist, setVoiceAssist] = useAtom(VoiceAssistAtom); | |
| const [rolls, setRolls] = useAtom(rollsAtom); | |
| useEffect(() => { | |
| voiceAssist.on(["roll number *", "role number * ", "roll no. *", "role no. *"], true).then((i, wildcard) => { | |
| setName(parseInt(wildcard)); | |
| }); | |
| voiceAssist.on(["client *"], true).then((i, wildcard) => { | |
| setClient(wildcard); | |
| }); | |
| voiceAssist.on(["stock *"], true).then((i, wildcard) => { | |
| setStock(parseInt(wildcard)); | |
| }); | |
| voiceAssist.on(["description *"], true).then((i, wildcard) => { | |
| setDescription(wildcard); | |
| }); | |
| voiceAssist.on(["submit"]).then((i) => { | |
| submitBtn.click(); | |
| }); | |
| }, []); | |
| return ( | |
| <div className="flex flex-col lg:flex-row gap-10 items-center justify-center w-full h-full"> | |
| <div className="max-w-80 w-[80%] mx-auto lg:mx-0 lg:w-auto"> | |
| <h4 className="font-semibold text-primary-900">Upload Image</h4> | |
| <div className="relative overflow-hidden bg-primary-200 hover:bg-primary-300/75 group/upload cursor-pointer border-2 border-dashed transition-all border-primary-900 rounded-lg w-full lg:w-64 h-16 lg:h-64 relativ flex flex-col items-center justify-center"> | |
| <input | |
| onChange={(event) => { | |
| let dataUri = URL.createObjectURL(event.target.files[0]); | |
| setImage(dataUri); | |
| }} | |
| id="sampleImage" | |
| type="file" | |
| allow=".png,.jpg,.jpeg" | |
| className="w-full h-full absolute top-0 left-0 opacity-0" | |
| /> | |
| {image === null ? ( | |
| <div> | |
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" className="w-32 h-32 text-primary-800 transition-all group-hover/upload:text-primary-700 " xmlSpace="preserve"> | |
| <path d="M22.414 23.586a2 2 0 1 1-2.828 2.828L18 24.828V29a2 2 0 0 1-4 0v-4.172l-1.586 1.586a2 2 0 1 1-2.828-2.828l5-5a2 2 0 0 1 2.828 0zM26 10A9 9 0 0 0 8.2 8.12 6 6 0 1 0 7 20h4.758l2.121-2.121A2.98 2.98 0 0 1 16 17c.802 0 1.555.312 2.121.879L20.242 20H26a5 5 0 0 0 0-10" fill="currentColor" /> | |
| </svg> | |
| <h6 className=" font-semibold text-primary-900 group-hover/upload:text-primary-800 transition-all -mb-3">Upload Image</h6> | |
| </div> | |
| ) : ( | |
| <img src={image} className="w-full h-full object-cover"></img> | |
| )} | |
| </div> | |
| </div> | |
| <div className="relative flex flex-col bg-clip-border rounded-xl bg-transparent text-primary-700 shadow-none"> | |
| <h4 className="text-xl font-semibold text-primary-900 lg:w-full w-[80%] lg:mx-0 mx-auto">Add New Roll</h4> | |
| <p className="text-primary-700 mt-1 font-normal lg:w-full w-[80%] lg:mx-0 mx-auto">Please fill in the form to register a new roll.</p> | |
| {success && ( | |
| <div role="alert" className="relative w-full text-base font-regular px-4 py-4 mt-3 rounded-none border-l-4 border-green-600 bg-green-600/10 font-medium text-green-600 flex" style={{ opacity: 1 }}> | |
| <div className="shrink-0"> | |
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className="h-6 w-6"> | |
| <path fillRule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm13.36-1.814a.75.75 0 10-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 00-1.06 1.06l2.25 2.25a.75.75 0 001.14-.094l3.75-5.25z" clipRule="evenodd" /> | |
| </svg> | |
| </div> | |
| <div className="ml-3 mr-12 truncate" id="successMsg"> | |
| {success} | |
| </div> | |
| </div> | |
| )} | |
| {error && ( | |
| <div role="alert" className="relative w-full text-base font-regular px-4 py-4 mt-3 rounded-none border-l-4 border-red-500 bg-red-500/10 font-medium text-red-500 flex" style={{ opacity: 1 }}> | |
| <div className="shrink-0"> | |
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className="h-6 w-6"> | |
| <path fillRule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm13.36-1.814a.75.75 0 10-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 00-1.06 1.06l2.25 2.25a.75.75 0 001.14-.094l3.75-5.25z" clipRule="evenodd" /> | |
| </svg> | |
| </div> | |
| <div className="ml-3 mr-12 truncate" id="errorMsg"> | |
| {error} | |
| </div> | |
| </div> | |
| )} | |
| <div className="mt-8 mb-2 max-w-80 lg:w-full w-[80%] lg:mx-0 mx-auto"> | |
| <div className="mb-1 flex flex-col gap-3"> | |
| <h6 className=" font-semibold text-primary-900">Roll No.</h6> | |
| <input | |
| onChange={(event) => { | |
| setName(event.target.value); | |
| }} | |
| value={name} | |
| placeholder={123} | |
| type="number" | |
| className="w-full h-11 bg-transparent text-primary-700 font-normal outline outline-0 focus:outline-0 disabled:bg-blue-gray-50 disabled:border-0 disabled:cursor-not-allowed transition-all placeholder-shown:border border focus:border-2 border-t-transparent focus:border-t-transparent text-sm px-3 py-3 rounded-md border-blue-gray-200 focus:border-gray-900 !border-t-blue-gray-200 focus:!border-t-gray-900" | |
| /> | |
| <h6 className=" font-semibold text-primary-900">Client</h6> | |
| <input | |
| onChange={(event) => { | |
| setClient(event.target.value); | |
| }} | |
| value={client} | |
| placeholder="Sahi" | |
| className="w-full h-11 bg-transparent text-primary-700 font-normal outline outline-0 focus:outline-0 disabled:bg-blue-gray-50 disabled:border-0 disabled:cursor-not-allowed transition-all placeholder-shown:border border focus:border-2 border-t-transparent focus:border-t-transparent text-sm px-3 py-3 rounded-md border-blue-gray-200 focus:border-gray-900 !border-t-blue-gray-200 focus:!border-t-gray-900" | |
| /> | |
| <h6 className=" font-semibold text-primary-900">Stock</h6> | |
| <input | |
| onChange={(event) => { | |
| setStock(event.target.value); | |
| }} | |
| value={stock} | |
| placeholder={10} | |
| type="number" | |
| className="w-full h-11 bg-transparent text-primary-700 font-normal outline outline-0 focus:outline-0 disabled:bg-blue-gray-50 disabled:border-0 disabled:cursor-not-allowed transition-all placeholder-shown:border border focus:border-2 border-t-transparent focus:border-t-transparent text-sm px-3 py-3 rounded-md border-blue-gray-200 focus:border-gray-900 !border-t-blue-gray-200 focus:!border-t-gray-900" | |
| /> | |
| <h6 className=" font-semibold text-primary-900">Description</h6> | |
| <input | |
| onChange={(event) => { | |
| setDescription(event.target.value); | |
| }} | |
| value={description} | |
| placeholder="Plain white Fabric" | |
| className="w-full h-11 bg-transparent text-primary-700 font-normal outline outline-0 focus:outline-0 disabled:bg-blue-gray-50 disabled:border-0 disabled:cursor-not-allowed transition-all placeholder-shown:border border focus:border-2 border-t-transparent focus:border-t-transparent text-sm px-3 py-3 rounded-md border-blue-gray-200 focus:border-gray-900 !border-t-blue-gray-200 focus:!border-t-gray-900" | |
| /> | |
| </div> | |
| <button | |
| id="submitBtn" | |
| onClick={() => { | |
| console.log(name, client, stock); | |
| if (!name || !client || !stock || !description || !image) { | |
| setError("Please fill all the fields"); | |
| setTimeout(() => { | |
| setError(null); | |
| }, 3000); | |
| return; | |
| } | |
| let sampleImage = document.getElementById("sampleImage"); | |
| let imageFile = sampleImage.files[0]; | |
| let data = new FormData(); | |
| data.append("name", name); | |
| data.append("client", client); | |
| data.append("stock", stock); | |
| data.append("description", description); | |
| data.append("image", imageFile); | |
| fetch("/api/rollEntry", { | |
| method: "POST", | |
| body: data, | |
| }) | |
| .then((response) => response.json()) | |
| .then((data) => { | |
| if (data.status === "success") { | |
| setClient(""); | |
| setName(""); | |
| setStock(""); | |
| setDescription(""); | |
| setImage(null); | |
| setSuccess(data.msg); | |
| setTimeout(() => { | |
| setSuccess(null); | |
| }, 3000); | |
| fetch("/api/rolls") | |
| .then((res) => res.json()) | |
| .then((data) => { | |
| setRolls(data["data"]); | |
| }) | |
| .catch((err) => console.error(err)); | |
| } else { | |
| setError(data.msg); | |
| setTimeout(() => { | |
| setError(null); | |
| }, 3000); | |
| voiceAssist.say(data.msg); | |
| } | |
| }) | |
| .catch((error) => console.error("Error:", error)); | |
| }} | |
| className="align-middle select-none font-sans font-bold text-center uppercase transition-all disabled:opacity-50 disabled:shadow-none disabled:pointer-events-none text-xs py-3 px-6 rounded-lg bg-gradient-to-tr from-primary-950 to-primary-800 text-white shadow-md shadow-gray-900/10 hover:shadow-lg hover:shadow-gray-900/20 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none block w-full mt-6" | |
| type="button" | |
| > | |
| Submit | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } | |
| export default AddRollPage; | |