From e8ecd3204e8515c16ae44452906599ea76d6774d Mon Sep 17 00:00:00 2001 From: sairaj mote Date: Tue, 6 Feb 2024 03:51:48 +0530 Subject: [PATCH] code refactoring --- index.html | 2 +- scripts/app.js | 26 ++++++++++++++++---------- scripts/app.min.js | 22 ++++++++++++++-------- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/index.html b/index.html index 2e87859..91c0781 100644 --- a/index.html +++ b/index.html @@ -98,7 +98,7 @@ - + \ No newline at end of file diff --git a/scripts/app.js b/scripts/app.js index 5319048..25b9cf1 100644 --- a/scripts/app.js +++ b/scripts/app.js @@ -587,7 +587,7 @@ async function applyToTask(id) { floCloudAPI.sendGeneralData({ taskID: id }, 'taskApplications') .then(response => { notify('You have successfully applied to the task', 'success') - render.availableTasks('available_tasks'); + render.availableTasks(); }).catch(e => { notify('An error occurred while applying to the task', 'error') }) @@ -643,7 +643,7 @@ async function saveTask() { floCloudAPI.updateObjectData('rmInterns') .then(response => { notify('Task saved successfully', 'success') - render.availableTasks('available_tasks_list'); + render.availableTasks(); }) .catch(e => { notify('An error occurred while saving the task', 'error') @@ -674,7 +674,7 @@ async function deleteTask(id) { floGlobals.appObjects.rmInterns.tasks.splice(taskIndex, 0, cloneOfTaskToBeDeleted); }).finally(() => { closePopup() - render.availableTasks('available_tasks_list'); + render.availableTasks(); }) } const render = { @@ -706,7 +706,7 @@ const render = { ` }, - availableTasks(target) { + availableTasks(target = 'available_tasks_list') { if (floGlobals.appObjects?.rmInterns?.tasks?.length === 0) return renderElem(getRef(target), html`

No tasks available

`) const tasksList = floGlobals.appObjects.rmInterns.tasks.map(render.task); @@ -779,12 +779,14 @@ function renderLanding(state) {

Available

- +
`) - render.availableTasks('available_tasks_list') + render.availableTasks() } router.addRoute('', renderLanding) router.addRoute('landing', renderLanding) @@ -892,9 +894,11 @@ router.addRoute('home', (state) => { Add Task - + `) - render.availableTasks('available_tasks_list') + render.availableTasks() } else if (view === 'applications') { renderElem(getRef('sub_admin_view'), html`
  • @@ -911,12 +915,14 @@ router.addRoute('home', (state) => {

    Home

    Available

    -
      +
        + +
      `) - render.availableTasks('available_tasks_list') + render.availableTasks() } }) diff --git a/scripts/app.min.js b/scripts/app.min.js index da5adde..8791377 100644 --- a/scripts/app.min.js +++ b/scripts/app.min.js @@ -1,4 +1,4 @@ -const uiGlobals={},{html:html,svg:svg,render:renderElem}=uhtml;function getRef(elementId){return document.getElementById(elementId)}uiGlobals.connectionErrorNotification=[],navigator.onLine||uiGlobals.connectionErrorNotification.push(notify("There seems to be a problem connecting to the internet, Please check you internet connection.","error")),window.addEventListener("offline",(()=>{uiGlobals.connectionErrorNotification.push(notify("There seems to be a problem connecting to the internet, Please check you internet connection.","error"))})),window.addEventListener("online",(()=>{uiGlobals.connectionErrorNotification.forEach((notification=>{getRef("notification_drawer").remove(notification)})),notify("We are back online.","success")}));const getConfirmation=(title,options={})=>new Promise((resolve=>{const{message:message="",cancelText:cancelText="Cancel",confirmText:confirmText="OK",danger:danger=!1}=options;getRef("confirm_title").innerText=title,getRef("confirm_message").innerText=message;const cancelButton=getRef("confirmation_popup").querySelector(".cancel-button"),confirmButton=getRef("confirmation_popup").querySelector(".confirm-button");confirmButton.textContent=confirmText,cancelButton.textContent=cancelText,danger?confirmButton.classList.add("button--danger"):confirmButton.classList.remove("button--danger");const{opened:opened,closed:closed}=openPopup("confirmation_popup");confirmButton.onclick=()=>{closePopup({payload:!0})},cancelButton.onclick=()=>{closePopup()},closed.then((payload=>{confirmButton.onclick=null,cancelButton.onclick=null,resolve(!!payload)}))})),debounce=(callback,wait)=>{let timeoutId=null;return(...args)=>{window.clearTimeout(timeoutId),timeoutId=window.setTimeout((()=>{callback.apply(null,args)}),wait)}};function addClass(elements,className){elements.forEach((element=>{document.querySelector(element).classList.add(className)}))}function removeClass(elements,className){elements.forEach((element=>{document.querySelector(element).classList.remove(className)}))}function getAllElements(selector){return Array.from(document.querySelectorAll(selector))}let zIndex=50;function openPopup(popupId,pinned){return void 0===popupStack.peek()&&document.addEventListener("keydown",(e=>{"Escape"===e.key&&closePopup()})),zIndex++,getRef(popupId).setAttribute("style",`z-index: ${zIndex}`),getRef(popupId).show({pinned:pinned})}function closePopup(options={}){void 0!==popupStack.peek()&&popupStack.peek().popup.hide(options)}function notify(message,mode,options={}){let icon;switch(mode){case"success":icon='';break;case"error":icon='',options.pinned=!0}return"error"===mode&&console.error(message),getRef("notification_drawer").push(message,{icon:icon,...options})}function getFormattedTime(timestamp,format){try{String(timestamp).length<13&&(timestamp*=1e3);let[day,month,date,year]=new Date(timestamp).toString().split(" "),minutes=new Date(timestamp).getMinutes(),hours=new Date(timestamp).getHours();(new Date).toString().split(" ");minutes=minutes<10?`0${minutes}`:minutes;let finalHours="";switch(finalHours=hours>12?`${hours-12}:${minutes}`:0===hours?`12:${minutes}`:`${hours}:${minutes}`,finalHours=hours>=12?`${finalHours} PM`:`${finalHours} AM`,format){case"date-only":return`${month} ${date}, ${year}`;case"time-only":return finalHours;default:return`${month} ${date} ${year}, ${finalHours}`}}catch(e){return console.error(e),timestamp}}function detectBrowser(){let tem,ua=navigator.userAgent,M=ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i)||[];return/trident/i.test(M[1])?(tem=/\brv[ :]+(\d+)/g.exec(ua)||[],"IE "+(tem[1]||"")):"Chrome"===M[1]&&(tem=ua.match(/\b(OPR|Edge)\/(\d+)/),null!=tem)?tem.slice(1).join(" ").replace("OPR","Opera"):(M=M[2]?[M[1],M[2]]:[navigator.appName,navigator.appVersion,"-?"],null!=(tem=ua.match(/version\/(\d+)/i))&&M.splice(1,1,tem[1]),M.join(" "))}function createRipple(event,target){const circle=document.createElement("span"),diameter=Math.max(target.clientWidth,target.clientHeight),radius=diameter/2,targetDimensions=target.getBoundingClientRect();circle.style.width=circle.style.height=`${diameter}px`,circle.style.left=event.clientX-(targetDimensions.left+radius)+"px",circle.style.top=event.clientY-(targetDimensions.top+radius)+"px",circle.classList.add("ripple");const rippleAnimation=circle.animate([{opacity:1,transform:"scale(0)"},{transform:"scale(4)",opacity:0}],{duration:600,fill:"forwards",easing:"ease-out"});target.append(circle),rippleAnimation.onfinish=()=>{circle.remove()}}document.addEventListener("popupopened",(async e=>{history.pushState({type:"popup"},null,null),e.target.id})),document.addEventListener("popupclosed",(e=>{if(zIndex--,"task_popup"===e.target.id)delete getRef("task_popup").dataset.taskId;void 0===popupStack.peek()&&document.removeEventListener("keydown",(e=>{"Escape"===e.key&&closePopup()}))})),window.addEventListener("popstate",(e=>{if(e.state&&"popup"===e.state.type)closePopup()}));class Router{constructor(options={}){const{routes:routes={},state:state={},routingStart:routingStart,routingEnd:routingEnd}=options;this.routes=routes,this.state=state,this.routingStart=routingStart,this.routingEnd=routingEnd,this.lastPage=null,window.addEventListener("hashchange",(e=>this.routeTo(window.location.hash)))}addRoute(route,callback){this.routes[route]=callback}handleRouting=async page=>{this.routingStart&&this.routingStart(this.state),this.routes[page]?(await this.routes[page](this.state),this.lastPage=page):this.routes[404]?this.routes[404](this.state):console.error(`No route found for '${page}' and no '404' route is defined.`),this.routingEnd&&this.routingEnd(this.state)};async routeTo(destination){try{let page,wildcards=[],params={},[path,queryString]=destination.split("?");path.includes("#")&&(path=path.split("#")[1]),path.includes("/")?[,page,...wildcards]=path.split("/"):page=path,this.state={page:page,wildcards:wildcards,lastPage:this.lastPage,params:params},queryString&&(params=new URLSearchParams(queryString),this.state.params=Object.fromEntries(params)),document.startViewTransition?document.startViewTransition((async()=>{await this.handleRouting(page)})):await this.handleRouting(page)}catch(e){console.error(e)}}}class LazyLoader{constructor(container,elementsToRender,renderFn,options={}){const{batchSize:batchSize=10,freshRender:freshRender,bottomFirst:bottomFirst=!1,domUpdated:domUpdated}=options;this.elementsToRender=elementsToRender,this.arrayOfElements="function"==typeof elementsToRender?this.elementsToRender():elementsToRender||[],this.renderFn=renderFn,this.intersectionObserver,this.batchSize=batchSize,this.freshRender=freshRender,this.domUpdated=domUpdated,this.bottomFirst=bottomFirst,this.shouldLazyLoad=!1,this.lastScrollTop=0,this.lastScrollHeight=0,this.lazyContainer=document.querySelector(container),this.update=this.update.bind(this),this.render=this.render.bind(this),this.init=this.init.bind(this),this.clear=this.clear.bind(this)}get elements(){return this.arrayOfElements}init(){this.intersectionObserver=new IntersectionObserver(((entries,observer)=>{entries.forEach((entry=>{entry.isIntersecting&&(observer.disconnect(),this.render({lazyLoad:!0}))}))})),this.mutationObserver=new MutationObserver((mutationList=>{mutationList.forEach((mutation=>{"childList"===mutation.type&&mutation.addedNodes.length&&(this.bottomFirst?this.lazyContainer.firstElementChild&&this.intersectionObserver.observe(this.lazyContainer.firstElementChild):this.lazyContainer.lastElementChild&&this.intersectionObserver.observe(this.lazyContainer.lastElementChild))}))})),this.mutationObserver.observe(this.lazyContainer,{childList:!0}),this.render()}update(elementsToRender){this.arrayOfElements="function"==typeof elementsToRender?this.elementsToRender():elementsToRender||[]}render(options={}){let{lazyLoad:lazyLoad=!1}=options;this.shouldLazyLoad=lazyLoad;const frag=document.createDocumentFragment();lazyLoad?this.bottomFirst?(this.updateEndIndex=this.updateStartIndex,this.updateStartIndex=this.updateEndIndex-this.batchSize):(this.updateStartIndex=this.updateEndIndex,this.updateEndIndex=this.updateEndIndex+this.batchSize):(this.intersectionObserver.disconnect(),this.bottomFirst?(this.updateEndIndex=this.arrayOfElements.length,this.updateStartIndex=this.updateEndIndex-this.batchSize-1):(this.updateStartIndex=0,this.updateEndIndex=this.batchSize),this.lazyContainer.innerHTML=""),this.lastScrollHeight=this.lazyContainer.scrollHeight,this.lastScrollTop=this.lazyContainer.scrollTop,this.arrayOfElements.slice(this.updateStartIndex,this.updateEndIndex).forEach(((element,index)=>{frag.append(this.renderFn(element))})),this.bottomFirst?(this.lazyContainer.prepend(frag),this.lastScrollTop+=this.lazyContainer.scrollHeight-this.lastScrollHeight,this.lazyContainer.scrollTo({top:this.lastScrollTop}),this.lastScrollHeight=this.lazyContainer.scrollHeight):this.lazyContainer.append(frag),!lazyLoad&&this.bottomFirst&&(this.lazyContainer.scrollTop=this.lazyContainer.scrollHeight),!lazyLoad&&this.freshRender&&this.freshRender()}clear(){this.intersectionObserver.disconnect(),this.mutationObserver.disconnect(),this.lazyContainer.innerHTML=""}reset(){this.arrayOfElements="function"==typeof this.elementsToRender?this.elementsToRender():this.elementsToRender||[],this.render()}}function buttonLoader(id,show){const button="string"==typeof id?document.getElementById(id):id;if(!button)return;button.dataset.hasOwnProperty("wasDisabled")||(button.dataset.wasDisabled=button.disabled);const animOptions={duration:200,fill:"forwards",easing:"ease"};if(show)button.disabled=!0,button.parentNode.append(document.createElement("sm-spinner")),button.animate([{clipPath:"circle(100%)"},{clipPath:"circle(0)"}],animOptions);else{button.disabled="true"===button.dataset.wasDisabled,button.animate([{clipPath:"circle(0)"},{clipPath:"circle(100%)"}],animOptions).onfinish=e=>{button.removeAttribute("data-original-state")};const potentialTarget=button.parentNode.querySelector("sm-spinner");potentialTarget&&potentialTarget.remove()}}let isMobileView=!1;const mobileQuery=window.matchMedia("(max-width: 40rem)");function handleMobileChange(e){isMobileView=e.matches}mobileQuery.addEventListener("change",handleMobileChange),handleMobileChange(mobileQuery);const slideInLeft=[{opacity:0,transform:"translateX(1.5rem)"},{opacity:1,transform:"translateX(0)"}],slideOutLeft=[{opacity:1,transform:"translateX(0)"},{opacity:0,transform:"translateX(-1.5rem)"}],slideInRight=[{opacity:0,transform:"translateX(-1.5rem)"},{opacity:1,transform:"translateX(0)"}],slideOutRight=[{opacity:1,transform:"translateX(0)"},{opacity:0,transform:"translateX(1.5rem)"}],slideInDown=[{opacity:0,transform:"translateY(-1.5rem)"},{opacity:1,transform:"translateY(0)"}],slideOutUp=[{opacity:1,transform:"translateY(0)"},{opacity:0,transform:"translateY(-1.5rem)"}];async function applyToTask(id){await getConfirmation("Apply to task",{message:"Are you sure you want to apply to this task?"})&&floCloudAPI.sendGeneralData({taskID:id},"taskApplications").then((response=>{notify("You have successfully applied to the task","success"),render.availableTasks("available_tasks")})).catch((e=>{notify("An error occurred while applying to the task","error")}))}function editTask(id){const task=floGlobals.appObjects.rmInterns.tasks.find((task=>task.id===id));if(!task)return notify("Task not found","error");const{title:title,description:description,category:category,deadline:deadline}=task;getRef("task_popup__title_input").value=title,getRef("task_popup__description").value=description,getRef("task_popup__category").value=category,getRef("task_popup__deadline").value=deadline,getRef("task_popup").dataset.taskId=id,openPopup("task_popup")}async function saveTask(){if(!await getConfirmation("Save task",{message:"Are you sure you want to save this task?",confirmText:"Save"}))return;const id=getRef("task_popup").dataset.taskId||Math.random().toString(36).substr(2,9),title=getRef("task_popup__title_input").value,description=getRef("task_popup__description").value,category=getRef("task_popup__category").value,deadline=getRef("task_popup__deadline").value,task={id:id,title:title,description:description,category:category,deadline:deadline,status:"open"},foundTask=floGlobals.appObjects.rmInterns.tasks.find((task=>task.id===id));if(foundTask){let taskDetailsChanged=!1;for(const key in task)task[key]!==foundTask[key]&&(taskDetailsChanged=!0,foundTask[key]=task[key]);if(!taskDetailsChanged)return notify("Please update at least one detail to save the changes","error")}else task.date=Date.now(),floGlobals.appObjects.rmInterns.tasks.unshift(task);floCloudAPI.updateObjectData("rmInterns").then((response=>{notify("Task saved successfully","success"),render.availableTasks("available_tasks_list")})).catch((e=>{notify("An error occurred while saving the task","error"),console.error(e)})).finally((()=>{closePopup()}))}async function deleteTask(id){if(!await getConfirmation("Delete task",{message:"Are you sure you want to delete this task?",confirmText:"Delete",danger:!0}))return;console;const taskIndex=floGlobals.appObjects.rmInterns.tasks.findIndex((task=>task.id===id));if(taskIndex<0)return notify("Task not found","error");const[cloneOfTaskToBeDeleted]=floGlobals.appObjects.rmInterns.tasks.splice(taskIndex,1);floCloudAPI.updateObjectData("rmInterns").then((response=>{notify("Task deleted successfully","success")})).catch((e=>{notify("An error occurred while deleting the task","error"),floGlobals.appObjects.rmInterns.tasks.splice(taskIndex,0,cloneOfTaskToBeDeleted)})).finally((()=>{closePopup(),render.availableTasks("available_tasks_list")}))}window.smCompConfig={"sm-input":[{selector:"[data-flo-address]",customValidation:value=>value?{isValid:floCrypto.validateFloID(value),errorText:'Invalid FLO address.
      It usually starts with "F"'}:{isValid:!1,errorText:"Please enter a FLO address"}},{selector:"[data-btc-address]",customValidation:value=>value?{isValid:btcOperator.validateAddress(value),errorText:'Invalid address.
      It usually starts with "1", "3" or "bc1"'}:{isValid:!1,errorText:"Please enter a BTC address"}},{selector:"[data-private-key]",customValidation:(value,inputElem)=>{if(!value)return{isValid:!1,errorText:"Please enter a private key"};if(floCrypto.getPubKeyHex(value)){const forAddress=inputElem.dataset.forAddress;return forAddress?{isValid:btcOperator.verifyKey(forAddress,value),errorText:`This private key does not match the address ${forAddress}`}:{isValid:!0}}return{isValid:!1,errorText:"Invalid private key. Please check and try again."}}}]};const render={task(details={}){const{title:title,description:description,date:date,id:id,status:status,deadline:deadline,category:category}=details;let actions="";return floGlobals.isSubAdmin?actions=html` +const uiGlobals={},{html:html,svg:svg,render:renderElem}=uhtml;function getRef(elementId){return document.getElementById(elementId)}uiGlobals.connectionErrorNotification=[],navigator.onLine||uiGlobals.connectionErrorNotification.push(notify("There seems to be a problem connecting to the internet, Please check you internet connection.","error")),window.addEventListener("offline",(()=>{uiGlobals.connectionErrorNotification.push(notify("There seems to be a problem connecting to the internet, Please check you internet connection.","error"))})),window.addEventListener("online",(()=>{uiGlobals.connectionErrorNotification.forEach((notification=>{getRef("notification_drawer").remove(notification)})),notify("We are back online.","success")}));const getConfirmation=(title,options={})=>new Promise((resolve=>{const{message:message="",cancelText:cancelText="Cancel",confirmText:confirmText="OK",danger:danger=!1}=options;getRef("confirm_title").innerText=title,getRef("confirm_message").innerText=message;const cancelButton=getRef("confirmation_popup").querySelector(".cancel-button"),confirmButton=getRef("confirmation_popup").querySelector(".confirm-button");confirmButton.textContent=confirmText,cancelButton.textContent=cancelText,danger?confirmButton.classList.add("button--danger"):confirmButton.classList.remove("button--danger");const{opened:opened,closed:closed}=openPopup("confirmation_popup");confirmButton.onclick=()=>{closePopup({payload:!0})},cancelButton.onclick=()=>{closePopup()},closed.then((payload=>{confirmButton.onclick=null,cancelButton.onclick=null,resolve(!!payload)}))})),debounce=(callback,wait)=>{let timeoutId=null;return(...args)=>{window.clearTimeout(timeoutId),timeoutId=window.setTimeout((()=>{callback.apply(null,args)}),wait)}};function addClass(elements,className){elements.forEach((element=>{document.querySelector(element).classList.add(className)}))}function removeClass(elements,className){elements.forEach((element=>{document.querySelector(element).classList.remove(className)}))}function getAllElements(selector){return Array.from(document.querySelectorAll(selector))}let zIndex=50;function openPopup(popupId,pinned){return void 0===popupStack.peek()&&document.addEventListener("keydown",(e=>{"Escape"===e.key&&closePopup()})),zIndex++,getRef(popupId).setAttribute("style",`z-index: ${zIndex}`),getRef(popupId).show({pinned:pinned})}function closePopup(options={}){void 0!==popupStack.peek()&&popupStack.peek().popup.hide(options)}function notify(message,mode,options={}){let icon;switch(mode){case"success":icon='';break;case"error":icon='',options.pinned=!0}return"error"===mode&&console.error(message),getRef("notification_drawer").push(message,{icon:icon,...options})}function getFormattedTime(timestamp,format){try{String(timestamp).length<13&&(timestamp*=1e3);let[day,month,date,year]=new Date(timestamp).toString().split(" "),minutes=new Date(timestamp).getMinutes(),hours=new Date(timestamp).getHours();(new Date).toString().split(" ");minutes=minutes<10?`0${minutes}`:minutes;let finalHours="";switch(finalHours=hours>12?`${hours-12}:${minutes}`:0===hours?`12:${minutes}`:`${hours}:${minutes}`,finalHours=hours>=12?`${finalHours} PM`:`${finalHours} AM`,format){case"date-only":return`${month} ${date}, ${year}`;case"time-only":return finalHours;default:return`${month} ${date} ${year}, ${finalHours}`}}catch(e){return console.error(e),timestamp}}function detectBrowser(){let tem,ua=navigator.userAgent,M=ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i)||[];return/trident/i.test(M[1])?(tem=/\brv[ :]+(\d+)/g.exec(ua)||[],"IE "+(tem[1]||"")):"Chrome"===M[1]&&(tem=ua.match(/\b(OPR|Edge)\/(\d+)/),null!=tem)?tem.slice(1).join(" ").replace("OPR","Opera"):(M=M[2]?[M[1],M[2]]:[navigator.appName,navigator.appVersion,"-?"],null!=(tem=ua.match(/version\/(\d+)/i))&&M.splice(1,1,tem[1]),M.join(" "))}function createRipple(event,target){const circle=document.createElement("span"),diameter=Math.max(target.clientWidth,target.clientHeight),radius=diameter/2,targetDimensions=target.getBoundingClientRect();circle.style.width=circle.style.height=`${diameter}px`,circle.style.left=event.clientX-(targetDimensions.left+radius)+"px",circle.style.top=event.clientY-(targetDimensions.top+radius)+"px",circle.classList.add("ripple");const rippleAnimation=circle.animate([{opacity:1,transform:"scale(0)"},{transform:"scale(4)",opacity:0}],{duration:600,fill:"forwards",easing:"ease-out"});target.append(circle),rippleAnimation.onfinish=()=>{circle.remove()}}document.addEventListener("popupopened",(async e=>{history.pushState({type:"popup"},null,null),e.target.id})),document.addEventListener("popupclosed",(e=>{if(zIndex--,"task_popup"===e.target.id)delete getRef("task_popup").dataset.taskId;void 0===popupStack.peek()&&document.removeEventListener("keydown",(e=>{"Escape"===e.key&&closePopup()}))})),window.addEventListener("popstate",(e=>{if(e.state&&"popup"===e.state.type)closePopup()}));class Router{constructor(options={}){const{routes:routes={},state:state={},routingStart:routingStart,routingEnd:routingEnd}=options;this.routes=routes,this.state=state,this.routingStart=routingStart,this.routingEnd=routingEnd,this.lastPage=null,window.addEventListener("hashchange",(e=>this.routeTo(window.location.hash)))}addRoute(route,callback){this.routes[route]=callback}handleRouting=async page=>{this.routingStart&&this.routingStart(this.state),this.routes[page]?(await this.routes[page](this.state),this.lastPage=page):this.routes[404]?this.routes[404](this.state):console.error(`No route found for '${page}' and no '404' route is defined.`),this.routingEnd&&this.routingEnd(this.state)};async routeTo(destination){try{let page,wildcards=[],params={},[path,queryString]=destination.split("?");path.includes("#")&&(path=path.split("#")[1]),path.includes("/")?[,page,...wildcards]=path.split("/"):page=path,this.state={page:page,wildcards:wildcards,lastPage:this.lastPage,params:params},queryString&&(params=new URLSearchParams(queryString),this.state.params=Object.fromEntries(params)),document.startViewTransition?document.startViewTransition((async()=>{await this.handleRouting(page)})):await this.handleRouting(page)}catch(e){console.error(e)}}}class LazyLoader{constructor(container,elementsToRender,renderFn,options={}){const{batchSize:batchSize=10,freshRender:freshRender,bottomFirst:bottomFirst=!1,domUpdated:domUpdated}=options;this.elementsToRender=elementsToRender,this.arrayOfElements="function"==typeof elementsToRender?this.elementsToRender():elementsToRender||[],this.renderFn=renderFn,this.intersectionObserver,this.batchSize=batchSize,this.freshRender=freshRender,this.domUpdated=domUpdated,this.bottomFirst=bottomFirst,this.shouldLazyLoad=!1,this.lastScrollTop=0,this.lastScrollHeight=0,this.lazyContainer=document.querySelector(container),this.update=this.update.bind(this),this.render=this.render.bind(this),this.init=this.init.bind(this),this.clear=this.clear.bind(this)}get elements(){return this.arrayOfElements}init(){this.intersectionObserver=new IntersectionObserver(((entries,observer)=>{entries.forEach((entry=>{entry.isIntersecting&&(observer.disconnect(),this.render({lazyLoad:!0}))}))})),this.mutationObserver=new MutationObserver((mutationList=>{mutationList.forEach((mutation=>{"childList"===mutation.type&&mutation.addedNodes.length&&(this.bottomFirst?this.lazyContainer.firstElementChild&&this.intersectionObserver.observe(this.lazyContainer.firstElementChild):this.lazyContainer.lastElementChild&&this.intersectionObserver.observe(this.lazyContainer.lastElementChild))}))})),this.mutationObserver.observe(this.lazyContainer,{childList:!0}),this.render()}update(elementsToRender){this.arrayOfElements="function"==typeof elementsToRender?this.elementsToRender():elementsToRender||[]}render(options={}){let{lazyLoad:lazyLoad=!1}=options;this.shouldLazyLoad=lazyLoad;const frag=document.createDocumentFragment();lazyLoad?this.bottomFirst?(this.updateEndIndex=this.updateStartIndex,this.updateStartIndex=this.updateEndIndex-this.batchSize):(this.updateStartIndex=this.updateEndIndex,this.updateEndIndex=this.updateEndIndex+this.batchSize):(this.intersectionObserver.disconnect(),this.bottomFirst?(this.updateEndIndex=this.arrayOfElements.length,this.updateStartIndex=this.updateEndIndex-this.batchSize-1):(this.updateStartIndex=0,this.updateEndIndex=this.batchSize),this.lazyContainer.innerHTML=""),this.lastScrollHeight=this.lazyContainer.scrollHeight,this.lastScrollTop=this.lazyContainer.scrollTop,this.arrayOfElements.slice(this.updateStartIndex,this.updateEndIndex).forEach(((element,index)=>{frag.append(this.renderFn(element))})),this.bottomFirst?(this.lazyContainer.prepend(frag),this.lastScrollTop+=this.lazyContainer.scrollHeight-this.lastScrollHeight,this.lazyContainer.scrollTo({top:this.lastScrollTop}),this.lastScrollHeight=this.lazyContainer.scrollHeight):this.lazyContainer.append(frag),!lazyLoad&&this.bottomFirst&&(this.lazyContainer.scrollTop=this.lazyContainer.scrollHeight),!lazyLoad&&this.freshRender&&this.freshRender()}clear(){this.intersectionObserver.disconnect(),this.mutationObserver.disconnect(),this.lazyContainer.innerHTML=""}reset(){this.arrayOfElements="function"==typeof this.elementsToRender?this.elementsToRender():this.elementsToRender||[],this.render()}}function buttonLoader(id,show){const button="string"==typeof id?document.getElementById(id):id;if(!button)return;button.dataset.hasOwnProperty("wasDisabled")||(button.dataset.wasDisabled=button.disabled);const animOptions={duration:200,fill:"forwards",easing:"ease"};if(show)button.disabled=!0,button.parentNode.append(document.createElement("sm-spinner")),button.animate([{clipPath:"circle(100%)"},{clipPath:"circle(0)"}],animOptions);else{button.disabled="true"===button.dataset.wasDisabled,button.animate([{clipPath:"circle(0)"},{clipPath:"circle(100%)"}],animOptions).onfinish=e=>{button.removeAttribute("data-original-state")};const potentialTarget=button.parentNode.querySelector("sm-spinner");potentialTarget&&potentialTarget.remove()}}let isMobileView=!1;const mobileQuery=window.matchMedia("(max-width: 40rem)");function handleMobileChange(e){isMobileView=e.matches}mobileQuery.addEventListener("change",handleMobileChange),handleMobileChange(mobileQuery);const slideInLeft=[{opacity:0,transform:"translateX(1.5rem)"},{opacity:1,transform:"translateX(0)"}],slideOutLeft=[{opacity:1,transform:"translateX(0)"},{opacity:0,transform:"translateX(-1.5rem)"}],slideInRight=[{opacity:0,transform:"translateX(-1.5rem)"},{opacity:1,transform:"translateX(0)"}],slideOutRight=[{opacity:1,transform:"translateX(0)"},{opacity:0,transform:"translateX(1.5rem)"}],slideInDown=[{opacity:0,transform:"translateY(-1.5rem)"},{opacity:1,transform:"translateY(0)"}],slideOutUp=[{opacity:1,transform:"translateY(0)"},{opacity:0,transform:"translateY(-1.5rem)"}];async function applyToTask(id){await getConfirmation("Apply to task",{message:"Are you sure you want to apply to this task?"})&&floCloudAPI.sendGeneralData({taskID:id},"taskApplications").then((response=>{notify("You have successfully applied to the task","success"),render.availableTasks()})).catch((e=>{notify("An error occurred while applying to the task","error")}))}function editTask(id){const task=floGlobals.appObjects.rmInterns.tasks.find((task=>task.id===id));if(!task)return notify("Task not found","error");const{title:title,description:description,category:category,deadline:deadline}=task;getRef("task_popup__title_input").value=title,getRef("task_popup__description").value=description,getRef("task_popup__category").value=category,getRef("task_popup__deadline").value=deadline,getRef("task_popup").dataset.taskId=id,openPopup("task_popup")}async function saveTask(){if(!await getConfirmation("Save task",{message:"Are you sure you want to save this task?",confirmText:"Save"}))return;const id=getRef("task_popup").dataset.taskId||Math.random().toString(36).substr(2,9),title=getRef("task_popup__title_input").value,description=getRef("task_popup__description").value,category=getRef("task_popup__category").value,deadline=getRef("task_popup__deadline").value,task={id:id,title:title,description:description,category:category,deadline:deadline,status:"open"},foundTask=floGlobals.appObjects.rmInterns.tasks.find((task=>task.id===id));if(foundTask){let taskDetailsChanged=!1;for(const key in task)task[key]!==foundTask[key]&&(taskDetailsChanged=!0,foundTask[key]=task[key]);if(!taskDetailsChanged)return notify("Please update at least one detail to save the changes","error")}else task.date=Date.now(),floGlobals.appObjects.rmInterns.tasks.unshift(task);floCloudAPI.updateObjectData("rmInterns").then((response=>{notify("Task saved successfully","success"),render.availableTasks()})).catch((e=>{notify("An error occurred while saving the task","error"),console.error(e)})).finally((()=>{closePopup()}))}async function deleteTask(id){if(!await getConfirmation("Delete task",{message:"Are you sure you want to delete this task?",confirmText:"Delete",danger:!0}))return;console;const taskIndex=floGlobals.appObjects.rmInterns.tasks.findIndex((task=>task.id===id));if(taskIndex<0)return notify("Task not found","error");const[cloneOfTaskToBeDeleted]=floGlobals.appObjects.rmInterns.tasks.splice(taskIndex,1);floCloudAPI.updateObjectData("rmInterns").then((response=>{notify("Task deleted successfully","success")})).catch((e=>{notify("An error occurred while deleting the task","error"),floGlobals.appObjects.rmInterns.tasks.splice(taskIndex,0,cloneOfTaskToBeDeleted)})).finally((()=>{closePopup(),render.availableTasks()}))}window.smCompConfig={"sm-input":[{selector:"[data-flo-address]",customValidation:value=>value?{isValid:floCrypto.validateFloID(value),errorText:'Invalid FLO address.
      It usually starts with "F"'}:{isValid:!1,errorText:"Please enter a FLO address"}},{selector:"[data-btc-address]",customValidation:value=>value?{isValid:btcOperator.validateAddress(value),errorText:'Invalid address.
      It usually starts with "1", "3" or "bc1"'}:{isValid:!1,errorText:"Please enter a BTC address"}},{selector:"[data-private-key]",customValidation:(value,inputElem)=>{if(!value)return{isValid:!1,errorText:"Please enter a private key"};if(floCrypto.getPubKeyHex(value)){const forAddress=inputElem.dataset.forAddress;return forAddress?{isValid:btcOperator.verifyKey(forAddress,value),errorText:`This private key does not match the address ${forAddress}`}:{isValid:!0}}return{isValid:!1,errorText:"Invalid private key. Please check and try again."}}}]};const render={task(details={}){const{title:title,description:description,date:date,id:id,status:status,deadline:deadline,category:category}=details;let actions="";return floGlobals.isSubAdmin?actions=html` `:floGlobals.isAdmin,html` @@ -14,7 +14,7 @@ const uiGlobals={},{html:html,svg:svg,render:renderElem}=uhtml;function getRef(e ${actions}
    • - `},availableTasks(target){if(0===floGlobals.appObjects?.rmInterns?.tasks?.length)return renderElem(getRef(target),html`

      No tasks available

      `);const tasksList=floGlobals.appObjects.rmInterns.tasks.map(render.task);renderElem(getRef(target),html`${tasksList}`)}},router=new Router({routingStart(state){"scrollRestoration"in history&&(history.scrollRestoration="manual"),window.scrollTo(0,0)},routingEnd(state){const{page:page,lastPage:lastPage}=state;lastPage!==page&&closePopup()}}),header=page=>{const isUserLoggedIn="loading"===page||floGlobals.isUserLoggedIn;return html` + `},availableTasks(target="available_tasks_list"){if(0===floGlobals.appObjects?.rmInterns?.tasks?.length)return renderElem(getRef(target),html`

      No tasks available

      `);const tasksList=floGlobals.appObjects.rmInterns.tasks.map(render.task);renderElem(getRef(target),html`${tasksList}`)}},router=new Router({routingStart(state){"scrollRestoration"in history&&(history.scrollRestoration="manual"),window.scrollTo(0,0)},routingEnd(state){const{page:page,lastPage:lastPage}=state;lastPage!==page&&closePopup()}}),header=page=>{const isUserLoggedIn="loading"===page||floGlobals.isUserLoggedIn;return html`
      @@ -44,11 +44,13 @@ const uiGlobals={},{html:html,svg:svg,render:renderElem}=uhtml;function getRef(e

      Available

      -
        +
          + +
        - `),render.availableTasks("available_tasks_list")}function handleSignIn(){privKeyResolver(getRef("private_key_field").value.trim()),router.routeTo("loading")}function handleSignUp(){const privKey=getRef("generated_private_key").value.trim();privKeyResolver(privKey),router.routeTo("loading")}function handleSubAdminViewChange(e){location.hash=`#/home?view=${e.target.value}`}router.addRoute("loading",(state=>{renderElem(getRef("app_body"),html` + `),render.availableTasks()}function handleSignIn(){privKeyResolver(getRef("private_key_field").value.trim()),router.routeTo("loading")}function handleSignUp(){const privKey=getRef("generated_private_key").value.trim();privKeyResolver(privKey),router.routeTo("loading")}function handleSubAdminViewChange(e){location.hash=`#/home?view=${e.target.value}`}router.addRoute("loading",(state=>{renderElem(getRef("app_body"),html`
        ${header("loading")}
        @@ -128,8 +130,10 @@ const uiGlobals={},{html:html,svg:svg,render:renderElem}=uhtml;function getRef(e Add Task -
          - `),render.availableTasks("available_tasks_list")):"applications"===view&&renderElem(getRef("sub_admin_view"),html` +
            + +
          + `),render.availableTasks()):"applications"===view&&renderElem(getRef("sub_admin_view"),html`
        • Applications

          @@ -141,11 +145,13 @@ const uiGlobals={},{html:html,svg:svg,render:renderElem}=uhtml;function getRef(e

          Home

          Available

          -
            +
              + +
          • - `),render.availableTasks("available_tasks_list")))})),router.addRoute("profile",(state=>{renderElem(getRef("app_body"),html` + `),render.availableTasks()))})),router.addRoute("profile",(state=>{renderElem(getRef("app_body"),html`
            ${header()}