From dabcb10d718aef9b9b551f567593dba380899bba Mon Sep 17 00:00:00 2001 From: Youngster Jaidev Date: Tue, 12 Oct 2021 12:47:03 +0530 Subject: [PATCH] Upload the base files --- css/main.css | 548 ++ index.html | 12066 +++++++++++++++++++++++++++++++++++++++++ js/components.min.js | 9 + js/main.js | 618 +++ js/main_UI.js | 305 ++ 5 files changed, 13546 insertions(+) create mode 100644 css/main.css create mode 100644 index.html create mode 100644 js/components.min.js create mode 100644 js/main.js create mode 100644 js/main_UI.js diff --git a/css/main.css b/css/main.css new file mode 100644 index 0000000..4b02408 --- /dev/null +++ b/css/main.css @@ -0,0 +1,548 @@ +* { + padding: 0; + margin: 0; + box-sizing: border-box; + font-family: "Roboto", sans-serif; + word-break: break-all; +} + +:root { + font-size: clamp(1rem, 1.2vmax, 3rem); +} + +html, body { + height: 100%; + scroll-behavior: smooth; +} + +body { + color: rgba(var(--text-color), 1); + background: rgba(var(--background-color), 1); +} +body, +body * { + --accent-color: #0D7377; + --text-color: 17, 17, 17; + --background-color: 255, 255, 255; + --danger-color: red; +} + +body[data-theme=dark], +body[data-theme=dark] * { + --accent-color: #32E0C4; + --text-color: 240, 240, 240; + --text-color-light: 170, 170, 170; + --background-color: 10, 10, 10; + --danger-color: rgb(255, 106, 106); +} + +span { + font-size: 5em; + height: 0em; + display: flex; + justify-content: center; + align-items: center; +} + +li > div > div:nth-of-type(1) { + text-align: right; + font-size: 35px; +} + +p { + font-size: 0.8; + max-width: 65ch; + line-height: 1.7; + margin-bottom: 1.5rem; + color: rgba(var(--text-color), 0.8); +} +p:not(:last-of-type) { + margin-bottom: 1rem; +} + +img { + object-fit: cover; +} + +a { + color: inherit; + text-decoration: none; +} +a:focus-visible { + box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset; +} + +button { + display: inline-flex; + border: none; + background-color: inherit; +} + +a:any-link:focus-visible { + outline: rgba(var(--text-color), 1) 0.1rem solid; +} + +sm-button { + --border-radius: 0.3rem; +} + +ul { + list-style-type: none; + padding: 0.5em; +} + +.input-icon { + padding: 0.2em 0.4em; + border-radius: 5px; + border: 1px solid rgba(var(--text-color), 1); +} + +.profile { + width: 50px; + height: 50px; + background: #64b5f6; + border-radius: 50%; + margin-bottom: 1em; +} + +.last-tx { + padding: 1em 0em; +} + +.last-tx > div:nth-of-type(1) { + font-weight: 700; +} + +.last-tx-content { + display: flex; + align-items: flex-end; + justify-content: center; + flex-flow: column nowrap; +} + + +.last-tx-content > div:nth-of-type(1) { + padding: 0.5em; + margin: 0.5em 0em; + border-radius: 1rem; + background: red; + color: white; +} + +.last-tx-content > div:nth-of-type(2) { + width: 100%; +} + +.app { + padding: 0.5em; + display: flex; + flex-flow: row wrap; +} + +.search-wrapper { + opacity: 0; + transition: visiblity 0s, opacity 0.1s ease-in; +} + +.search-wrapper:not(.open) { + visibility: hidden; + position: fixed; +} + +.search-wrapper.open { + visibility: visible; + position: fixed; + z-index: 10; + top: 0; + left: 0; + right: 0; + bottom: 0; + opacity: 1; + height: 100vh; +} + +.search-overlay { + background: rgba(0, 0, 0, 0.05); + height: 100%; + position: fixed; + width: 100%; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +.search { + margin: 0em auto; + width: 50%; + margin-top: 4rem; + border-radius: 0.5rem; + box-shadow: 0 4px 7px 3px rgb(0 0 0 / 20%); + background: rgba(var(--background-color), 1); +} + +.flex { + display: flex; +} + +.grid { + display: grid; +} + +.hide { + opacity: 0; + pointer-events: none; +} + +.hide-completely { + display: none !important; +} + +.no-transformations { + transform: none !important; +} + +.overflow-ellipsis { + width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.breakable { + overflow-wrap: break-word; + word-wrap: break-word; + -ms-word-break: break-all; + word-break: break-word; + -ms-hyphens: auto; + -moz-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +.full-bleed { + grid-column: 1/4; +} + +.h1 { + font-size: 2.5rem; +} + +.h2 { + font-size: 2rem; +} + +.h3 { + font-size: 1.4rem; +} + +.h4 { + font-size: 1rem; +} + +.h5 { + font-size: 0.8rem; +} + +.uppercase { + text-transform: uppercase; +} + +.capitalize { + text-transform: capitalize; +} + +.flex { + display: flex; +} + +.grid { + display: grid; +} + +.grid-3 { + grid-template-columns: 1fr auto auto; +} + +.flow-column { + grid-auto-flow: column; +} + +.gap-0-5 { + gap: 0.5rem; +} + +.gap-1 { + gap: 1rem; +} + +.gap-1-5 { + gap: 1.5rem; +} + +.gap-2 { + gap: 2rem; +} + +.gap-3 { + gap: 3rem; +} + +.text-align-right { + text-align: right; +} + +.align-start { + align-items: flex-start; +} + +.align-center { + align-items: center; +} + +.text-center { + text-align: center; +} + +.justify-start { + justify-content: start; +} + +.justify-center { + justify-content: center; +} + +.justify-right { + margin-left: auto; +} + +.align-self-center { + align-self: center; +} + +.justify-self-center { + justify-self: center; +} + +.justify-self-start { + justify-self: start; +} + +.justify-self-end { + justify-self: end; +} + +.direction-column { + flex-direction: column; +} + +.space-between { + justify-content: space-between; +} + +.w-100 { + width: 100%; +} + +.color-0-8 { + color: rgba(var(--text-color), 0.8); +} + +.weight-400 { + font-weight: 400; +} + +.weight-500 { + font-weight: 500; +} + +.ripple { + position: absolute; + border-radius: 50%; + transform: scale(0); + background: rgba(var(--text-color), 0.16); + pointer-events: none; +} + +.interact { + position: relative; + overflow: hidden; + cursor: pointer; + -webkit-tap-highlight-color: transparent; +} + +.observe-empty-state:empty { + display: none; +} + +.observe-empty-state:not(:empty) ~ .empty-state { + display: none; +} + +.icon { + width: 1.5rem; + height: 1.5rem; + fill: rgba(var(--text-color), 0.9); +} + +.button__icon { + height: 1.2rem; + width: 1.2rem; +} +.button__icon--left { + margin-right: 0.5rem; +} +.button__icon--right { + margin-left: 0.5rem; +} + +#loading { + text-align: center; + amimation: load 1s infinite; +} + +#searchToggle { + cursor: pointer; +} + + +@keyframes load { + 0% { + color: red; + } + 50% { + color: white; + } + 100% { + color: red; + } +} + +#confirmation_popup, +#prompt_popup { + flex-direction: column; +} +#confirmation_popup h4, +#prompt_popup h4 { + font-weight: 500; + margin-bottom: 0.5rem; +} +#confirmation_popup sm-button, +#prompt_popup sm-button { + margin: 0; +} +#confirmation_popup .flex, +#prompt_popup .flex { + padding: 0; + margin-top: 1rem; +} +#confirmation_popup .flex sm-button:first-of-type, +#prompt_popup .flex sm-button:first-of-type { + margin-right: 0.6rem; + margin-left: auto; +} + +#main_header { + display: flex; + gap: 1rem; + align-items: center; + position: sticky; + padding: 0.5rem 1.5rem; + background: rgba(var(--background-color), 1); + border-bottom: solid 1px rgba(var(--text-color), 0.16); + z-index: 2; +} + +#logo { + display: grid; + align-items: center; + width: 100%; + grid-template-columns: auto 1fr; + gap: 0 0.5rem; + margin-right: 1rem; + cursor: pointer; +} +#logo h4 { + text-transform: capitalize; + font-size: 1rem; + font-weight: 600; + margin-top: 0.2rem; +} +#logo h5 { + font-size: 0.8rem; + font-family: "Roboto", sans-serif; + font-weight: 400; +} +#logo #main_logo { + height: 1.4rem; + width: 1.4rem; + fill: rgba(var(--text-color), 1); + stroke: none; +} + +sm-tab-header { + padding: 0 1.5rem; + background-color: rgba(var(--text-color), 0.06); +} + +sm-tab { + padding: 0.5rem 0.8rem; +} + +.section { + display: flex; + flex-direction: column; + margin-top: 3rem; + padding: 0 1.5rem; +} +.section:first-of-type { + margin-top: 0; +} + +.section__header { + display: flex; + padding: 1rem 0; + justify-content: space-between; +} + +.card { + padding: 1.5rem; + display: flex; + flex-direction: column; + /*width: 100%;*/ + /*min-width: 20rem;*/ + border-radius: 0.5rem; + margin: 1rem 0.5em; + margin-bottom: 0.4em; + flex: 1 0; + cursor: pointer; + position: relative; + background-color: rgba(var(--text-color), 0.06); +} + +.card > a > div:nth-of-type(3) { + position: absolute; + right: 1em; + top: 1em; + padding: 0.5em; + border-radius: 1rem; + background-color: rgba(var(--background-color)); +} + +.card > a > h3 { + font-weight: 500; +} + +@media screen and (min-width: 640px) { + sm-popup { + --width: 24rem; + } +} + +@media screen and (max-width: 500px) { + .search { + width: 80%; + } +} + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..ffb6926 --- /dev/null +++ b/index.html @@ -0,0 +1,12066 @@ + + + + FLO Interns Payements + + + Flo Intern Data + + + + + + + + + + + + +

+

+
+ Cancel + OK +
+
+ +

+

+ +
+ Cancel + OK +
+
+
+
+ +
+ + + +
+ +
+ + +
+
+ +
+ + + + + + +
+ + +
+ + + + + + + + + + + + + + + + diff --git a/js/components.min.js b/js/components.min.js new file mode 100644 index 0000000..7078968 --- /dev/null +++ b/js/components.min.js @@ -0,0 +1,9 @@ +const smButton=document.createElement("template");smButton.innerHTML="\n\n
\n \n
",customElements.define("sm-button",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smButton.content.cloneNode(!0))}static get observedAttributes(){return["disabled"]}get disabled(){return this.hasAttribute("disabled")}set disabled(e){e?this.setAttribute("disabled",""):this.removeAttribute("disabled")}handleKeyDown(e){this.hasAttribute("disabled")||"Enter"!==e.key&&"Space"!==e.code||(e.preventDefault(),this.click())}connectedCallback(){this.hasAttribute("disabled")||this.setAttribute("tabindex","0"),this.setAttribute("role","button"),this.addEventListener("keydown",this.handleKeyDown)}attributeChangedCallback(e,t,n){"disabled"===e?(this.removeAttribute("tabindex"),this.setAttribute("aria-disabled","true")):(this.setAttribute("tabindex","0"),this.setAttribute("aria-disabled","false"))}}); +const smCarousel=document.createElement("template");smCarousel.innerHTML='\n\n\n',customElements.define("sm-carousel",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smCarousel.content.cloneNode(!0)),this.isAutoPlaying=!1,this.autoPlayInterval=5e3,this.autoPlayTimeout,this.initialTimeout,this.activeSlideNum=0,this.carouselItems,this.indicators,this.showIndicator=!1,this.carousel=this.shadowRoot.querySelector(".carousel"),this.carouselContainer=this.shadowRoot.querySelector(".carousel-container"),this.carouselSlot=this.shadowRoot.querySelector("slot"),this.navButtonRight=this.shadowRoot.querySelector(".carousel__button--right"),this.navButtonLeft=this.shadowRoot.querySelector(".carousel__button--left"),this.indicatorsContainer=this.shadowRoot.querySelector(".indicators"),this.scrollLeft=this.scrollLeft.bind(this),this.scrollRight=this.scrollRight.bind(this),this.handleIndicatorClick=this.handleIndicatorClick.bind(this),this.showSlide=this.showSlide.bind(this),this.nextSlide=this.nextSlide.bind(this),this.autoPlay=this.autoPlay.bind(this),this.startAutoPlay=this.startAutoPlay.bind(this),this.stopAutoPlay=this.stopAutoPlay.bind(this)}static get observedAttributes(){return["indicator","autoplay","interval"]}scrollLeft(){this.carousel.scrollBy({left:-this.scrollDistance,behavior:"smooth"})}scrollRight(){this.carousel.scrollBy({left:this.scrollDistance,behavior:"smooth"})}showSlide(t){this.carousel.scrollTo({left:this.carouselItems[t].getBoundingClientRect().left-this.carousel.getBoundingClientRect().left+this.carousel.scrollLeft,behavior:"smooth"})}nextSlide(){if(!this.carouselItems)return;let t=this.activeSlideNum+1{this.autoPlay()},this.autoPlayInterval))}startAutoPlay(){this.setAttribute("autoplay","")}stopAutoPlay(){this.removeAttribute("autoplay")}createIndicator(t){let n=document.createElement("div");return n.classList.add("indicator"),n.dataset.rank=t,n}handleIndicatorClick(t){if(t.target.closest(".indicator")){const n=parseInt(t.target.closest(".indicator").dataset.rank);this.activeSlideNum!==n&&this.showSlide(n)}}handleKeyDown(t){"ArrowLeft"===t.code?this.scrollRight():"ArrowRight"===t.code&&this.scrollRight()}connectedCallback(){let t=document.createDocumentFragment();this.carouselSlot.addEventListener("slotchange",n=>{this.carouselItems=this.carouselSlot.assignedElements(),this.carouselItems.forEach(t=>i.observe(t)),this.carouselItems.length>0?(o.observe(this.carouselItems[0]),e.observe(this.carouselItems[this.carouselItems.length-1])):(navButtonLeft.classList.add("hide"),navButtonRight.classList.add("hide"),o.disconnect(),e.disconnect()),this.showIndicator&&(this.indicatorsContainer.innerHTML="",this.carouselItems.forEach((n,i)=>{t.append(this.createIndicator(i)),n.dataset.rank=i}),this.indicatorsContainer.append(t),this.indicators=this.indicatorsContainer.children)});const n={threshold:.9,root:this},i=new IntersectionObserver(t=>{t.forEach(t=>{if(this.showIndicator){const n=parseInt(t.target.dataset.rank);t.isIntersecting?(this.indicators[n].classList.add("active"),this.activeSlideNum=n):this.indicators[n].classList.remove("active")}})},n),o=new IntersectionObserver(t=>{t.forEach(t=>{t.isIntersecting?this.navButtonLeft.classList.add("hide"):this.navButtonLeft.classList.remove("hide")})},n),e=new IntersectionObserver(t=>{t.forEach(t=>{t.isIntersecting?this.navButtonRight.classList.add("hide"):this.navButtonRight.classList.remove("hide")})},n),s=new ResizeObserver(t=>{t.forEach(t=>{if(t.contentBoxSize){const n=Array.isArray(t.contentBoxSize)?t.contentBoxSize[0]:t.contentBoxSize;this.scrollDistance=.6*n.inlineSize}else this.scrollDistance=.6*t.contentRect.width})});s.observe(this),this.addEventListener("keydown",this.handleKeyDown),this.navButtonRight.addEventListener("click",this.scrollRight),this.navButtonLeft.addEventListener("click",this.scrollLeft),this.indicatorsContainer.addEventListener("click",this.handleIndicatorClick)}attributeChangedCallback(t,n,i){n!==i&&("indicator"===t&&(this.showIndicator=this.hasAttribute("indicator")),"autoplay"===t&&(this.hasAttribute("autoplay")?this.initialTimeout=setTimeout(()=>{this.isAutoPlaying=!0,this.autoPlay()},this.autoPlayInterval):(this.isAutoPlaying=!1,clearTimeout(this.autoPlayTimeout),clearTimeout(this.initialTimeout))),"interval"===t&&(this.hasAttribute("interval")&&""!==this.getAttribute("interval").trim()?this.autoPlayInterval=Math.abs(parseInt(this.getAttribute("interval").trim())):this.autoPlayInterval=5e3))}disconnectedCallback(){this.navButtonRight.removeEventListener("click",this.scrollRight),this.navButtonLeft.removeEventListener("click",this.scrollLeft),this.indicatorsContainer.removeEventListener("click",this.handleIndicatorClick)}}); +const smForm=document.createElement("template");smForm.innerHTML='\n \n\t
\n\t\t\n\t
\n',customElements.define("sm-form",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smForm.content.cloneNode(!0)),this.form=this.shadowRoot.querySelector("form"),this.formElements,this.requiredElements,this.submitButton,this.resetButton,this.allRequiredValid=!1,this.debounce=this.debounce.bind(this),this.handleInput=this.handleInput.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.reset=this.reset.bind(this)}debounce(t,e){let n=null;return(...s)=>{window.clearTimeout(n),n=window.setTimeout(()=>{t.apply(null,s)},e)}}handleInput(t){this.allRequiredValid=this.requiredElements.every(t=>t.isValid),this.submitButton&&(this.allRequiredValid?this.submitButton.disabled=!1:this.submitButton.disabled=!0)}handleKeydown(t){"Enter"===t.key&&this.allRequiredValid&&this.submitButton.click()}reset(){this.formElements.forEach(t=>t.reset())}connectedCallback(){const t=this.shadowRoot.querySelector("slot");t.addEventListener("slotchange",t=>{this.formElements=[...this.querySelectorAll("sm-input, sm-textarea, sm-checkbox, tags-input, file-input, sm-switch, sm-radio")],this.requiredElements=this.formElements.filter(t=>t.hasAttribute("required")),this.submitButton=t.target.assignedElements().find(t=>"primary"===t.getAttribute("variant")||"submit"===t.getAttribute("type")),this.resetButton=t.target.assignedElements().find(t=>"reset"===t.getAttribute("type")),this.resetButton&&this.resetButton.addEventListener("click",this.reset)}),this.addEventListener("input",this.debounce(this.handleInput,100)),this.addEventListener("keydown",this.debounce(this.handleKeydown,100))}disconnectedCallback(){this.removeEventListener("input",this.debounce(this.handleInput,100)),this.removeEventListener("keydown",this.debounce(this.handleKeydown,100))}}); +const smInput=document.createElement("template");smInput.innerHTML='\n\n
\n \n \n
\n',customElements.define("sm-input",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smInput.content.cloneNode(!0)),this.inputParent=this.shadowRoot.querySelector(".input"),this.input=this.shadowRoot.querySelector("input"),this.clearBtn=this.shadowRoot.querySelector(".clear"),this.label=this.shadowRoot.querySelector(".label"),this.feedbackText=this.shadowRoot.querySelector(".feedback-text"),this._helperText,this._errorText,this.isRequired=!1,this.validationFunction,this.reflectedAttributes=["value","required","disabled","type","inputmode","readonly","min","max","pattern","minlength","maxlength","step"],this.reset=this.reset.bind(this),this.focusIn=this.focusIn.bind(this),this.focusOut=this.focusOut.bind(this),this.fireEvent=this.fireEvent.bind(this),this.checkInput=this.checkInput.bind(this)}static get observedAttributes(){return["value","placeholder","required","disabled","type","inputmode","readonly","min","max","pattern","minlength","maxlength","step","helper-text","error-text"]}get value(){return this.input.value}set value(t){this.input.value=t,this.checkInput(),this.fireEvent()}get placeholder(){return this.getAttribute("placeholder")}set placeholder(t){this.setAttribute("placeholder",t)}get type(){return this.getAttribute("type")}set type(t){this.setAttribute("type",t)}get isValid(){const t=this.input.checkValidity();let e=!0;return this.customValidation&&(e=this.validationFunction(this.input.value)),t&&e}get validity(){return this.input.validity}set disabled(t){t?this.inputParent.classList.add("disabled"):this.inputParent.classList.remove("disabled")}set readOnly(t){t?this.setAttribute("readonly",""):this.removeAttribute("readonly")}set customValidation(t){this.validationFunction=t}set errorText(t){this._errorText=t}set helperText(t){this._helperText=t}reset(){this.value=""}focusIn(){this.input.focus()}focusOut(){this.input.blur()}fireEvent(){let t=new Event("input",{bubbles:!0,cancelable:!0,composed:!0});this.dispatchEvent(t)}checkInput(t){this.hasAttribute("readonly")||(""!==this.input.value?this.clearBtn.classList.remove("hide"):(this.clearBtn.classList.add("hide"),this.isRequired&&(this.feedbackText.textContent="* required")),this.isValid?(this.feedbackText.classList.remove("error"),this.feedbackText.classList.add("success"),this.feedbackText.textContent=""):this._errorText&&(this.feedbackText.classList.add("error"),this.feedbackText.classList.remove("success"),this.feedbackText.innerHTML=`\n \n ${this._errorText}\n `)),this.hasAttribute("placeholder")&&""!==this.getAttribute("placeholder").trim()&&(""!==this.input.value?this.animate?this.inputParent.classList.add("animate-label"):this.label.classList.add("hide"):this.animate?this.inputParent.classList.remove("animate-label"):this.label.classList.remove("hide"))}connectedCallback(){this.animate=this.hasAttribute("animate"),this.input.addEventListener("input",this.checkInput),this.clearBtn.addEventListener("click",this.reset)}attributeChangedCallback(t,e,n){e!==n&&(this.reflectedAttributes.includes(t)&&(this.hasAttribute(t)?this.input.setAttribute(t,this.getAttribute(t)?this.getAttribute(t):""):this.input.removeAttribute(t)),"placeholder"===t?(this.label.textContent=n,this.setAttribute("aria-label",n)):this.hasAttribute("value")?this.checkInput():"type"===t?this.hasAttribute("type")&&"number"===this.getAttribute("type")&&this.input.setAttribute("inputmode","numeric"):"helper-text"===t?this._helperText=this.getAttribute("helper-text"):"error-text"===t?this._errorText=this.getAttribute("error-text"):"required"===t?(this.isRequired=this.hasAttribute("required"),this.feedbackText.textContent="* required"):"readonly"===t?this.hasAttribute("readonly")?this.inputParent.classList.add("readonly"):this.inputParent.classList.remove("readonly"):"disabled"===t&&(this.hasAttribute("disabled")?this.inputParent.classList.add("disabled"):this.inputParent.classList.remove("disabled")))}disconnectedCallback(){this.input.removeEventListener("input",this.checkInput),this.clearBtn.removeEventListener("click",this.reset)}}); +const smMenu=document.createElement("template");smMenu.innerHTML='\n\n
\n \n
\n \n
\n
',customElements.define("sm-menu",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smMenu.content.cloneNode(!0)),this.isOpen=!1,this.availableOptions,this.containerDimensions,this.animOptions={duration:200,easing:"ease"},this.optionList=this.shadowRoot.querySelector(".options"),this.menu=this.shadowRoot.querySelector(".menu"),this.icon=this.shadowRoot.querySelector(".icon"),this.expand=this.expand.bind(this),this.collapse=this.collapse.bind(this),this.toggle=this.toggle.bind(this),this.handleKeyDown=this.handleKeyDown.bind(this),this.handleClickoutSide=this.handleClickoutSide.bind(this)}static get observedAttributes(){return["value"]}get value(){return this.getAttribute("value")}set value(n){this.setAttribute("value",n)}expand(){this.isOpen||(this.optionList.classList.remove("hide"),this.optionList.animate([{transform:window.innerWidth<640?"translateY(1.5rem)":"translateY(-1rem)",opacity:"0"},{transform:"none",opacity:"1"}],this.animOptions).onfinish=(()=>{this.isOpen=!0,this.icon.classList.add("focused")}))}collapse(){this.isOpen&&(this.optionList.animate([{transform:"none",opacity:"1"},{transform:window.innerWidth<640?"translateY(1.5rem)":"translateY(-1rem)",opacity:"0"}],this.animOptions).onfinish=(()=>{this.isOpen=!1,this.icon.classList.remove("focused"),this.optionList.classList.add("hide")}))}toggle(){this.isOpen?this.collapse():this.expand()}handleKeyDown(n){n.target===this?"ArrowDown"===n.code?(n.preventDefault(),this.availableOptions[0].focus()):"Enter"!==n.code&&"Space"!==n.code||(n.preventDefault(),this.toggle()):"ArrowUp"===n.code?(n.preventDefault(),document.activeElement.previousElementSibling?document.activeElement.previousElementSibling.focus():this.availableOptions[this.availableOptions.length-1].focus()):"ArrowDown"===n.code?(n.preventDefault(),document.activeElement.nextElementSibling?document.activeElement.nextElementSibling.focus():this.availableOptions[0].focus()):"Enter"!==n.code&&"Space"!==n.code||(n.preventDefault(),n.target.click())}handleClickoutSide(n){this.contains(n.target)||2===n.button||this.collapse()}connectedCallback(){this.setAttribute("role","listbox"),this.setAttribute("aria-label","dropdown menu");const n=this.shadowRoot.querySelector(".options slot");n.addEventListener("slotchange",n=>{this.availableOptions=n.target.assignedElements(),this.containerDimensions=this.optionList.getBoundingClientRect()}),this.addEventListener("click",this.toggle),this.addEventListener("keydown",this.handleKeyDown),document.addEventListener("mousedown",this.handleClickoutSide)}disconnectedCallback(){this.removeEventListener("click",this.toggle),this.removeEventListener("keydown",this.handleKeyDown),document.removeEventListener("mousedown",this.handleClickoutSide)}});const menuOption=document.createElement("template");menuOption.innerHTML='\n\n
\n \n
',customElements.define("menu-option",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(menuOption.content.cloneNode(!0))}connectedCallback(){this.setAttribute("role","option"),this.addEventListener("keyup",n=>{"Enter"!==n.code&&"Space"!==n.code||(n.preventDefault(),this.click())})}}); +const smNotifications=document.createElement("template");smNotifications.innerHTML='\n\n
\n',customElements.define("sm-notifications",class extends HTMLElement{constructor(){super(),this.shadow=this.attachShadow({mode:"open"}).append(smNotifications.content.cloneNode(!0)),this.notificationPanel=this.shadowRoot.querySelector(".notification-panel"),this.animationOptions={duration:300,fill:"forwards",easing:"cubic-bezier(0.175, 0.885, 0.32, 1.275)"},this.push=this.push.bind(this),this.createNotification=this.createNotification.bind(this),this.removeNotification=this.removeNotification.bind(this),this.clearAll=this.clearAll.bind(this)}randString(n){let t="";const i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";for(let o=0;o${o}\n

${n}

\n `,i&&(e.classList.add("pinned"),a+='\n \n '),e.innerHTML=a,e}push(n,t={}){const i=this.createNotification(n,t);return this.notificationPanel.append(i),i.animate([{transform:"translateY(1rem)",opacity:"0"},{transform:"none",opacity:"1"}],this.animationOptions),i.id}removeNotification(n){n.animate([{transform:"none",opacity:"1"},{transform:"translateY(0.5rem)",opacity:"0"}],this.animationOptions).onfinish=(()=>{n.remove()})}clearAll(){Array.from(this.notificationPanel.children).forEach(n=>{this.removeNotification(n)})}connectedCallback(){this.notificationPanel.addEventListener("click",n=>{n.target.closest(".close")&&this.removeNotification(n.target.closest(".notification"))});const n=new MutationObserver(n=>{n.forEach(n=>{"childList"===n.type&&n.addedNodes.length&&!n.addedNodes[0].classList.contains("pinned")&&setTimeout(()=>{this.removeNotification(n.addedNodes[0])},5e3)})});n.observe(this.notificationPanel,{childList:!0})}}); +const smPopup=document.createElement("template");smPopup.innerHTML='\n\n\n',customElements.define("sm-popup",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smPopup.content.cloneNode(!0)),this.allowClosing=!1,this.isOpen=!1,this.pinned=!1,this.popupStack,this.offset,this.touchStartY=0,this.touchEndY=0,this.touchStartTime=0,this.touchEndTime=0,this.touchEndAnimataion,this.popupContainer=this.shadowRoot.querySelector(".popup-container"),this.popup=this.shadowRoot.querySelector(".popup"),this.popupBodySlot=this.shadowRoot.querySelector(".popup-body slot"),this.popupHeader=this.shadowRoot.querySelector(".popup-top"),this.resumeScrolling=this.resumeScrolling.bind(this),this.show=this.show.bind(this),this.hide=this.hide.bind(this),this.handleTouchStart=this.handleTouchStart.bind(this),this.handleTouchMove=this.handleTouchMove.bind(this),this.handleTouchEnd=this.handleTouchEnd.bind(this),this.movePopup=this.movePopup.bind(this)}static get observedAttributes(){return["open"]}get open(){return this.isOpen}resumeScrolling(){const t=document.body.style.top;window.scrollTo(0,-1*parseInt(t||"0")),setTimeout(()=>{document.body.style.overflow="auto",document.body.style.top="initial"},300)}show(t={}){const{pinned:e=!1,popupStack:n}=t;return n&&(this.popupStack=n),this.popupStack&&!this.hasAttribute("open")&&(this.popupStack.push({popup:this,permission:e}),this.popupStack.items.length>1&&this.popupStack.items[this.popupStack.items.length-2].popup.classList.add("stacked"),this.dispatchEvent(new CustomEvent("popupopened",{bubbles:!0,detail:{popup:this,popupStack:this.popupStack}})),this.setAttribute("open",""),this.pinned=e,this.isOpen=!0),this.popupContainer.classList.remove("hide"),this.popup.style.transform="none",document.body.style.overflow="hidden",document.body.style.top=`-${window.scrollY}px`,this.popupStack}hide(){window.innerWidth<640?this.popup.style.transform="translateY(100%)":this.popup.style.transform="translateY(3rem)",this.popupContainer.classList.add("hide"),this.removeAttribute("open"),void 0!==this.popupStack?(this.popupStack.pop(),this.popupStack.items.length?this.popupStack.items[this.popupStack.items.length-1].popup.classList.remove("stacked"):this.resumeScrolling()):this.resumeScrolling(),this.forms.length&&setTimeout(()=>{this.forms.forEach(t=>t.reset())},300),setTimeout(()=>{this.dispatchEvent(new CustomEvent("popupclosed",{bubbles:!0,detail:{popup:this,popupStack:this.popupStack}})),this.isOpen=!1},300)}handleTouchStart(t){this.touchStartY=t.changedTouches[0].clientY,this.popup.style.transition="transform 0.1s",this.touchStartTime=t.timeStamp}handleTouchMove(t){this.touchStartYthis.movePopup()))}handleTouchEnd(t){if(this.touchEndTime=t.timeStamp,cancelAnimationFrame(this.touchEndAnimataion),this.touchEndY=t.changedTouches[0].clientY,this.popup.style.transition="transform 0.3s",this.threshold=.3*this.popup.getBoundingClientRect().height,this.touchEndTime-this.touchStartTime>200)if(this.touchEndY-this.touchStartY>this.threshold){if(this.pinned)return void this.show();this.hide()}else this.show();else if(this.touchEndY>this.touchStartY){if(this.pinned)return void this.show();this.hide()}}movePopup(){this.popup.style.transform=`translateY(${this.offset}px)`}connectedCallback(){this.popupBodySlot.addEventListener("slotchange",()=>{this.forms=this.querySelectorAll("sm-form")}),this.popupContainer.addEventListener("mousedown",t=>{t.target!==this.popupContainer||this.pinned||(this.pinned?this.show():this.hide())});const t=new ResizeObserver(t=>{for(let e of t)if(e.contentBoxSize){Array.isArray(e.contentBoxSize)?e.contentBoxSize[0]:e.contentBoxSize;this.threshold=.3*e.blockSize.height}else this.threshold=.3*e.contentRect.height});t.observe(this),this.popupHeader.addEventListener("touchstart",t=>{this.handleTouchStart(t)},{passive:!0}),this.popupHeader.addEventListener("touchmove",t=>{this.handleTouchMove(t)},{passive:!0}),this.popupHeader.addEventListener("touchend",t=>{this.handleTouchEnd(t)},{passive:!0})}disconnectedCallback(){this.popupHeader.removeEventListener("touchstart",this.handleTouchStart,{passive:!0}),this.popupHeader.removeEventListener("touchmove",this.handleTouchMove,{passive:!0}),this.popupHeader.removeEventListener("touchend",this.handleTouchEnd,{passive:!0}),resizeObserver.unobserve()}attributeChangedCallback(t,e,n){"open"===t&&this.hasAttribute("open")&&this.show()}}); +const smTabHeader=document.createElement("template");smTabHeader.innerHTML='\n\n
\n
\n \n
\n
\n
\n',customElements.define("sm-tab-header",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smTabHeader.content.cloneNode(!0)),this.prevTab,this.allTabs,this.activeTab,this.indicator=this.shadowRoot.querySelector(".indicator"),this.tabSlot=this.shadowRoot.querySelector("slot"),this.tabHeader=this.shadowRoot.querySelector(".tab-header"),this.changeTab=this.changeTab.bind(this),this.handleClick=this.handleClick.bind(this),this.handlePanelChange=this.handlePanelChange.bind(this)}fireEvent(t){this.dispatchEvent(new CustomEvent(`switchedtab${this.target}`,{bubbles:!0,detail:{index:parseInt(t)}}))}moveIndiactor(t){this.indicator.setAttribute("style",`width: ${t.width}px; transform: translateX(${t.left-this.tabHeader.getBoundingClientRect().left+this.tabHeader.scrollLeft}px)`)}changeTab(t){t!==this.prevTab&&t.closest("sm-tab")&&(this.prevTab&&this.prevTab.classList.remove("active"),t.classList.add("active"),t.scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"}),this.moveIndiactor(t.getBoundingClientRect()),this.prevTab=t,this.activeTab=t)}handleClick(t){t.target.closest("sm-tab")&&(this.changeTab(t.target),this.fireEvent(t.target.dataset.index))}handlePanelChange(t){this.changeTab(this.allTabs[t.detail.index])}connectedCallback(){if(!this.hasAttribute("target")||""===this.getAttribute("target").value)return;this.target=this.getAttribute("target"),this.tabSlot.addEventListener("slotchange",()=>{this.allTabs=this.tabSlot.assignedElements(),this.allTabs.forEach((t,n)=>{t.dataset.index=n})}),this.addEventListener("click",this.handleClick),document.addEventListener(`switchedpanel${this.target}`,this.handlePanelChange);let t=new ResizeObserver(t=>{t.forEach(t=>{if(this.prevTab){let t=this.activeTab.getBoundingClientRect();this.moveIndiactor(t)}})});t.observe(this);let n=new IntersectionObserver(t=>{t.forEach(t=>{if(t.isIntersecting)if(this.indicator.style.transition="none",this.activeTab){let t=this.activeTab.getBoundingClientRect();this.moveIndiactor(t)}else{this.allTabs[0].classList.add("active");let t=this.allTabs[0].getBoundingClientRect();this.moveIndiactor(t),this.fireEvent(0),this.prevTab=this.tabSlot.assignedElements()[0],this.activeTab=this.prevTab}})},{threshold:1});n.observe(this)}disconnectedCallback(){this.removeEventListener("click",this.handleClick),document.removeEventListener(`switchedpanel${this.target}`,this.handlePanelChange)}});const smTab=document.createElement("template");smTab.innerHTML='\n\n
\n\n
\n',customElements.define("sm-tab",class extends HTMLElement{constructor(){super(),this.shadow=this.attachShadow({mode:"open"}).append(smTab.content.cloneNode(!0))}});const smTabPanels=document.createElement("template");smTabPanels.innerHTML='\n\n
\n Nothing to see here.\n
\n',customElements.define("sm-tab-panels",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smTabPanels.content.cloneNode(!0)),this.isTransitioning=!1,this.panelContainer=this.shadowRoot.querySelector(".panel-container"),this.panelSlot=this.shadowRoot.querySelector("slot"),this.handleTabChange=this.handleTabChange.bind(this)}handleTabChange(t){this.isTransitioning=!0,this.panelContainer.scrollTo({left:this.allPanels[t.detail.index].getBoundingClientRect().left-this.panelContainer.getBoundingClientRect().left+this.panelContainer.scrollLeft,behavior:"smooth"}),setTimeout(()=>{this.isTransitioning=!1},300)}fireEvent(t){this.dispatchEvent(new CustomEvent(`switchedpanel${this.id}`,{bubbles:!0,detail:{index:parseInt(t)}}))}connectedCallback(){this.panelSlot.addEventListener("slotchange",()=>{this.allPanels=this.panelSlot.assignedElements(),this.allPanels.forEach((n,e)=>{n.dataset.index=e,t.observe(n)})}),document.addEventListener(`switchedtab${this.id}`,this.handleTabChange);const t=new IntersectionObserver(t=>{t.forEach(t=>{!this.isTransitioning&&t.isIntersecting&&this.fireEvent(t.target.dataset.index)})},{threshold:.6})}disconnectedCallback(){intersectionObserver.disconnect(),document.removeEventListener(`switchedtab${this.id}`,this.handleTabChange)}}); +const themeToggle=document.createElement("template");themeToggle.innerHTML='\n \n \n';class ThemeToggle extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(themeToggle.content.cloneNode(!0)),this.isChecked=!1,this.hasTheme="light",this.toggleState=this.toggleState.bind(this),this.fireEvent=this.fireEvent.bind(this),this.handleThemeChange=this.handleThemeChange.bind(this)}static get observedAttributes(){return["checked"]}daylight(){this.hasTheme="light",document.body.dataset.theme="light",this.setAttribute("aria-checked","false")}nightlight(){this.hasTheme="dark",document.body.dataset.theme="dark",this.setAttribute("aria-checked","true")}toggleState(){this.toggleAttribute("checked"),this.fireEvent()}handleKeyDown(e){"Space"===e.code&&this.toggleState()}handleThemeChange(e){e.detail.theme!==this.hasTheme&&("dark"===e.detail.theme?this.setAttribute("checked",""):this.removeAttribute("checked"))}fireEvent(){this.dispatchEvent(new CustomEvent("themechange",{bubbles:!0,composed:!0,detail:{theme:this.hasTheme}}))}connectedCallback(){this.setAttribute("role","switch"),this.setAttribute("aria-label","theme toggle"),"dark"===localStorage.theme?(this.nightlight(),this.setAttribute("checked","")):"light"===localStorage.theme?(this.daylight(),this.removeAttribute("checked")):window.matchMedia("(prefers-color-scheme: dark)").matches?(this.nightlight(),this.setAttribute("checked","")):(this.daylight(),this.removeAttribute("checked")),this.addEventListener("click",this.toggleState),this.addEventListener("keydown",this.handleKeyDown),document.addEventListener("themechange",this.handleThemeChange)}disconnectedCallback(){this.removeEventListener("click",this.toggleState),this.removeEventListener("keydown",this.handleKeyDown),document.removeEventListener("themechange",this.handleThemeChange)}attributeChangedCallback(e,t,n){"checked"===e&&(this.hasAttribute("checked")?(this.nightlight(),localStorage.setItem("theme","dark")):(this.daylight(),localStorage.setItem("theme","light")))}}window.customElements.define("theme-toggle",ThemeToggle); \ No newline at end of file diff --git a/js/main.js b/js/main.js new file mode 100644 index 0000000..042fac2 --- /dev/null +++ b/js/main.js @@ -0,0 +1,618 @@ +const main = (ready) => { + if (ready) { + document.body.addEventListener("keydown", (e) => { + if (e.key === "/") { + e.preventDefault(); + searchWrapper.classList.add("open"); + let el = document.getElementById("input"); + el.focusIn(); + } + }); + let _input = document.querySelector("#input"); + let _backBtn = document.querySelector("#logo"); + let home = document.getElementById("home"); + let searchToggle = document.getElementById("searchToggle"); + let searchOverlay = document.querySelector(".search-overlay"); + let searchWrapper = document.querySelector(".search-wrapper"); + let _getTemplate = document.getElementById("myTemplate"); + let _cardTemplate = document.getElementById("cardTemplate"); + let internRating = {}; + function getDate(time) { + let stringTime = time + "000"; + let newTime = new Date(+stringTime).toDateString(); + return newTime; + } + searchToggle.addEventListener("click", () => { + searchWrapper.classList.add("open"); + _input.focus(); + }); + searchOverlay.addEventListener("click", () => { + searchWrapper.classList.remove("open"); + }); + /** + * On changing the search input + * - Update the DOM and fill the result + * - if there is nothing set all the element to the DOM + */ + _input.addEventListener("input", (e) => { + // @ts-ignore + let val = e.target.value; + window.location.hash = ""; + if (finalList.length !== 0) { + const list = finalList.filter((element) => { + let newUserName = element.name.slice(0, val.length); + return newUserName.toLowerCase() === val.toLowerCase(); + }); + if (list.length) { + _rootDiv.innerHTML = renderList(list); + } + else { + _rootDiv.innerHTML = renderList(finalList); + } + } + else { + return ` +

Loading...

+ `; + } + }); + // intern Data "const internList = []" + // + // Data from distributer "const distributerData = []" + // + // filter the transaction of interns from the distributer + const receiverList = []; + const internList = []; + let finalList = []; + customElements.define("my-card", class MyCard extends HTMLElement { + displayUsername; + displayUserId; + // look all the value we have to look on change + static get observedAttributes() { + return ["username", "userid"]; + } + constructor() { + super(); + // attach the shadow DOM + this.attachShadow({ mode: "open" }); + } + get username() { + return this.getAttribute("username"); + } + get userid() { + return this.getAttribute("userid"); + } + set username(val) { + this.setAttribute("username", val); + } + set userid(val) { + this.setAttribute("userid", val); + } + // @ts-ignore + attributeChangedCallback(name, oldValue, newValue) { + if (oldValue !== newValue && this.displayUsername) { + this.displayUsername.innerText = this.username; + this.displayUserId.innerText = this.userid; + } + } + // run when the element attached to the DOM + connectedCallback() { + const template = document.createElement("template"); + template.innerHTML = this.render(); + const node = document.importNode(template.content, true); + this.shadowRoot.append(node); + // select the element from the shadow DOM and set the value + this.displayUsername = this.shadowRoot.querySelector(".username"); + this.displayUserId = this.shadowRoot.querySelector(".userid"); + this.shadowRoot + .querySelector("span") + .addEventListener("click", (e) => { + // back to the home page + window.location.hash = ""; + _rootDiv.innerHTML = renderList(); + }); + } + // render the element to the DOM + render() { + if (finalList.length) { + let el = document.createElement("div"); + let backBtn = document.createElement("div"); + let username = document.createElement("h2"); + let floId = document.createElement("h3"); + let projectName = document.createElement("h4"); + let profile = document.createElement("div"); + let totalMoneyEarned = document.createElement("div"); + let totalNumberOfTransaction = document.createElement("div"); + const myResult = finalList.filter((l) => { + return this.userid.slice(1) === l.floId; + }); + myResult.forEach((r) => { + let txData = document.createElement("ul"); + let red = document.createElement("span"); + let totalAmount = 0; + profile.classList.add("profile"); + username.innerText = r.name; + floId.innerText = this.userid.slice(1); + projectName.innerText = `Project - ${r.projectName || "Intern Inactive"}`; + totalNumberOfTransaction.innerText = `Total Number of transactions - ${r.transactions.length}`; + username.style.textAlign = "left"; + red.innerHTML = ` + + + + `; + backBtn.classList.add("back-btn"); + backBtn.append(red); + if (r.transactions.length) { + r.transactions.forEach((t) => { + let amount = t.transaction.floData.match(/([0-9]+)/); + let num = Number(amount[0]); + let senderAddress = t.transaction.vin[0].addr; + let time = getDate(t.transaction.time); + let li = document.createElement("li"); + li.style.margin = "1em 0em"; + totalAmount += num; + li.innerHTML = ` +
+
₹${amount[0]}/-
+
${time}
+

Transaction Detail

+
Message - ${t.transaction.floData}
+
Sent from - RanchiMall Distribution Address "${senderAddress}"
+ ${t.transaction.blockChainLink} +
+ `; + txData.appendChild(li); + }); + } + else { + let li = document.createElement("div"); + li.innerText = "No Transaction Found"; + txData.appendChild(li); + } + totalMoneyEarned.classList.add("totalAmount"); + totalMoneyEarned.innerHTML = ` +
₹${totalAmount}
+
Total Amount Paid
+ `; + let styling = document.createElement("style"); + styling.innerHTML = ` + * { box-sizing: border-box; } + + ul { + padding: 0em; + list-style-type: none; + } + + h4 { + margin-bottom: 2.5em; + } + + h5 { + margin: 1em 0em; + } + + a { + padding: 1em 0em; + color: #64b5f6; + } + + svg { + width: 45px; + } + + .profile { + width: 50px; + height: 50px; + background: #64b5f6; + border-radius: 50%; + margin-bottom: 1em; + } + + .back-btn { + background: rgba(var(--background-color), 1); + position: sticky; + top: 0; + z-index: 2; + } + + span { + font-size: 4em; + display: flex; + align-items: center; + cursor: pointer; + } + + .totalAmount { + position: absolute; + top: 1em; + right: 1em; + font-size: 1.5em; + } + + .card { + padding: 1.5rem; + display: flex; + flex-direction: column; + position: relative; + width: 100%; + min-width: 20rem; + border-radius: 0.5rem; + flex: 1 0; + background-color: rgba(var(--text-color), 0.06); + } + + .card > div:nth-of-type(1) { + margin: 0.5em 0em; + font-size: 3.5em; + } + + .card > div:nth-of-type(2) { + position: absolute; + right: 1em; + top: 1em; + width: max-content; + background: rgba(var(--background-color), 1); + padding: 0.4em; + border-radius: 0.5rem; + } + `; + el.appendChild(backBtn); + el.appendChild(styling); + //el.appendChild(profile); + el.appendChild(username); + el.appendChild(floId); + el.appendChild(projectName); + el.appendChild(totalMoneyEarned); + el.appendChild(totalNumberOfTransaction); + el.appendChild(txData); + }); + return el.innerHTML; + } + } + }); + let path = { + current: window.location.hash || "#", + printPath: () => { }, + }; + const _rootDiv = document.getElementById("uInfo"); + // render all the list of the use on to the DOM + /*function renderList() { + + if (finalList.length !== 0) { + let el: HTMLDivElement = document.createElement("div"); + let heading: HTMLHeadElement = document.createElement("h2"); + heading.innerText = "RanchiMall Internship Blockchain Contract"; + heading.style.textAlign = "center"; + heading.style.width = "100%"; + heading.style.padding = "2em 0.5em"; + + el.appendChild(heading); + + for (let i of finalList) { + let card: HTMLAnchorElement = document.createElement("div"); + let link = document.createElement("a"); + + link.innerText = + i.transactions[0].transaction.blockChainLink; + link.href = i.transactions[0].transaction.blockChainLink; + link.target = "_blank"; + link.style.marginTop = "0em"; + + card.classList.add("card"); + card.href = `#${i.floId}`; + let amount = i.transactions[0].transaction.floData.match( + /([0-9]+)/ + ); + card.innerHTML = ` + +
+

${i.name}

+
${i.floId}
+
Total amount paid: ₹${i.totalMoneyEarned}
+
Total no. of transaction: ${i.transactions.length + }
+
+
Last transaction
+
+
${getDate( + i.transactions[0].transaction.time + )}
+
₹${amount[0] + }
+
+
+
${internRating[i.floId]}
+
+
View last payment blockchain
+ ${i.transactions[0].transaction.blockChainLink} + `; + el.appendChild(card); + } + return el.innerHTML; + } else { + return ` +

Loading...

+ `; + } + }*/ + function renderList(data) { + // check if the finallist have any length + if (data.length !== 0) { + // get the template from the DOM + // get the deep copy the template + let node = _getTemplate.content.cloneNode(true); + for (let i of data) { + let amount = i.transactions[0].transaction.floData.match(/([0-9]+)/); + // + let cardNode = _cardTemplate.content.cloneNode(true); + cardNode.querySelector(".link").href = `#${i.floId}`; + cardNode.querySelector(".heading-name").textContent = + i.name; + cardNode.querySelector(".heading-floId").textContent = + i.floId; + cardNode.querySelector(".total-money-earned").textContent = `Total amount paid: ₹${i.totalMoneyEarned}`; + cardNode.querySelector(".number-of-transaction").textContent = `Total number of transactions: ${i.transactions.length}`; + cardNode.querySelector(".last-tx-content").textContent = getDate(i.transactions[0].transaction.time); + cardNode.querySelector(".last-tx-amount").textContent = `₹${amount[0]}/-`; + cardNode.querySelector(".intern-rating").textContent = + internRating[i.floId]; + cardNode.querySelector(".blockchain-link").href = + i.transactions[0].transaction.blockChainLink; + node.querySelector(".card-wrapper").appendChild(cardNode); + } + let el = document.createElement("div"); + el.appendChild(node); + return el.innerHTML; + } + else { + return ` +

Loading...

+ `; + } + } + // render the details page + function renderDetail() { + return ` + + `; + } + let routes = { + "#": renderList(finalList), + "#detail": renderDetail(), + }; + /** + * Run when there is change of hash on the window + * - get the first value from the routes object + * - check the value is matching to the comming route value + * - if so, render the home page otherwise detail page + */ + const handleRender = (route) => { + // ... + let val = Object.keys(routes)[0]; + if (val === route) { + _rootDiv.innerHTML = renderList(finalList); + } + else { + _rootDiv.innerHTML = renderDetail(); + } + }; + // check the change in hash + window.addEventListener("hashchange", (e) => { + // get the current path + path.current = window.location.hash || "#"; + /** + * @param always be the path of the window + */ + handleRender(path.current); + }); + // render the home page default + _rootDiv.innerHTML = renderList(finalList); + // Go the home page + _backBtn.addEventListener("click", () => { + window.location.hash = ""; + _rootDiv.innerHTML = renderList(); + }); + /** + * Creating a list in which store all the + * flo addresses of the receiver + */ + /** + * get the intern data from the RanchiMall + * - request the server for data + * - loop over the response + * - push the each data to the "finalList arrary" + * - call the fetchInternData() + */ + async function getInternData() { + try { + let r = await floCloudAPI.requestObjectData("RIBC", { + application: "RIBC", + receiverID: "FMeiptdJNtYQEtzyYAVNP8fjsDJ1i4EPfE", + senderIDs: [ + "F7TxecSPV8oFZE6Y2giVuP8hfsqfAD6erj", + "FCja6sLv58e3RMy41T5AmWyvXEWesqBCkX", + "FPFeL5PXzW9bGosUjQYCxTHSMHidnygvvd", + "FS4jMAcSimRMrhoRhk5cjuJERS2otiwq4A", + "FU2fkubqGD5ynbr7qhvaPe9DPqrNdGB6mw", + "FUkY9k9mVVxPzYA8uUGxUuLVH6CB83Nb9r", + ], + }); + if (r) { + let i = floGlobals.appObjects.RIBC.internList; + for (let key in i) { + internList.push({ + floId: key, + floUserName: i[key], + }); + } + // fetch all the data and pack together + fetchInternData(); + } + } + catch (e) { + // ERROR HANDLING + console.log("Error Occur while fetching the Intern Data", e); + _rootDiv.innerHTML = ` +
+

Something Went Wrong [keep Refreshing the page ...]

+

${e}

+
+ `; + } + } + function bundleAllData() { + // get the internList from the server + let internList = floGlobals.appObjects.RIBC.internList; + internRating = floGlobals.appObjects.RIBC.internRating; + // get the intern Assigned project from the server + // get the value of internAssigned project + let internsAssigned = floGlobals.appObjects.RIBC.internsAssigned; + const internsAssignedArr = Object.entries(internsAssigned); + // get the project details from the server + let projectDetails = floGlobals.appObjects.RIBC.projectDetails; + // set the tragetList + let tragetList = []; + // loop over the intern data + for (let internId in internList) { + // loop over the intern assigned project so we get the + // associated projects + for (let [k, v] of internsAssignedArr) { + // find the value have correct key + let value = v.find((el) => { + return el === internId; + }); + // if we find a value find its project Details also + if (value) { + // loop over the project details + for (let i in projectDetails) { + // find out the key by the slicing it + let key = k.slice(0, 14); + // get the value + let newVal = projectDetails[key]; + // send it ot targetList + tragetList.push({ + internId: internId, + project: k, + projectName: newVal.projectName, + }); + } + } + } + } + // loop over to the finalList to attach the projectName + for (let key in tragetList) { + // get the internId from the tragetList + let val = tragetList[key].internId; + // get the index out of that + let index = finalList.findIndex((el) => el.floId === val); + // if it exists + if (index > -1) { + finalList[index].projectName = tragetList[key].projectName; + } + } + for (let index of finalList) { + let totalAmount = 0; + /*finalList[index].transactions.forEach((intern) => { + let amount = intern.transaction.floData.match(/([0-9]+)/); + let num = Number(amount[0]); + totalAmount += num; + }); + finalList[index].totalMoneyEarned = totalAmount;*/ + } + /** + * Loop over the final List to get the totalAmount + */ + finalList.forEach((list) => { + let totalAmount = 0; + list.transactions.forEach((intern) => { + let amount = intern.transaction.floData.match(/([0-9]+)/); + let num = Number(amount[0]); + totalAmount += num; + // add the blockChainLink key + //intern.transaction.blockChainLink = `https://livenet.flocha.in/block/${intern.transaction.blockhash}`; + intern.transaction.blockChainLink = `https://livenet.flocha.in/tx/${intern.transaction.txid}`; + }); + const transactionsDetails = list.transactions.sort((first, second) => { + return second.transaction.time - first.transaction.time; + }); + list.totalMoneyEarned = totalAmount; + list.transactions = transactionsDetails; + }); + const myArr = finalList.sort((first, second) => { + return (second.transactions[0].transaction.time - + first.transactions[0].transaction.time); + }); + finalList = myArr; + } + // get the internData after the 3sec I don't know why + setTimeout(() => { + getInternData(); + }, 1000); + /** + * Fetch initial transactions + * - request the distributer transactions from the server + * - push all these transactions to the "receiverList array" + * - then loop over to the interList array in which we collect interns data + * - filter out the transactions of the intern from the distributer transactions + * - push all the data to the new called finalList array + * - render the home page to the DOM + */ + function fetchInternData() { + floBlockchainAPI + .readAllTxs("FThgnJLcuStugLc24FJQggmp2WgaZjrBSn", "", "") + .then((r) => { + // loop over the response transactions + r.forEach((user) => { + // sending all the transaction to the new array + receiverList.push({ + floId: user.vout[0].scriptPubKey.addresses[0], + transaction: user, + }); + }); + // loop over the intern data + for (let d of internList) { + // filter the intern transactions + const result = receiverList.filter((i) => { + return i.floId === d.floId; + }); + // check if the transaction are available + if (result.length) { + // add all the transaction to the new Array + finalList.push({ + name: d.floUserName, + floId: d.floId, + transactions: [...result], + }); + } + } + bundleAllData(); + // re-render the DOM + _rootDiv.innerHTML = renderList(finalList); + }, console.error); + } + } +}; diff --git a/js/main_UI.js b/js/main_UI.js new file mode 100644 index 0000000..9057041 --- /dev/null +++ b/js/main_UI.js @@ -0,0 +1,305 @@ +// Global variables +const appPages = ['dashboard', 'settings']; +const domRefs = {}; +let timerId; +const currentYear = new Date().getFullYear(); + +//Checks for internet connection status +if (!navigator.onLine) + notify( + "There seems to be a problem connecting to the internet, Please check you internet connection.", + "error", + { sound: true } + ); +window.addEventListener("offline", () => { + notify( + "There seems to be a problem connecting to the internet, Please check you internet connection.", + "error", + { pinned: true, sound: true } + ); +}); +window.addEventListener("online", () => { + getRef("notification_drawer").clearAll(); + notify("We are back online.", "success"); +}); + +// Use instead of document.getElementById +function getRef(elementId) { + if (!domRefs.hasOwnProperty(elementId)) { + domRefs[elementId] = { + count: 1, + ref: null, + }; + return document.getElementById(elementId); + } else { + if (domRefs[elementId].count < 3) { + domRefs[elementId].count = domRefs[elementId].count + 1; + return document.getElementById(elementId); + } else { + if (!domRefs[elementId].ref) + domRefs[elementId].ref = document.getElementById(elementId); + return domRefs[elementId].ref; + } + } +} + +// returns dom with specified element +function createElement(tagName, options) { + const { className, textContent, innerHTML, attributes = {} } = options + const elem = document.createElement(tagName) + for (let attribute in attributes) { + elem.setAttribute(attribute, attributes[attribute]) + } + if (className) + elem.className = className + if (textContent) + elem.textContent = textContent + if (innerHTML) + elem.innerHTML = innerHTML + return elem +} + +// Use when a function needs to be executed after user finishes changes +const debounce = (callback, wait) => { + let timeoutId = null; + return (...args) => { + window.clearTimeout(timeoutId); + timeoutId = window.setTimeout(() => { + callback.apply(null, args); + }, wait); + }; +} + +// Limits the rate of function execution +function throttle(func, delay) { + // If setTimeout is already scheduled, no need to do anything + if (timerId) { + return; + } + + // Schedule a setTimeout after delay seconds + timerId = setTimeout(function () { + func(); + + // Once setTimeout function execution is finished, timerId = undefined so that in + // the next scroll event function execution can be scheduled by the setTimeout + timerId = undefined; + }, delay); +} + +class Stack { + constructor() { + this.items = []; + } + push(element) { + this.items.push(element); + } + pop() { + if (this.items.length == 0) + return "Underflow"; + return this.items.pop(); + } + peek() { + return this.items[this.items.length - 1]; + } +} + +// function required for popups or modals to appear +function showPopup(popupId, pinned) { + zIndex++ + getRef(popupId).setAttribute('style', `z-index: ${zIndex}`) + popupStack = getRef(popupId).show({ pinned, popupStack }) + return getRef(popupId); +} + +// hides the popup or modal +function hidePopup() { + if (popupStack.peek() === undefined) + return; + popupStack.peek().popup.hide() +} + +// displays a popup for asking permission. Use this instead of JS confirm +const getConfirmation = (title, message, cancelText = 'Cancel', confirmText = 'OK') => { + return new Promise(resolve => { + showPopup('confirmation_popup', true) + getRef('confirm_title').textContent = title; + getRef('confirm_message').textContent = message; + let cancelButton = getRef('confirmation_popup').children[2].children[0], + submitButton = getRef('confirmation_popup').children[2].children[1] + submitButton.textContent = confirmText + cancelButton.textContent = cancelText + submitButton.onclick = () => { + hidePopup() + resolve(true); + } + cancelButton.onclick = () => { + hidePopup() + resolve(false); + } + }) +} + +// displays a popup for asking user input. Use this instead of JS prompt +async function getPromptInput(title, message = '', isPassword = true, cancelText = 'Cancel', confirmText = 'OK') { + showPopup('prompt_popup', true) + getRef('prompt_title').textContent = title; + let input = getRef('prompt_input'); + input.setAttribute("placeholder", message) + let buttons = getRef('prompt_popup').querySelectorAll("sm-button"); + if (isPassword) + input.setAttribute("type", "text") + else + input.setAttribute("type", "password") + input.focusIn() + buttons[0].textContent = cancelText; + buttons[1].textContent = confirmText; + return new Promise((resolve, reject) => { + buttons[0].onclick = () => { + hidePopup() + return; + } + buttons[1].onclick = () => { + let value = input.value; + hidePopup() + resolve(value) + } + }) +} + +//Function for displaying toast notifications. pass in error for mode param if you want to show an error. +function notify(message, mode, options = {}) { + const { pinned = false, sound = false } = options + let icon + switch (mode) { + case 'success': + icon = `` + break; + case 'error': + icon = `` + break; + } + getRef("notification_drawer").push(message, { pinned, icon }); + if (navigator.onLine && sound) { + getRef("notification_sound").currentTime = 0; + getRef("notification_sound").play(); + } +} + +function getFormatedTime(time, relative) { + try { + if (String(time).indexOf("_")) time = String(time).split("_")[0]; + const intTime = parseInt(time); + if (String(intTime).length < 13) time *= 1000; + let timeFrag = new Date(intTime).toString().split(" "), + day = timeFrag[0], + month = timeFrag[1], + date = timeFrag[2], + year = timeFrag[3], + minutes = new Date(intTime).getMinutes(), + hours = new Date(intTime).getHours(), + currentTime = new Date().toString().split(" "); + + minutes = minutes < 10 ? `0${minutes}` : minutes; + let finalHours = ``; + if (hours > 12) finalHours = `${hours - 12}:${minutes}`; + else if (hours === 0) finalHours = `12:${minutes}`; + else finalHours = `${hours}:${minutes}`; + + finalHours = hours >= 12 ? `${finalHours} PM` : `${finalHours} AM`; + if (relative) { + return `${date} ${month} ${year}`; + } else return `${finalHours} ${month} ${date} ${year}`; + } catch (e) { + console.error(e); + return time; + } +} + +window.addEventListener('hashchange', e => showPage(window.location.hash)) +window.addEventListener("load", () => { + document.body.classList.remove('hide-completely') + showPage(window.location.hash) + // document.querySelectorAll('sm-input[data-flo-id]').forEach(input => input.customValidation = validateAddr) + document.addEventListener('keyup', (e) => { + if (e.code === 'Escape') { + hidePopup() + } + }) + document.addEventListener("pointerdown", (e) => { + if (e.target.closest("button, sm-button:not([disabled]), .interact")) { + createRipple(e, e.target.closest("button, sm-button, .interact")); + } + }); + document.addEventListener('copy', () => { + notify('copied', 'success') + }) +}); + +function createRipple(event, target) { + const circle = document.createElement("span"); + const diameter = Math.max(target.clientWidth, target.clientHeight); + const radius = diameter / 2; + const 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( + [ + { + transform: "scale(3)", + opacity: 0, + }, + ], + { + duration: 1000, + fill: "forwards", + easing: "ease-out", + } + ); + target.append(circle); + rippleAnimation.onfinish = () => { + circle.remove(); + }; +} + +function showPage(targetPage, options = {}) { + const { firstLoad, hashChange } = options + let pageId + if (targetPage === '') { + pageId = 'overview_page' + } + else { + pageId = targetPage.includes('#') ? targetPage.split('#')[1] : targetPage + } + if(!appPages.includes(pageId)) return + document.querySelector('.page:not(.hide-completely)').classList.add('hide-completely') + document.querySelector('.nav-list__item--active').classList.remove('nav-list__item--active') + getRef(pageId).classList.remove('hide-completely') + getRef(pageId).animate([ + { + opacity: 0, + transform: 'translateX(-1rem)' + }, + { + opacity: 1, + transform: 'none' + }, + ], + { + duration: 300, + easing: 'ease' + }) + const targetListItem = document.querySelector(`.nav-list__item[href="#${pageId}"]`) + targetListItem.classList.add('nav-list__item--active') + if (firstLoad && window.innerWidth > 640 && targetListItem.getBoundingClientRect().top > getRef('side_nav').getBoundingClientRect().height) { + getRef('side_nav').scrollTo({ + top: (targetListItem.getBoundingClientRect().top - getRef('side_nav').getBoundingClientRect().top + getRef('side_nav').scrollTop), + behavior: 'smooth' + }) + } + if (hashChange && window.innerWidth < 640) { + getRef('side_nav').close() + } +} \ No newline at end of file