From 9519236662e845bd2e1efc823b9dede574027320 Mon Sep 17 00:00:00 2001 From: engineerTrooper Date: Sun, 15 Nov 2020 19:19:23 +0100 Subject: [PATCH] VENOM-10: added, fake tables with display:grid. create v-table as html dom element --- public/theme/admin/css/admin-panel.css | 2 +- public/theme/admin/css/style.css | 2 +- .../admin/images/icon/ic_arrow_back_24px.svg | 1 + .../admin/images/icon/ic_delete_24px.svg | 4 + public/theme/admin/js/scripts.js | 189 ++++++- public/theme/admin/js/scripts.min.js | 2 +- tpl/admin/admin-panel.php | 533 +++++++++++++++--- 7 files changed, 638 insertions(+), 95 deletions(-) create mode 100644 public/theme/admin/images/icon/ic_arrow_back_24px.svg create mode 100644 public/theme/admin/images/icon/ic_delete_24px.svg diff --git a/public/theme/admin/css/admin-panel.css b/public/theme/admin/css/admin-panel.css index cc90666..afdab4e 100644 --- a/public/theme/admin/css/admin-panel.css +++ b/public/theme/admin/css/admin-panel.css @@ -1 +1 @@ -:focus{outline:0}*{box-sizing:border-box}body,html{width:100vw;height:100vh;overflow:hidden;padding:0;margin:0;background:#1f2857;background:linear-gradient(144deg,#1f2954 25%,#000 50%,#5e002c 80%);background-attachment:fixed;color:#fff;font-family:sans-serif;font-size:16px}.hide{display:none!important}main{display:flex;height:100vh;overflow:hidden}.menu{width:220px;background-color:#1b1b1b;box-shadow:0 3px 6px rgba(0,0,0,.16),0 3px 6px rgba(0,0,0,.23);flex-shrink:0;display:flex;flex-direction:column}.menu .logo{text-align:center;font-family:monospace}.menu div[data-link]{padding:.75rem .5rem;position:relative}.menu div[data-link]:after{background-color:#3949ab;content:"";position:absolute;left:0;bottom:0;height:3px;width:100%;transform:scaleX(0);transition:transform .4s;transform-origin:left}.menu div[data-link]:hover:after{transform:scaleX(1)}.menu div[data-link]:last-child{margin-top:auto}.menu div[data-link].active{font-weight:700}.content-area{padding:0 1rem;margin:1rem 1.5rem;flex-grow:1;overflow-y:auto;max-height:100%;background:RGBA(27,27,27,.5)}.content-area .max-width{max-width:300px}.content-area hr{border:.5px solid #e9e9e9;box-shadow:0 10px 20px rgba(0,0,0,.19),0 6px 6px rgba(0,0,0,.23)}.content-area .text{display:flex;position:relative;padding:5px 0}.content-area .icon{display:inline-block;width:18px;height:18px;background-size:cover;margin:0 10px 0 auto;fill:#fff}.content-area .icon-add{background-image:url(../images/icon/ic_add_circle_outline_24px.svg)}.content-area .icon-edit{background-image:url(../images/icon/ic_edit_24px.svg)}.content-area .icon-visibility{background-image:url(../images/icon/ic_visibility_24px.svg)}.content-area .add-new-role{display:flex;position:relative;align-items:center;padding:0 0 5px 0} \ No newline at end of file +:focus{outline:0}*{box-sizing:border-box}body,html{width:100vw;height:100vh;overflow:hidden;padding:0;margin:0;background:#1f2857;background:linear-gradient(144deg,#1f2954 25%,#000 50%,#5e002c 80%);background-attachment:fixed;color:#fff;font-family:sans-serif;font-size:16px}.hide{display:none!important}v-table{display:block}v-table v-table-footer,v-table v-table-header,v-table v-table-row{display:grid;grid-auto-columns:1fr;grid-auto-flow:column;-moz-column-gap:20px;column-gap:20px}v-table v-table-header h2{text-align:center}v-table v-table-row{margin:10px 0}v-table .grid12{grid-template-columns:repeat(12,[col-start] 1fr);-moz-column-gap:5px;column-gap:5px}v-table .grid12 .col-1to4{grid-column:1/3}v-table .grid12 .col-1to6{grid-column:1/6}v-table .grid12 .col-5to6{grid-column:5/6}v-table .grid12 .col-6to11{grid-column:6/11}v-table .grid12 .col-6to9{grid-column:6/9}v-table .grid12 .col-9to10{grid-column:9/10}v-table .grid12 .col-11to13{grid-column:11/13}v-label,v-option,v-options,v-select{display:inline-block;box-sizing:border-box}v-select{display:block;position:relative;margin-bottom:.5rem}v-label{padding:.5rem 1rem;background-color:#3949ab;color:#fff;cursor:pointer;display:block;border-radius:4px}v-options{position:absolute;display:flex;border-radius:4px;flex-direction:column;overflow:hidden;max-height:0;top:.5rem;left:.5rem;background-color:#1b1b1b;z-index:1000;cursor:pointer;color:#fff;box-shadow:0 3px 6px rgba(0,0,0,.16),0 3px 6px rgba(0,0,0,.23)}v-option{padding:.5rem 1rem}v-option:not([disabled]):hover{background-color:rgba(0,0,0,.3)}v-option[selected]{background-color:#3949ab;color:#fff}v-option[disabled]{color:#aaa}main{display:flex;height:100vh;overflow:hidden}.menu{width:220px;background-color:#1b1b1b;box-shadow:0 3px 6px rgba(0,0,0,.16),0 3px 6px rgba(0,0,0,.23);flex-shrink:0;display:flex;flex-direction:column}.menu .logo{text-align:center;font-family:monospace}.menu div[data-link]{padding:.75rem .5rem;position:relative}.menu div[data-link]:after{background-color:#3949ab;content:"";position:absolute;left:0;bottom:0;height:3px;width:100%;transform:scaleX(0);transition:transform .4s;transform-origin:left}.menu div[data-link]:hover:after{transform:scaleX(1)}.menu div[data-link]:last-child{margin-top:auto}.menu div[data-link].active{font-weight:700}.content-area{padding:0 1%;margin:1rem 1.5rem;flex-grow:1;overflow-y:auto;width:100%;max-height:100%;background:rgba(27,27,27,.5)}.content-area .inline{display:inline}.content-area .inline div{display:inline}.content-area .btn-line{margin-top:35px}.content-area .btn-line div{text-align:right}.content-area .btn-line div button{display:inline;margin-left:10px;min-width:100px}.content-area .modules div{padding:6px 20px 6px 0}.content-area .icon-cont div{display:inline-block;vertical-align:middle;margin-top:5px}.content-area .icon-cont .icon{width:18px;height:18px;background-size:cover;margin:0 15px 0 0;fill:#fff}.content-area .icon-cont .icon-add{background-image:url(../images/icon/ic_add_circle_outline_24px.svg)}.content-area .icon-cont .icon-edit{background-image:url(../images/icon/ic_edit_24px.svg)}.content-area .icon-cont .icon-visibility{background-image:url(../images/icon/ic_visibility_24px.svg)}.content-area .icon-cont .icon-delete{background-image:url(../images/icon/ic_delete_24px.svg)}.content-area .icon-cont .icon-arrow-back{background-image:url(../images/icon/ic_arrow_back_24px.svg);width:24px;height:24px}.content-area .description{margin-top:25px}.content-area .fix-pad{padding-top:14px} \ No newline at end of file diff --git a/public/theme/admin/css/style.css b/public/theme/admin/css/style.css index 19df622..a49f290 100644 --- a/public/theme/admin/css/style.css +++ b/public/theme/admin/css/style.css @@ -1 +1 @@ -:focus{outline:0}*{box-sizing:border-box}body,html{width:100vw;height:100vh;overflow:hidden;padding:0;margin:0;background:#1f2857;background:linear-gradient(144deg,#1f2954 25%,#000 50%,#5e002c 80%);background-attachment:fixed;color:#fff;font-family:sans-serif;font-size:16px}.hide{display:none!important}.btn{border:none;background:#3949ab radial-gradient(circle at 0 0,#3949ab 0,rgba(0,0,0,.2) 100%) no-repeat;color:#fff;padding:5px 15px;margin:10px 0;cursor:pointer;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-radius:4px;box-shadow:0 2px 5px 0 rgba(0,0,0,.26);overflow:hidden;display:flex;justify-content:center;align-items:center;transition:.5s}.btn--outline{background:0 0;border:1px solid #3949ab}.btn:focus{box-shadow:0 3px 8px 1px rgba(0,0,0,.4)}.btn--accent{background:#ff0089 radial-gradient(circle at 0 0,#ff0089 0,rgba(0,0,0,.2) 100%) no-repeat}.btn--warn{background:#f87229 radial-gradient(circle at 0 0,#f87229 0,rgba(0,0,0,.2) 100%) no-repeat}.btn-fab{border-radius:2rem;width:2em;height:2em;padding:5px}.btn-ripple{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;background:0 0}.btn-ripple__effect{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);opacity:1;width:200%;height:0;padding-bottom:200%;border-radius:50%;background:rgba(190,190,190,.3);-webkit-animation:a-ripple .4s ease-in;animation:a-ripple .4s ease-in}.btn-ripple__effect.to-remove{-webkit-animation:remove-ripple .2s linear;animation:remove-ripple .2s linear}.btn--outline .btn-ripple__effect{background:rgba(57,73,171,.5);z-index:-1}.btn__content{z-index:1;font-weight:400;pointer-events:none}@-webkit-keyframes remove-ripple{from{opacity:1}to{opacity:0}}@keyframes remove-ripple{from{opacity:1}to{opacity:0}}@-webkit-keyframes a-ripple{0%{opacity:0;padding-bottom:0;width:0}25%{opacity:1}100%{width:200%;padding-bottom:200%}}@keyframes a-ripple{0%{opacity:0;padding-bottom:0;width:0}25%{opacity:1}100%{width:200%;padding-bottom:200%}}.input-group input{background-color:rgba(0,0,0,.4);border:none;border-bottom:2px solid #3949ab;color:#fff;padding:6px}.input-group input:focus,.input-group.focus input{border-color:#ff0089}.input-group.valid input{border-color:#39ab48}.input-group.invalid input{border-color:#cf1b1b}.input-group{display:flex;flex-direction:column;margin-bottom:3px;position:relative;padding-top:.7rem}.input-group.no-space{padding-top:.1rem}.input-group label{font-size:.7rem;position:absolute;top:.7rem;left:6px;height:1rem;vertical-align:middle;transform:translateY(50%);color:#dcdcdc;transition:all .2s ease-out}.input-group input:focus~label,.input-group.focus label{top:0;left:0;transform:translateY(0);font-size:.6rem}.input-group .error{display:none}.input-group.invalid .error{margin-top:2px;display:block;font-size:.7rem;color:#f32f32}.switch{display:flex;flex-direction:row;align-items:center;padding:5px 20px 5px 5px}.switch input{position:absolute;-webkit-appearance:none;-moz-appearance:none;appearance:none;opacity:0}.switch label{display:block;border-radius:10px;width:40px;height:20px;background-color:#e9e9e9;position:relative;cursor:pointer;margin-right:.5rem}.switch label:after{content:'';background-color:#c51162;position:absolute;top:2px;left:2px;height:16px;width:16px;border-radius:10px;transition:.5s}.switch input:checked+label:after{transform:translateX(20px);background-color:#007769} \ No newline at end of file +:focus{outline:0}*{box-sizing:border-box}body,html{width:100vw;height:100vh;overflow:hidden;padding:0;margin:0;background:#1f2857;background:linear-gradient(144deg,#1f2954 25%,#000 50%,#5e002c 80%);background-attachment:fixed;color:#fff;font-family:sans-serif;font-size:16px}.hide{display:none!important}.btn{border:none;background:#3949ab radial-gradient(circle at 0 0,#3949ab 0,rgba(0,0,0,.2) 100%) no-repeat;color:#fff;padding:5px 15px;margin:10px 0;cursor:pointer;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-radius:4px;box-shadow:0 2px 5px 0 rgba(0,0,0,.26);overflow:hidden;display:flex;justify-content:center;align-items:center;transition:.5s}.btn--outline{background:0 0;border:1px solid #3949ab}.btn:focus{box-shadow:0 3px 8px 1px rgba(0,0,0,.4)}.btn--valid{background:#39ab48 radial-gradient(circle at 0 0,#39ab48 0,rgba(0,0,0,.2) 100%) no-repeat}.btn--accent{background:#ff0089 radial-gradient(circle at 0 0,#ff0089 0,rgba(0,0,0,.2) 100%) no-repeat}.btn--warn{background:#f87229 radial-gradient(circle at 0 0,#f87229 0,rgba(0,0,0,.2) 100%) no-repeat}.btn-fab{border-radius:2rem;width:2em;height:2em;padding:5px}.btn-ripple{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;background:0 0}.btn-ripple__effect{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);opacity:1;width:200%;height:0;padding-bottom:200%;border-radius:50%;background:rgba(190,190,190,.3);-webkit-animation:a-ripple .4s ease-in;animation:a-ripple .4s ease-in}.btn-ripple__effect.to-remove{-webkit-animation:remove-ripple .2s linear;animation:remove-ripple .2s linear}.btn--outline .btn-ripple__effect{background:rgba(57,73,171,.5);z-index:-1}.btn__content{z-index:1;font-weight:400;pointer-events:none}@-webkit-keyframes remove-ripple{from{opacity:1}to{opacity:0}}@keyframes remove-ripple{from{opacity:1}to{opacity:0}}@-webkit-keyframes a-ripple{0%{opacity:0;padding-bottom:0;width:0}25%{opacity:1}100%{width:200%;padding-bottom:200%}}@keyframes a-ripple{0%{opacity:0;padding-bottom:0;width:0}25%{opacity:1}100%{width:200%;padding-bottom:200%}}.input-group input{background-color:rgba(0,0,0,.4);border:none;border-bottom:2px solid #3949ab;color:#fff;padding:6px}.input-group input:focus,.input-group.focus input{border-color:#ff0089}.input-group.valid input{border-color:#39ab48}.input-group.invalid input{border-color:#cf1b1b}.input-group{display:flex;flex-direction:column;margin-bottom:3px;position:relative;padding-top:.7rem}.input-group.no-space{padding-top:.1rem}.input-group label{font-size:.7rem;position:absolute;top:.7rem;left:6px;height:1rem;vertical-align:middle;transform:translateY(50%);color:#dcdcdc;transition:all .2s ease-out}.input-group input:focus~label,.input-group.focus label{top:0;left:0;transform:translateY(0);font-size:.6rem}.input-group .error{display:none}.input-group.invalid .error{margin-top:2px;display:block;font-size:.7rem;color:#f32f32}.switch{display:flex;flex-direction:row;align-items:center;padding:5px 20px 5px 0}.switch input{position:absolute;-webkit-appearance:none;-moz-appearance:none;appearance:none;opacity:0}.switch label{display:block;border-radius:10px;width:40px;height:20px;background-color:#e9e9e9;position:relative;cursor:pointer;margin-right:.5rem}.switch label:after{content:'';background-color:#c51162;position:absolute;top:2px;left:2px;height:16px;width:16px;border-radius:10px;transition:.5s}.switch input:checked+label:after{transform:translateX(20px);background-color:#007769} \ No newline at end of file diff --git a/public/theme/admin/images/icon/ic_arrow_back_24px.svg b/public/theme/admin/images/icon/ic_arrow_back_24px.svg new file mode 100644 index 0000000..d153fea --- /dev/null +++ b/public/theme/admin/images/icon/ic_arrow_back_24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/theme/admin/images/icon/ic_delete_24px.svg b/public/theme/admin/images/icon/ic_delete_24px.svg new file mode 100644 index 0000000..e8dde6e --- /dev/null +++ b/public/theme/admin/images/icon/ic_delete_24px.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/theme/admin/js/scripts.js b/public/theme/admin/js/scripts.js index 6aa374b..fa36f40 100644 --- a/public/theme/admin/js/scripts.js +++ b/public/theme/admin/js/scripts.js @@ -196,6 +196,193 @@ class VRipple { } } const rippler = new VRipple(); + + + +(function () { + window._openVSelect = null; + + requestAnimationFrame(e => { + document.body.addEventListener('click', ev => { + if (window._openVSelect && ev.target.closest('v-select') !== window._openVSelect) { + window._openVSelect.toggle(false); + } + }) + }) + + class VSelectElement extends HTMLElement { + constructor() { + super(); + let self = this; + self._in = this.attachInternals(); + self._in.role = 'select'; + self.setAttribute('tabindex', 0); + self.update(); + } + + static get formAssociated() { + return true; + } + + static get observedAttributes() { + return ['required', 'validity']; + } + + get required() { + return this.hasAttribute('required'); + } + + set required(flag) { + this.toggleAttribute('required', Boolean(flag)); + } + + get name() { + return this.getAttribute('name'); + } + + set name(val) { + this.toggleAttribute('name', val); + } + + get form() { + return this._in.form; + } + + get options() { + return $$('v-options v-option', this); + } + + get selected() { + return $$('v-options v-option[selected]', this); + } + + update() { + let selected = [], + lbl = $('v-label', this), + fd = new FormData(); + this.selected.forEach(e => { + selected.push(e.innerText); + fd.append(this.name, e.value); + }) + lbl.attributeChangedCallback('value', '', selected.join(", ")); + if (this.required && selected.length === 0) { + this._in.setValidity({customError: true}, "Option is needed"); + } else { + this._in.setValidity({}); + } + this._in.setFormValue(fd); + } + + checkValidity() { + return this._in.checkValidity(); + } + + reportValidity() { + return this._in.reportValidity(); + } + + toggle(open) { + if (window._openVSelect && open) { + window._openVSelect.toggleSelect(false); + } + const options = $('v-options', this); + if (!open || this.isOpen) { + options.style.maxHeight = '0'; + window._openVSelect = false; + this.isOpen = false; + this.update(); + } else { + options.focus(); + let height = 0, + children = options.children; + for (let i = 0; i < children.length; i++) { + height += children[i].offsetHeight; + } + options.style.maxHeight = height + 'px'; + window._openVSelect = this; + this.isOpen = true; + } + } + } + + class VSelectOptionElement extends HTMLElement { + constructor() { + super(); + this._in = this.attachInternals(); + this._in.role = 'option'; + this.addEventListener('click', e => { + let parent = this.parentNode.parentNode, + select = !this.selected; + if (!parent.hasAttribute('multiple')) { + parent.toggle(false); + for (let item of parent.selected) { + if (item !== this) { + item.removeAttribute('selected'); + } + } + } + if (!this.disabled) { + this.attributeChangedCallback('selected', false, select, true); + this.parentNode.parentNode.update(); + } + }); + } + + static get observedAttributes() { + return ['selected', 'disabled', 'value']; + } + + attributeChangedCallback(name, oldValue, newValue, force) { + if (name === 'selected' && this.hasAttribute('disabled')) { + this.removeAttribute(name); + return; + } + if (name === 'disabled' && newValue === true && this.hasAttribute('selected')) { + this.attributeChangedCallback('selected', false, false); + } + + if (force) { + if (newValue) { + this.setAttribute(name, newValue); + } else { + this.removeAttribute(name); + } + } + this[name] = newValue; + } + } + + class VLabel extends HTMLElement { + constructor() { + super(); + this.empty = this.getAttribute('empty') || ""; + this.innerHTML = this.getAttribute("value") || this.empty; + this.addEventListener('click', this.openPopUp.bind(this)); + } + + static get observedAttributes() { + return ['empty', 'value']; + } + + openPopUp() { + this.parentNode.toggle(true); + } + + attributeChangedCallback(name, oldValue, newValue) { + if (name === 'value') { + this.innerHTML = newValue || this.empty; + } + this[name] = newValue; + } + } + + customElements.define("v-label", VLabel); + customElements.define("v-option", VSelectOptionElement); + customElements.define("v-select", VSelectElement); +})(); + + + class FormHandler { constructor(selector, parent, cb, err) { this.cb = cb || console.log; @@ -263,4 +450,4 @@ class FormHandler { $('.error-message', el).classList.remove('hide'); }) } -})() \ No newline at end of file +})(); \ No newline at end of file diff --git a/public/theme/admin/js/scripts.min.js b/public/theme/admin/js/scripts.min.js index 47e60ed..327f1fa 100644 --- a/public/theme/admin/js/scripts.min.js +++ b/public/theme/admin/js/scripts.min.js @@ -1 +1 @@ -class VUtils{static makePublic(){VUtils.isUsed||(this.initHandlers(),VUtils.isUsed=!0,console.log("[VUtils] is now available in the Global Space! no VUtils. anymore needed"))}static initHandlers(){window.$=this.$,window.$$=this.$$,window.tryCatch=this.tryCatch,VUtils.nodePrototypes()}static $(e,t){return(t=t||document).querySelector(e)}static $$(e,t){return(t=t||document).querySelectorAll(e)}static tryCatch(e,t,i){e=VUtils.wrap(e,[]),i=i||console.error,t=t||console.log;try{t(...e)}catch(e){i(e)}}static forEach(e,t,i){for(let s=0;s{let n=e.target;if(e.detail instanceof HTMLElement&&(n=e.detail),n instanceof HTMLElement)if(n.matches(t))VUtils.tryCatch([e,n],i,s);else{const o=n.find(t);o&&VUtils.tryCatch([e,o],i,s)}})},Node.prototype.addMultiListener=function(e,t,i={}){let s=e.split(" ");for(let e of s)this.addEventListener(e,t,i)}}}VUtils.makePublic();class VRipple{constructor(e={}){if(!VUtils.isUsed)throw"VRipply is only with Public VUtils usable!";let t=this;if(t.options=JSON.parse('{"classes":["btn-ripple__effect"],"target":"body","selector":".btn-ripple"}'),VUtils.mergeOptions(t.options,e),t.options.selector.indexOf("#")>-1)throw"ID's are not allowed as selector!";this.instanceCheck(),this.ripples=[],requestAnimationFrame(this.initHandler.bind(this))}instanceCheck(){let e=this.options;const t=[e.target,e.selector,e.classes.join(".")].join(" ");VRipple.instances=VRipple.instances||{},VRipple.instances[t]=this}initHandler(){let e=this,t=e.options.selector;$(e.options.target).addDelegatedEventListener("mousedown touchstart",t,(t,i)=>{let s=t.touches?t.touches[0]:t,n=i.parentNode,o=i.createNew("span",e.options),l=n.getBoundingClientRect(),r=s.clientX-l.left,a=s.clientY-l.top;o.style.top=a+"px",o.style.left=r+"px",o._mouseDown=!0,o._animationEnded=!1,e.ripples.push(o)}),document.body.addDelegatedEventListener("animationend","."+VUtils.get(e.options.classes,""),e.rippleEnd.bind(e)),document.body._vRippleInit||(document.body.addMultiListener("mouseup touchend mouseleave rippleClose",t=>{let i=Object.keys(VRipple.instances);for(let s of i)for(let i of VRipple.instances[s].ripples)e.rippleEnd.bind(VRipple.instances[s])(t,i)}),document.body._vRippleInit=!0)}rippleEnd(e,t){t.parentNode&&("animationend"===e.type?t._animationEnded=!0:t._mouseDown=!1,!t._mouseDown&&t._animationEnded&&(t.classList.contains("to-remove")?(t.parentNode.removeChild(t),this.ripples.splice(this.ripples.indexOf(t),1)):t.classList.add("to-remove")))}}const rippler=new VRipple;class FormHandler{constructor(e,t,i,s){this.cb=i||console.log,this.err=s||console.err,$(t).addDelegatedEventListener("submit",e,this.handleEvent.bind(this))}handleEvent(e,t){if(e.preventDefault(),t.checkValidity()){if(""===(t.action??""))return void console.error("No URL Found on Form",t);fetch(t.action,{method:t.method.toUpperCase(),credentials:"same-origin",body:new FormData(t),redirect:"manual"}).then(e=>{if(!e.ok)throw new Error("Network response errored");return e.json()}).then(e=>this.cb(e,t)).catch(e=>this.err(e,t))}else VUtils.forEach($$("input",t),e=>{if(!e.checkValidity()){let t=e.parentNode;t.classList.remove("valid"),t.classList.add("invalid")}})}}$("body").addDelegatedEventListener("change input","input",(e,t)=>{let i=$(".error-message",t.find("form"));i&&i.classList.add("hide");let s=t.parentNode;""===t.value?s.classList.remove("focus"):s.classList.add("focus"),t.checkValidity()?(s.classList.add("valid"),s.classList.remove("invalid")):(s.classList.remove("valid"),s.classList.add("invalid"))}),$("#login")&&new FormHandler("form#login","body",()=>{location.reload()},(e,t)=>{$(".error-message",t).classList.remove("hide")}); \ No newline at end of file +class VUtils{static makePublic(){VUtils.isUsed||(this.initHandlers(),VUtils.isUsed=!0,console.log("[VUtils] is now available in the Global Space! no VUtils. anymore needed"))}static initHandlers(){window.$=this.$,window.$$=this.$$,window.tryCatch=this.tryCatch,VUtils.nodePrototypes()}static $(e,t){return(t=t||document).querySelector(e)}static $$(e,t){return(t=t||document).querySelectorAll(e)}static tryCatch(e,t,i){e=VUtils.wrap(e,[]),i=i||console.error,t=t||console.log;try{t(...e)}catch(e){i(e)}}static forEach(e,t,i){for(let s=0;s{let n=e.target;if(e.detail instanceof HTMLElement&&(n=e.detail),n instanceof HTMLElement)if(n.matches(t))VUtils.tryCatch([e,n],i,s);else{const o=n.find(t);o&&VUtils.tryCatch([e,o],i,s)}})},Node.prototype.addMultiListener=function(e,t,i={}){let s=e.split(" ");for(let e of s)this.addEventListener(e,t,i)}}}VUtils.makePublic();class VRipple{constructor(e={}){if(!VUtils.isUsed)throw"VRipply is only with Public VUtils usable!";let t=this;if(t.options=JSON.parse('{"classes":["btn-ripple__effect"],"target":"body","selector":".btn-ripple"}'),VUtils.mergeOptions(t.options,e),t.options.selector.indexOf("#")>-1)throw"ID's are not allowed as selector!";this.instanceCheck(),this.ripples=[],requestAnimationFrame(this.initHandler.bind(this))}instanceCheck(){let e=this.options;const t=[e.target,e.selector,e.classes.join(".")].join(" ");VRipple.instances=VRipple.instances||{},VRipple.instances[t]=this}initHandler(){let e=this,t=e.options.selector;$(e.options.target).addDelegatedEventListener("mousedown touchstart",t,(t,i)=>{let s=t.touches?t.touches[0]:t,n=i.parentNode,o=i.createNew("span",e.options),r=n.getBoundingClientRect(),l=s.clientX-r.left,a=s.clientY-r.top;o.style.top=a+"px",o.style.left=l+"px",o._mouseDown=!0,o._animationEnded=!1,e.ripples.push(o)}),document.body.addDelegatedEventListener("animationend","."+VUtils.get(e.options.classes,""),e.rippleEnd.bind(e)),document.body._vRippleInit||(document.body.addMultiListener("mouseup touchend mouseleave rippleClose",t=>{let i=Object.keys(VRipple.instances);for(let s of i)for(let i of VRipple.instances[s].ripples)e.rippleEnd.bind(VRipple.instances[s])(t,i)}),document.body._vRippleInit=!0)}rippleEnd(e,t){t.parentNode&&("animationend"===e.type?t._animationEnded=!0:t._mouseDown=!1,!t._mouseDown&&t._animationEnded&&(t.classList.contains("to-remove")?(t.parentNode.removeChild(t),this.ripples.splice(this.ripples.indexOf(t),1)):t.classList.add("to-remove")))}}const rippler=new VRipple;!function(){window._openVSelect=null,requestAnimationFrame(e=>{document.body.addEventListener("click",e=>{window._openVSelect&&e.target.closest("v-select")!==window._openVSelect&&window._openVSelect.toggle(!1)})});class e extends HTMLElement{constructor(){super();let e=this;e._in=this.attachInternals(),e._in.role="select",e.setAttribute("tabindex",0),e.update()}static get formAssociated(){return!0}static get observedAttributes(){return["required","validity"]}get required(){return this.hasAttribute("required")}set required(e){this.toggleAttribute("required",Boolean(e))}get name(){return this.getAttribute("name")}set name(e){this.toggleAttribute("name",e)}get form(){return this._in.form}get options(){return $$("v-options v-option",this)}get selected(){return $$("v-options v-option[selected]",this)}update(){let e=[],t=$("v-label",this),i=new FormData;this.selected.forEach(t=>{e.push(t.innerText),i.append(this.name,t.value)}),t.attributeChangedCallback("value","",e.join(", ")),this.required&&0===e.length?this._in.setValidity({customError:!0},"Option is needed"):this._in.setValidity({}),this._in.setFormValue(i)}checkValidity(){return this._in.checkValidity()}reportValidity(){return this._in.reportValidity()}toggle(e){window._openVSelect&&e&&window._openVSelect.toggleSelect(!1);const t=$("v-options",this);if(!e||this.isOpen)t.style.maxHeight="0",window._openVSelect=!1,this.isOpen=!1,this.update();else{t.focus();let e=0,i=t.children;for(let t=0;t{let t=this.parentNode.parentNode,i=!this.selected;if(!t.hasAttribute("multiple")){t.toggle(!1);for(let e of t.selected)e!==this&&e.removeAttribute("selected")}this.disabled||(this.attributeChangedCallback("selected",!1,i,!0),this.parentNode.parentNode.update())})}static get observedAttributes(){return["selected","disabled","value"]}attributeChangedCallback(e,t,i,s){"selected"===e&&this.hasAttribute("disabled")?this.removeAttribute(e):("disabled"===e&&!0===i&&this.hasAttribute("selected")&&this.attributeChangedCallback("selected",!1,!1),s&&(i?this.setAttribute(e,i):this.removeAttribute(e)),this[e]=i)}}class i extends HTMLElement{constructor(){super(),this.empty=this.getAttribute("empty")||"",this.innerHTML=this.getAttribute("value")||this.empty,this.addEventListener("click",this.openPopUp.bind(this))}static get observedAttributes(){return["empty","value"]}openPopUp(){this.parentNode.toggle(!0)}attributeChangedCallback(e,t,i){"value"===e&&(this.innerHTML=i||this.empty),this[e]=i}}customElements.define("v-label",i),customElements.define("v-option",t),customElements.define("v-select",e)}();class FormHandler{constructor(e,t,i,s){this.cb=i||console.log,this.err=s||console.err,$(t).addDelegatedEventListener("submit",e,this.handleEvent.bind(this))}handleEvent(e,t){if(e.preventDefault(),t.checkValidity()){if(""===(t.action??""))return void console.error("No URL Found on Form",t);fetch(t.action,{method:t.method.toUpperCase(),credentials:"same-origin",body:new FormData(t),redirect:"manual"}).then(e=>{if(!e.ok)throw new Error("Network response errored");return e.json()}).then(e=>this.cb(e,t)).catch(e=>this.err(e,t))}else VUtils.forEach($$("input",t),e=>{if(!e.checkValidity()){let t=e.parentNode;t.classList.remove("valid"),t.classList.add("invalid")}})}}$("body").addDelegatedEventListener("change input","input",(e,t)=>{let i=$(".error-message",t.find("form"));i&&i.classList.add("hide");let s=t.parentNode;""===t.value?s.classList.remove("focus"):s.classList.add("focus"),t.checkValidity()?(s.classList.add("valid"),s.classList.remove("invalid")):(s.classList.remove("valid"),s.classList.add("invalid"))}),$("#login")&&new FormHandler("form#login","body",()=>{location.reload()},(e,t)=>{$(".error-message",t).classList.remove("hide")}); \ No newline at end of file diff --git a/tpl/admin/admin-panel.php b/tpl/admin/admin-panel.php index e129e08..f09a386 100644 --- a/tpl/admin/admin-panel.php +++ b/tpl/admin/admin-panel.php @@ -1,144 +1,495 @@
-

Roles

-
-

Overview

-
Admin (secured) -
-
-
Moderator -
-
-
Predator -
-
-

Add new Role

-
-
- - - New Role Name is required + + +

Roles

+
+ +
+

Overview

+
+
+
Admin (secured)
+
+
+
+
Moderator
+
+
+
+
Predator
+
-
-
-
-
-
-

Role: Admin

-
- - - If enabled role is active. -
-
-

Change Name

-
- - - Role Name is required +
+

Add new Role

+
+ + + New Role Name is required +
+
-
-
-

View Permissions

-
+ + + Dies ist der Footer. + + + + + + +

Role: Admin

+
+ +
+
+
+
+ +
+

Role Status

+
+ + + If enabled role is active. +
+
+
+

Role Name

+
+ + + New Role Name is required +
+
+
+ +
+

Module

+
Meta-Data
+
Pages
+
Roles
+
SEO-URL
+
Users
+
VENOM-Status
+
+
+

Edit

+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+

View

- Meta-Data +
- Pages +
- Roles +
- SEO-URL +
- Users +
- VENOM-Status +
-
-
-

View Permissions

-
-
- - - Meta-Data -
+ + +
+ + + +
+
+ + Dies ist der Footer. + + -
- - - Pages -
-
- - - Roles + + +

Users

+
+ +
+

All Users

+
+
+
ALLE Alphabetisch ordnen!
- -
- - - SEO-URL +
+
+
derflieger (Ina Ruh)
- -
- - - Users +
+
+
engineertrooper (Dominic Seela)
- -
- - - VENOM-Status +
+
+
versustunez (Maurice Grönewald)
+
+
+
+
vollglaswasser (Marie Joseph)
-
+
+

Add new User

+
+
+ + + New User Name is required +
+
+ +
+ + + Dies ist der Footer. + + - -
+ + + +

User: engineertrooper

+
+ +
+
+
+
+ +
+
Username:
+
+ + + User Name is required +
+
Author Name:
+
+ + + Author Name is required +
+
+
+
E-Mail:
+
+ + + E-Mail Address is required +
+
+
+
New Password:
+
+ + + New Password is required +
+
New Password repeat:
+
+ + + New Password Repeat is required +
+
+
+ +
+ + + +
+
+ + Dies ist der Footer. + +
+ + + + +

Pages

+
+ +

All Pages

+
+ +
Name
+
Edit, View, Delete
+
ID
+
Status
+
+ +
Sonnenuntergang am Meer
+
+
+
+
+
+
+
+
+
+
+
+
+ 4 +
+
+ + + + Visible + Privat + + +
+
+ +
Fernsehen zu Zweit mit Nebenwirkungen
+
+
+
+
+
+
+
+
+
+
+
+
+ 7 +
+
+ + + + Visible + Privat + + +
+
+ +
Spiele 1 und 2 und 3
+
+
+
+
+
+
+
+
+
+
+
+
+ 14 +
+
+ + + + Visible + Privat + + +
+
+ +
+

Add new Page

+
+ + + New Page Name is required +
+ +
+
+ + Dies ist der Footer. + +
+ + + + +

Page: Fernsehen zu Zweit mit Nebenwirkungen

+
+ +
+
+
+
+ +

Seitenname:

+
+ +
+ + + New Page Name is required +
+
+ + hier kommt das Editorfeld hin + + +

Page Information

+
+ +
Author
+
ID
+
SEO-URL
+
Status
+
+ +
+ + + + engineertrooper (Dominic Seela) + versustunez (Maurice Grönewald) + + +
+
+ 7 +
+
+ https://beispiel.seo-url.de/blabla/23455234 +
+
+ + + + Visible + Privat + + +
+
+ +
+ + + +
+
+ + Dies ist der Footer + +
-
+ \ No newline at end of file