diff --git a/Govt-Billing-React/src/components/Menu/Menu.tsx b/Govt-Billing-React/src/components/Menu/Menu.tsx index 392becf..a7fe88b 100644 --- a/Govt-Billing-React/src/components/Menu/Menu.tsx +++ b/Govt-Billing-React/src/components/Menu/Menu.tsx @@ -22,7 +22,7 @@ const Menu: React.FC<{ const [showAlert4, setShowAlert4] = useState(false); const [showToast1, setShowToast1] = useState(false); const [toastMessage, setToastMessage] = useState(""); - /* Utility functions */ + const _validateName = async (filename) => { filename = filename.trim(); if (filename === "default" || filename === "Untitled") { @@ -49,7 +49,6 @@ const Menu: React.FC<{ }; const _formatString = (filename) => { - /* Remove whitespaces */ while (filename.indexOf(" ") !== -1) { filename = filename.replace(" ", ""); } @@ -62,39 +61,43 @@ const Menu: React.FC<{ printer.print(AppGeneral.getCurrentHTMLContent()); } else { const content = AppGeneral.getCurrentHTMLContent(); - // useReactToPrint({ content: () => content }); const printWindow = window.open("/printwindow", "Print Invoice"); printWindow.document.write(content); printWindow.print(); } }; - const doSave = () => { + + const doSave = async () => { if (props.file === "default") { setShowAlert1(true); return; } + const content = encodeURIComponent(AppGeneral.getSpreadsheetContent()); - const data = props.store._getFile(props.file); + + const existingData = await props.store._getFile(props.file); + + + const createdTimestamp = + existingData?.created ?? new Date().toString(); + const file = new File( - (data as any).created, - new Date().toString(), + createdTimestamp, + new Date().toString(), content, props.file, props.bT ); + props.store._saveFile(file); props.updateSelectedFile(props.file); setShowAlert2(true); }; const doSaveAs = async (filename) => { - // event.preventDefault(); if (filename) { - // console.log(filename, _validateName(filename)); if (await _validateName(filename)) { - // filename valid . go on save const content = encodeURIComponent(AppGeneral.getSpreadsheetContent()); - // console.log(content); const file = new File( new Date().toString(), new Date().toString(), @@ -102,8 +105,6 @@ const Menu: React.FC<{ filename, props.bT ); - // const data = { created: file.created, modified: file.modified, content: file.content, password: file.password }; - // console.log(JSON.stringify(data)); props.store._saveFile(file); props.updateSelectedFile(filename); setShowAlert4(true); @@ -117,7 +118,6 @@ const Menu: React.FC<{ if (isPlatform("hybrid")) { const content = AppGeneral.getCurrentHTMLContent(); const base64 = btoa(content); - EmailComposer.open({ to: ["jackdwell08@gmail.com"], cc: [], @@ -128,7 +128,7 @@ const Menu: React.FC<{ isHtml: true, }); } else { - alert("This Functionality works on Anroid/IOS devices"); + alert("This Functionality works on Android/iOS devices"); } }; @@ -179,9 +179,7 @@ const Menu: React.FC<{ isOpen={showAlert1} onDidDismiss={() => setShowAlert1(false)} header="Alert Message" - message={ - "Cannot update " + getCurrentFileName() + " file!" - } + message={"Cannot update " + getCurrentFileName() + " file!"} buttons={["Ok"]} /> setShowAlert2(false)} header="Save" - message={ - "File " + - getCurrentFileName() + - " updated successfully" - } + message={"File " + getCurrentFileName() + " updated successfully"} buttons={["Ok"]} /> setShowAlert3(false)} header="Save As" - inputs={[ - { name: "filename", type: "text", placeholder: "Enter filename" }, - ]} + inputs={[{ name: "filename", type: "text", placeholder: "Enter filename" }]} buttons={[ { text: "Ok", @@ -218,11 +210,7 @@ const Menu: React.FC<{ isOpen={showAlert4} onDidDismiss={() => setShowAlert4(false)} header="Save As" - message={ - "File " + - getCurrentFileName() + - " saved successfully" - } + message={"File " + getCurrentFileName() + " saved successfully"} buttons={["Ok"]} /> = (props) => { const [showAlertNewFileCreated, setShowAlertNewFileCreated] = useState(false); - const newFile = () => { + + const newFile = async () => { if (props.file !== "default") { const content = encodeURIComponent(AppGeneral.getSpreadsheetContent()); - const data = props.store._getFile(props.file); - const file = new File( - (data as any).created, - new Date().toString(), - content, - props.file, - props.billType - ); - props.store._saveFile(file); - props.updateSelectedFile(props.file); + + const existingData = await props.store._getFile(props.file); + + if (existingData === null) { + console.warn( + `[NewFile] _getFile returned null for "${props.file}". Skipping persist.` + ); + } else { + const file = new File( + existingData.created, + new Date().toString(), + content, + props.file, + props.billType + ); + + await props.store._saveFile(file); + props.updateSelectedFile(props.file); + } } + const msc = DATA["home"][AppGeneral.getDeviceType()]["msc"]; AppGeneral.viewFile("default", JSON.stringify(msc)); props.updateSelectedFile("default"); @@ -41,7 +52,6 @@ const NewFile: React.FC<{ size="large" onClick={() => { newFile(); - // console.log("New file clicked"); }} /> { - let data = { + _saveFile = async (file: File): Promise => { + const data = { created: file.created, modified: file.modified, content: file.content, @@ -37,32 +37,45 @@ export class Local { }); }; - _getFile = async (name: string) => { - const rawData = await Preferences.get({ key: name }); - return JSON.parse(rawData.value); + /** + * Reads a stored FileObject by key. + * + * @returns The parsed FileObject, or `null` if the key does not exist + * or the stored value cannot be parsed. Callers MUST `await` + * this method before accessing any properties on the result. + */ + _getFile = async (name: string): Promise => { + try { + const rawData = await Preferences.get({ key: name }); + if (rawData.value === null || rawData.value === undefined) { + return null; + } + return JSON.parse(rawData.value) as File; + } catch (err) { + console.error(`[LocalStorage] _getFile failed for key "${name}":`, err); + return null; + } }; - _getAllFiles = async () => { - let arr = {}; + _getAllFiles = async (): Promise> => { + const arr: Record = {}; const { keys } = await Preferences.keys(); for (let i = 0; i < keys.length; i++) { - let fname = keys[i]; + const fname = keys[i]; const data = await this._getFile(fname); - arr[fname] = (data as any).modified; + if (data !== null) { + arr[fname] = data.modified; + } } return arr; }; - _deleteFile = async (name: string) => { + _deleteFile = async (name: string): Promise => { await Preferences.remove({ key: name }); }; - _checkKey = async (key: string) => { + _checkKey = async (key: string): Promise => { const { keys } = await Preferences.keys(); - if (keys.includes(key, 0)) { - return true; - } else { - return false; - } + return keys.includes(key); }; -} +} \ No newline at end of file