thejagstudio's picture
Upload 39 files
49d3082 verified
import { useEffect, useState } from "react";
import { useAtom } from "jotai";
import { VoiceAssistAtom, CurrentRollAtom, CurrentGRNAtom, TranscribeAtom, rollsAtom, grnsAtom, searchAtom } from "./Variables";
import { Routes, Route, useNavigate } from "react-router-dom";
import { CusNavbar } from "./Components/CusNavbar";
import RollCard from "./Components/RollCard";
import HomePage from "./Pages/HomePage";
import ErrorPage from "./Pages/ErrorPage";
import AddRollPage from "./Pages/AddRollPage";
import TranscribePage from "./Pages/TranscribePage";
import RollDetailPage from "./Pages/RollDetailPage";
import GRNCard from "./Components/GRNCard";
import GRNDetailPage from "./Pages/GRNDetailPage";
function App() {
const [search, setSearch] = useAtom(searchAtom);
const [rolls, setRolls] = useAtom(rollsAtom);
const [grns, setGrns] = useAtom(grnsAtom);
const [voiceAssist, setVoiceAssist] = useAtom(VoiceAssistAtom);
const [currentRoll, setCurrentRoll] = useAtom(CurrentRollAtom);
const [currentGRN, setCurrentGRN] = useAtom(CurrentGRNAtom);
const [transcribe, setTranscribe] = useAtom(TranscribeAtom);
const [sidebar, setSidebar] = useState(true);
const navigate = useNavigate();
useEffect(() => {
if (localStorage.getItem("currentGRN")) {
setCurrentGRN(JSON.parse(localStorage.getItem("currentGRN")));
}
fetch("/api/grns")
.then((res) => res.json())
.then((data) => {
setGrns(data["data"]);
voiceAssist.on(["open *", "grn *", "open grn *"], true).then((i, wildcard) => {
wildcard = wildcard.replace(/\s/g, "").replace(/-/g, "");
let found = false;
for (let index = 0; index < data["data"].length; index++) {
if (data["data"][index].GRN.toLowerCase() == wildcard.toLowerCase()) {
setCurrentGRN(data["data"][index]);
localStorage.setItem("currentGRN", JSON.stringify(data["data"][index]));
setTranscribe((prev) => [...prev.slice(0, -1), { msg: "open GRN " + wildcard, isCommand: true }]);
navigate("/grn");
found = true;
}
}
if (!found) {
voiceAssist.say("No GRN found with that Number");
}
});
})
.catch((err) => console.error(err));
voiceAssist.emptyCommands();
voiceAssist.on(["search *"], true).then((i, wildcard) => {
wildcard = wildcard.replace(/ /g, "");
setSearch(wildcard);
setTranscribe((prev) => [...prev.slice(0, -1), { msg: "search " + wildcard, isCommand: true }]);
});
voiceAssist.on(["transcribe"]).then((i) => {
setTranscribe((prev) => [...prev.slice(0, -1), { msg: "transcribe", isCommand: true }]);
navigate("/transcribe");
});
voiceAssist.on(["home", "go to home"]).then((i) => {
setTranscribe((prev) => [...prev.slice(0, -1), { msg: "home", isCommand: true }]);
navigate("/");
});
voiceAssist.on(["refresh"]).then((i) => {
window.location.reload();
});
voiceAssist.fatality();
setTimeout(() => {
voiceAssist
.initialize({
lang: "en-US",
continuous: true,
soundex: true,
debug: true,
executionKeyword: "and do it now",
listen: true,
name: "",
speed: 1.2,
// mode:"quick"
})
.then(() => {
console.log("Artyom has been succesfully initialized");
})
.catch((err) => {
console.error("Artyom couldn't be initialized: ", err);
});
}, 250);
voiceAssist.redirectRecognizedTextOutput((recognized, isFinal) => {
if (isFinal && recognized != "") {
setTranscribe((prev) => [...prev, { msg: recognized, isCommand: false }]);
}
});
}, []);
return (
<div className="flex flex-col h-screen w-full overflow-hidden relative">
{transcribe.length > 0 && (
<div className="z-50 max-w-[25%] absolute bottom-5 right-10 flex flex-col items-end gap-2">
{transcribe.map((item, index) => {
if (transcribe.length - index > 4) return null;
return (
<div key={index} className={"relative w-fit max-w-full text-white rounded-lg rounded-br-none p-3 px-4 transition-all duration-700 origin-bottom-right " + (item?.isCommand ? "bg-orange-500 " : "bg-primary-500 ")} style={{ opacity: transcribe.length - index < 4 ? 1.25 - (transcribe.length - index) * 0.25 : 0, transform: transcribe.length - index == 4 ? "translate(200px,0px)" : "scale(1)" }}>
<p>{item?.msg}</p>
<svg className={"absolute translate-x-1/2 translate-y-[2.5px] bottom-0 right-0 h-5 w-5 scale-x-150 " + (item?.isCommand ? "text-orange-500" : "text-primary-500")} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path fill="currentColor" d="M21 21H3l9-18Z" />
</svg>
</div>
);
})}
</div>
)}
<CusNavbar />
<div className="flex flex-row w-full h-[calc(100vh-4rem)] flex-nowrap items-center justify-between border-t border-primary-950">
<div className={"border-r border-primary-950 h-full p-5 relative px-0 transition-all " + (sidebar ? "w-[20%] min-w-64" : "w-0 ")}>
<svg
onClick={() => {
setSidebar(!sidebar);
}}
className={"absolute top-0 w-10 h-10 p-2 z-50 border border-t-0 border-primary-950 hover:bg-primary-100 cursor-pointer transition-all " + (sidebar ? "border-l-0 right-0 -scale-x-100" : "border-l-0 -right-10")}
viewBox="-0.2 0 1 1"
xmlns="http://www.w3.org/2000/svg"
>
<path d="m0.138 0.023 0.434 0.417 0.004 0.003c0.015 0.014 0.023 0.033 0.024 0.055l0 0.007c-0.001 0.02 -0.01 0.038 -0.027 0.054l0 0L0.138 0.977a0.082 0.082 0 0 1 -0.114 0 0.079 0.079 0 0 1 0 -0.114l0.376 -0.361L0.024 0.137a0.079 0.079 0 0 1 0 -0.114 0.082 0.082 0 0 1 0.114 0" fill="#1C1C1F" />
</svg>
<div className={"flex flex-col w-full h-full gap-3 transition-all origin-left " + (sidebar ? "" : "scale-x-0")}>
<div className="relative w-[calc(100%-2.5rem)] mx-auto h-10">
<div className="grid place-items-center absolute text-blue-gray-500 top-2/4 right-12 -translate-y-2/4 w-5 h-5">
<svg width={16} height={16} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path fill="currentColor" d="M21.71 20.29 18 16.61A9 9 0 1 0 16.61 18l3.68 3.68a1 1 0 0 0 1.42 0 1 1 0 0 0 0-1.39M11 18a7 7 0 1 1 7-7 7 7 0 0 1-7 7" />
</svg>
</div>
<input
onChange={(event) => {
setSearch(event.target.value);
}}
value={search}
className="peer w-[calc(100%-2.5rem)] h-full bg-transparent text-blue-gray-700 font-sans 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 placeholder-shown:border-blue-gray-200 placeholder-shown:border-t-blue-gray-200 border focus:border-2 border-t-transparent focus:border-t-transparent placeholder:opacity-0 focus:placeholder:opacity-100 text-sm px-3 py-2.5 rounded-[7px] !pr-9 border-blue-gray-200 focus:border-gray-900"
placeholder=" "
/>
<label className="flex w-[calc(100%-2.5rem)] h-full select-none pointer-events-none absolute left-0 font-normal !overflow-visible truncate peer-placeholder-shown:text-blue-gray-500 leading-tight peer-focus:leading-tight peer-disabled:text-transparent peer-disabled:peer-placeholder-shown:text-blue-gray-500 transition-all -top-1.5 peer-placeholder-shown:text-sm text-[11px] peer-focus:text-[11px] before:content[' '] before:block before:box-border before:w-2.5 before:h-1.5 before:mt-[6.5px] before:mr-1 peer-placeholder-shown:before:border-transparent before:rounded-tl-md before:border-t peer-focus:before:border-t-2 before:border-l peer-focus:before:border-l-2 before:pointer-events-none before:transition-all peer-disabled:before:border-transparent after:content[' '] after:block after:flex-grow after:box-border after:w-2.5 after:h-1.5 after:mt-[6.5px] after:ml-1 peer-placeholder-shown:after:border-transparent after:rounded-tr-md after:border-t peer-focus:after:border-t-2 after:border-r peer-focus:after:border-r-2 after:pointer-events-none after:transition-all peer-disabled:after:border-transparent peer-placeholder-shown:leading-[3.75] text-gray-500 peer-focus:text-gray-900 before:border-blue-gray-200 peer-focus:before:!border-gray-900 after:border-blue-gray-200 peer-focus:after:!border-gray-900">Search Roll No. </label>
</div>
<div className="w-full h-full flex flex-col gap-2 text-primary-700 overflow-y-scroll pl-6 py-5 px-5 noScrollBars">
{grns.map((grn, index) => {
if (search && !grn.supplierName.toLowerCase().includes(search.toLowerCase()) && !grn.buyer.toLowerCase().includes(search.toLowerCase()) && !grn.GRN.toLowerCase().includes(search.toLowerCase())) return null;
return <GRNCard key={index} GRN={grn} />;
})}
</div>
</div>
</div>
<div className={"border-r h-full overflow-y-auto custom-scrollbar " + (sidebar ? "w-[80%]" : "w-full")}>
<Routes>
<Route path="/" element={<HomePage />} />
{/* <Route path="/add-roll" element={<AddRollPage />} /> */}
<Route path="/roll" element={<RollDetailPage />} />
<Route path="/grn" element={<GRNDetailPage sidebar={sidebar} />} />
<Route path="/transcribe" element={<TranscribePage />} />
<Route path="*" element={<ErrorPage />} />
</Routes>
</div>
</div>
</div>
);
}
export default App;