-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.min.js
More file actions
1 lines (1 loc) · 4.15 KB
/
index.min.js
File metadata and controls
1 lines (1 loc) · 4.15 KB
1
"use strict";const dbName="arxfinote",dbVersion=1,storeName="transactions";let dbCache=null;const nanoid=(t=21)=>{let a="",e=crypto.getRandomValues(new Uint8Array(t));for(let s=0;s<t;s++)a+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&e[s]];return a},formatCurrency=t=>new Intl.NumberFormat("id-ID",{currency:"IDR",minimumFractionDigits:0,style:"currency"}).format(t),parseCurrency=t=>parseFloat(t.replace(/[^0-9,-]+/g,"").replace(",","."));document.addEventListener("DOMContentLoaded",(()=>{dayjs.locale("id"),AOS.init({duration:800,easing:"ease-in-out-quart",once:!0})})),document.addEventListener("alpine:init",(()=>{Alpine.data("finoteApp",(()=>({async init(){try{await this.loadTransactions()}catch(t){this.toastMessage="Data transaksi gagal dimuat.",bootstrap.Toast.getOrCreateInstance("#toast").show()}},transactions:[],searchQuery:"",filterCategory:"",filterMonth:"",editing:!1,activeID:null,form:{id:null,description:"",nominal:"",date:dayjs().format("YYYY-MM-DD"),category:"expense"},scrollToTop:!1,toastMessage:"",openDB:async()=>dbCache||(dbCache=await idb.openDB(dbName,1,{upgrade(t){t.objectStoreNames.contains(storeName)||t.createObjectStore(storeName,{keyPath:"id"})}}),dbCache),async loadTransactions(){const t=(await this.openDB()).transaction(storeName,"readonly").objectStore(storeName),a=await t.getAll();this.transactions=a.sort(((t,a)=>new Date(a.date)-new Date(t.date)))},async saveTransaction(){try{const a={id:this.editing?this.form.id:nanoid(),description:this.form.description.trim(),nominal:(t=this.form.nominal,parseFloat(t.replace(/[^0-9,-]+/g,"").replace(",","."))),date:this.form.date,category:this.form.category},e=(await this.openDB()).transaction(storeName,"readwrite").objectStore(storeName);this.editing?await e.put(a):await e.add(a),await this.loadTransactions(),bootstrap.Modal.getOrCreateInstance("#saveModal").hide(),this.toastMessage="Data transaksi berhasil disimpan."}catch(t){this.toastMessage="Data transaksi gagal disimpan."}finally{bootstrap.Toast.getOrCreateInstance("#toast").show()}var t},editTransaction(t){var a;this.editing=!0,this.form={id:t.id,description:t.description,nominal:(a=t.nominal,new Intl.NumberFormat("id-ID",{currency:"IDR",minimumFractionDigits:0,style:"currency"}).format(a)).replace("Rp","").trim(),date:t.date,category:t.category}},async deleteTransaction(t){try{const a=(await this.openDB()).transaction(storeName,"readwrite").objectStore(storeName);await a.delete(t),this.activeID=null,await this.loadTransactions(),bootstrap.Modal.getOrCreateInstance("#deleteModal").hide(),this.toastMessage="Data transaksi berhasil dihapus."}catch(t){this.toastMessage="Data transaksi gagal dihapus."}finally{bootstrap.Toast.getOrCreateInstance("#toast").show()}},resetForm(){this.editing=!1,this.form={id:null,description:"",nominal:"",date:dayjs().format("YYYY-MM-DD"),category:"expense"}},get filteredTransactions(){return this.transactions.filter((t=>{const a=t.description.toLowerCase().includes(this.searchQuery.toLowerCase()),e=!this.filterCategory||t.category===this.filterCategory,s=!this.filterMonth||t.date.startsWith(this.filterMonth);return a&&e&&s}))},get totalIncome(){return this.transactions.filter((t=>"income"===t.category)).reduce(((t,a)=>t+a.nominal),0)},get totalExpense(){return this.transactions.filter((t=>"expense"===t.category)).reduce(((t,a)=>t+a.nominal),0)},get balance(){return this.totalIncome-this.totalExpense},exportData(){const t=JSON.stringify(this.transactions,null,0);try{download(t,`arxfinote_${Date.now()}.json`,"application/json"),this.toastMessage="Data transaksi berhasil diekspor."}catch(t){this.toastMessage="Data transaksi gagal diekspor."}finally{bootstrap.Toast.getOrCreateInstance("#toast").show()}},importData(t){const a=t.target.files[0],e=new FileReader;e.addEventListener("load",(async a=>{try{const e=JSON.parse(a.target.result),s=(await this.openDB()).transaction(storeName,"readwrite").objectStore(storeName);await s.clear();for(const t of e)await s.add(t);await this.loadTransactions(),this.toastMessage="Data transaksi berhasil diimpor."}catch(t){this.toastMessage="Data transaksi gagal diimpor."}finally{bootstrap.Toast.getOrCreateInstance("#toast").show(),t.target.value=""}})),e.readAsText(a)}})))}));