Spaces:
Sleeping
Sleeping
File size: 11,239 Bytes
49d3082 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
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;
|